1
0
mirror of https://github.com/stedolan/jq.git synced 2024-05-11 05:55:39 +00:00

Implemented contains operator

This commit is contained in:
Stephen Roantree
2012-10-24 11:42:25 -07:00
parent 033d9b2fd5
commit 5e25c2a259
12 changed files with 2965 additions and 2557 deletions

View File

@@ -161,6 +161,21 @@ static void f_greatereq(jv input[], jv output[]) {
order_cmp(input, output, CMP_OP_GREATEREQ); order_cmp(input, output, CMP_OP_GREATEREQ);
} }
static void f_contains(jv input[], jv output[]) {
jv_free(input[0]);
jv a = input[2];
jv b = input[1];
jv_kind akind = jv_get_kind(a);
if (akind == jv_get_kind(b)) {
output[0] = jv_bool(jv_contains(a, b));
} else {
output[0] = jv_invalid_with_msg(jv_string_fmt("Can only check containment of values of the same type."));
jv_free(a);
jv_free(b);
}
}
static void f_tonumber(jv input[], jv output[]) { static void f_tonumber(jv input[], jv output[]) {
if (jv_get_kind(input[0]) == JV_KIND_NUMBER) { if (jv_get_kind(input[0]) == JV_KIND_NUMBER) {
output[0] = input[0]; output[0] = input[0];
@@ -294,6 +309,7 @@ static struct cfunction function_list[] = {
{f_greater, "_greater", CALL_BUILTIN_3_1}, {f_greater, "_greater", CALL_BUILTIN_3_1},
{f_lesseq, "_lesseq", CALL_BUILTIN_3_1}, {f_lesseq, "_lesseq", CALL_BUILTIN_3_1},
{f_greatereq, "_greatereq", CALL_BUILTIN_3_1}, {f_greatereq, "_greatereq", CALL_BUILTIN_3_1},
{f_contains, "_contains", CALL_BUILTIN_3_1},
{f_length, "length", CALL_BUILTIN_1_1}, {f_length, "length", CALL_BUILTIN_1_1},
{f_type, "type", CALL_BUILTIN_1_1}, {f_type, "type", CALL_BUILTIN_1_1},
{f_add, "add", CALL_BUILTIN_1_1}, {f_add, "add", CALL_BUILTIN_1_1},

View File

@@ -522,7 +522,33 @@ sections:
- program: '.[] == 1' - program: '.[] == 1'
input: '[1, 1.0, "1", "banana"]' input: '[1, 1.0, "1", "banana"]'
output: ['[true, true, false, false]'] output: ['[true, true, false, false]']
- title: `contains`
body: |
The expression 'a contains b' will produce true if b is completely
contained within a. A string B is contained in a string A if B is a
substring of A. An array B is contained in an array A is all elements
in B are contained in any element in A. An object B is contained in
object A if all of the values in B are contained in the value in A with
the same key. All other types are assumed to be contained in each other
if they are equal.
examples:
- program: '. == contains "bar"'
input: '"foobar"'
output: ['true']
- program: '. contains ["baz", "bar"]'
input: '["foobar", "foobaz", "blarp"]'
output: ['true']
- program: '. contains ["bazzzzz", "bar"]'
input: '["foobar", "foobaz", "blarp"]'
output: ['false']
- program: '. contains {foo: 12, bar: [{barp: 12}]}'
input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
output: ['true']
- program: '. contains {foo: 12, bar: [{barp: 15}]}'
input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
output: ['false']
- title: if-then-else - title: if-then-else
body: | body: |

60
jv.c
View File

@@ -250,6 +250,27 @@ static int jvp_array_equal(jv_complex* a, jv_complex* b) {
return 1; return 1;
} }
static int jvp_array_contains(jv_complex* a, jv_complex* b) {
int r = 1;
for (int bi = 0; bi < jvp_array_length(b); bi++) {
int ri = 0;
jv* bval = jvp_array_read(b, bi);
for (int ai = 0; ai < jvp_array_length(a); ai++) {
jv aval = jv_copy(*jvp_array_read(a, ai));
jv bval_copy = jv_copy(*bval);
if (jv_contains(aval, bval_copy)) {
ri = 1;
break;
}
}
if (!ri) {
r = 0;
break;
}
}
return r;
}
static jv_complex jvp_array_slice(jv_complex* a, int start, int end) { static jv_complex jvp_array_slice(jv_complex* a, int start, int end) {
// FIXME: maybe slice should reallocate if the slice is small enough // FIXME: maybe slice should reallocate if the slice is small enough
assert(start <= end); assert(start <= end);
@@ -863,6 +884,27 @@ jv jv_object_merge(jv a, jv b) {
return a; return a;
} }
int jv_object_contains(jv a, jv b) {
assert(jv_get_kind(a) == JV_KIND_OBJECT);
assert(jv_get_kind(b) == JV_KIND_OBJECT);
int r = 1;
for (int i=0; i<jvp_object_size(&b.val.complex); i++) {
struct object_slot* slotb = jvp_object_get_slot(&b.val.complex, i);
if (!slotb->string) continue;
jv* slota = jvp_object_read(&a.val.complex, slotb->string);
if (!(slota && jv_get_kind(slotb->value) == jv_get_kind(*slota)
&& jv_contains(jv_copy(*slota), jv_copy(slotb->value)))) {
r = 0;
break;
}
}
jv_free(a);
jv_free(b);
return r;
}
/* /*
* Object iteration (internal helpers) * Object iteration (internal helpers)
*/ */
@@ -977,3 +1019,21 @@ int jv_equal(jv a, jv b) {
jv_free(b); jv_free(b);
return r; return r;
} }
int jv_contains(jv a, jv b) {
int r = 1;
if (jv_get_kind(a) != jv_get_kind(b)) {
r = 0;
} else if (jv_get_kind(a) == JV_KIND_OBJECT) {
r = jv_object_contains(jv_copy(a), jv_copy(b));
} else if (jv_get_kind(a) == JV_KIND_ARRAY) {
r = jvp_array_contains(&a.val.complex, &b.val.complex);
} else if (jv_get_kind(a) == JV_KIND_STRING) {
r = strstr(jv_string_value(a), jv_string_value(b)) != 0;
} else {
r = jv_equal(jv_copy(a), jv_copy(b));
}
jv_free(a);
jv_free(b);
return r;
}

1
jv.h
View File

@@ -48,6 +48,7 @@ jv jv_copy(jv);
void jv_free(jv); void jv_free(jv);
int jv_equal(jv, jv); int jv_equal(jv, jv);
int jv_contains(jv, jv);
jv jv_invalid(); jv jv_invalid();
jv jv_invalid_with_msg(jv); jv jv_invalid_with_msg(jv);

View File

@@ -9,7 +9,7 @@
#define FLEX_SCANNER #define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 37 #define YY_FLEX_SUBMINOR_VERSION 35
#if YY_FLEX_SUBMINOR_VERSION > 0 #if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA #define FLEX_BETA
#endif #endif
@@ -159,7 +159,15 @@ typedef void* yyscan_t;
/* Size of default input buffer. */ /* Size of default input buffer. */
#ifndef YY_BUF_SIZE #ifndef YY_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k.
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
* Ditto for the __ia64__ case accordingly.
*/
#define YY_BUF_SIZE 32768
#else
#define YY_BUF_SIZE 16384 #define YY_BUF_SIZE 16384
#endif /* __ia64__ */
#endif #endif
/* The state buf must be large enough to hold one state per character in the main buffer. /* The state buf must be large enough to hold one state per character in the main buffer.
@@ -171,11 +179,6 @@ typedef void* yyscan_t;
typedef struct yy_buffer_state *YY_BUFFER_STATE; typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif #endif
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2 #define EOB_ACT_LAST_MATCH 2
@@ -198,6 +201,11 @@ typedef size_t yy_size_t;
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE #ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state struct yy_buffer_state
@@ -215,7 +223,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB /* Number of characters read into yy_ch_buf, not including EOB
* characters. * characters.
*/ */
yy_size_t yy_n_chars; int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it, /* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to * and can realloc() it to grow it, and should free() it to
@@ -294,7 +302,7 @@ static void jq_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner
YY_BUFFER_STATE jq_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE jq_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
YY_BUFFER_STATE jq_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); YY_BUFFER_STATE jq_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
void *jq_yyalloc (yy_size_t ,yyscan_t yyscanner ); void *jq_yyalloc (yy_size_t ,yyscan_t yyscanner );
void *jq_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); void *jq_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
@@ -326,7 +334,7 @@ void jq_yyfree (void * ,yyscan_t yyscanner );
/* Begin user sect3 */ /* Begin user sect3 */
#define jq_yywrap(yyscanner) 1 #define jq_yywrap(n) 1
#define YY_SKIP_YYWRAP #define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR; typedef unsigned char YY_CHAR;
@@ -350,8 +358,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*yy_cp = '\0'; \ *yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp; yyg->yy_c_buf_p = yy_cp;
#define YY_NUM_RULES 35 #define YY_NUM_RULES 36
#define YY_END_OF_BUFFER 36 #define YY_END_OF_BUFFER 37
/* This struct is not used in this scanner, /* This struct is not used in this scanner,
but its presence is necessary. */ but its presence is necessary. */
struct yy_trans_info struct yy_trans_info
@@ -359,17 +367,19 @@ struct yy_trans_info
flex_int32_t yy_verify; flex_int32_t yy_verify;
flex_int32_t yy_nxt; flex_int32_t yy_nxt;
}; };
static yyconst flex_int16_t yy_accept[88] = static yyconst flex_int16_t yy_accept[96] =
{ 0, { 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 36, 34, 33, 33, 34, 26, 1, 22, 0, 0, 37, 35, 34, 34, 35, 27, 1, 23,
23, 24, 22, 22, 22, 22, 22, 25, 22, 22, 24, 25, 23, 23, 23, 23, 23, 26, 23, 23,
22, 32, 32, 32, 32, 32, 32, 32, 22, 30, 23, 33, 33, 33, 33, 33, 33, 33, 33, 23,
30, 28, 31, 33, 2, 1, 17, 15, 25, 16, 31, 31, 29, 32, 34, 2, 1, 17, 15, 26,
0, 13, 18, 20, 3, 21, 32, 32, 4, 32, 16, 0, 13, 18, 20, 3, 21, 33, 33, 4,
32, 32, 6, 11, 32, 14, 30, 29, 27, 29, 33, 33, 33, 33, 6, 11, 33, 14, 31, 30,
0, 25, 19, 10, 5, 32, 32, 12, 32, 0, 28, 30, 0, 26, 19, 10, 33, 5, 33, 33,
29, 9, 8, 7, 29, 29, 0 12, 33, 0, 30, 33, 9, 8, 7, 30, 33,
30, 33, 33, 22, 0
} ; } ;
static yyconst flex_int32_t yy_ec[256] = static yyconst flex_int32_t yy_ec[256] =
@@ -383,11 +393,11 @@ static yyconst flex_int32_t yy_ec[256] =
21, 22, 1, 1, 23, 23, 23, 23, 24, 23, 21, 22, 1, 1, 23, 23, 23, 23, 24, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
25, 26, 27, 1, 28, 1, 29, 23, 23, 30, 25, 26, 27, 1, 28, 1, 29, 23, 30, 31,
31, 32, 23, 33, 34, 23, 23, 35, 23, 36, 32, 33, 23, 34, 35, 23, 23, 36, 23, 37,
37, 23, 23, 38, 39, 40, 41, 23, 23, 23, 38, 23, 23, 39, 40, 41, 42, 23, 23, 23,
23, 23, 42, 43, 44, 1, 1, 1, 1, 1, 23, 23, 43, 44, 45, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -404,91 +414,97 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1 1, 1, 1, 1, 1
} ; } ;
static yyconst flex_int32_t yy_meta[45] = static yyconst flex_int32_t yy_meta[46] =
{ 0, { 0,
1, 1, 2, 2, 1, 3, 1, 1, 1, 1, 1, 1, 2, 2, 1, 3, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1,
1, 1, 4, 4, 1, 5, 1, 6, 4, 4, 1, 1, 4, 4, 1, 5, 1, 6, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 1, 1, 1 4, 4, 1, 1, 1
} ; } ;
static yyconst flex_int16_t yy_base[97] = static yyconst flex_int16_t yy_base[105] =
{ 0, { 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42, 43, 144, 145, 48, 50, 122, 145, 0, 145, 43, 44, 152, 153, 49, 51, 130, 153, 0, 153,
145, 145, 121, 120, 39, 40, 42, 50, 119, 118, 153, 153, 129, 128, 40, 41, 43, 51, 127, 126,
117, 0, 23, 91, 37, 88, 78, 77, 80, 0, 125, 0, 23, 107, 112, 35, 110, 88, 91, 100,
0, 145, 38, 73, 145, 0, 145, 145, 63, 145, 0, 0, 153, 39, 74, 153, 0, 153, 153, 63,
71, 79, 145, 145, 145, 145, 0, 69, 0, 66, 153, 72, 94, 153, 153, 153, 153, 0, 75, 0,
27, 67, 0, 0, 65, 145, 0, 69, 145, 67, 68, 71, 27, 72, 0, 0, 70, 153, 0, 75,
75, 74, 145, 0, 0, 58, 58, 0, 50, 61, 153, 74, 82, 81, 153, 0, 56, 0, 63, 62,
58, 0, 0, 0, 56, 51, 145, 102, 108, 111, 0, 56, 65, 66, 62, 0, 0, 0, 64, 53,
117, 123, 126, 128, 130, 132 59, 45, 39, 0, 153, 107, 113, 116, 122, 128,
131, 133, 135, 137
} ; } ;
static yyconst flex_int16_t yy_def[97] = static yyconst flex_int16_t yy_def[105] =
{ 0, { 0,
87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 95, 1, 1, 1, 1, 1, 1, 1, 1, 1,
88, 88, 87, 87, 87, 87, 87, 87, 89, 87, 96, 96, 95, 95, 95, 95, 95, 95, 97, 95,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
87, 90, 90, 90, 90, 90, 90, 90, 87, 91, 95, 98, 98, 98, 98, 98, 98, 98, 98, 95,
91, 87, 92, 87, 87, 89, 87, 87, 87, 87, 99, 99, 95, 100, 95, 95, 97, 95, 95, 95,
87, 87, 87, 87, 87, 87, 90, 90, 90, 90, 95, 95, 95, 95, 95, 95, 95, 98, 98, 98,
90, 90, 90, 90, 90, 87, 91, 87, 87, 93, 98, 98, 98, 98, 98, 98, 98, 95, 99, 95,
87, 87, 87, 90, 90, 90, 90, 90, 90, 92, 95, 101, 95, 95, 95, 98, 98, 98, 98, 98,
94, 90, 90, 90, 95, 96, 0, 87, 87, 87, 98, 98, 100, 102, 98, 98, 98, 98, 103, 98,
87, 87, 87, 87, 87, 87 104, 98, 98, 98, 0, 95, 95, 95, 95, 95,
95, 95, 95, 95
} ; } ;
static yyconst flex_int16_t yy_nxt[190] = static yyconst flex_int16_t yy_nxt[199] =
{ 0, { 0,
14, 15, 16, 14, 17, 18, 19, 20, 21, 22, 14, 15, 16, 14, 17, 18, 19, 20, 21, 22,
23, 24, 20, 25, 26, 27, 28, 20, 20, 29, 23, 24, 20, 25, 26, 27, 28, 20, 20, 29,
30, 31, 32, 32, 21, 14, 22, 32, 33, 34, 30, 31, 32, 32, 21, 14, 22, 32, 33, 34,
35, 32, 32, 36, 32, 32, 37, 32, 32, 38, 35, 36, 32, 32, 37, 32, 32, 38, 32, 32,
32, 21, 39, 22, 41, 41, 69, 42, 42, 44, 39, 32, 21, 40, 22, 42, 42, 71, 43, 43,
44, 44, 44, 49, 49, 49, 49, 52, 58, 50, 45, 45, 45, 45, 50, 50, 50, 50, 53, 59,
76, 59, 53, 51, 49, 77, 49, 43, 43, 87, 51, 79, 60, 54, 52, 50, 80, 50, 44, 44,
51, 61, 62, 51, 44, 44, 80, 49, 70, 49, 63, 64, 52, 95, 52, 45, 45, 50, 94, 50,
51, 80, 71, 80, 71, 84, 51, 72, 83, 82, 72, 93, 52, 73, 83, 73, 52, 92, 74, 83,
72, 72, 80, 51, 80, 79, 78, 75, 74, 73, 90, 83, 88, 87, 52, 86, 85, 74, 74, 83,
83, 82, 81, 78, 77, 76, 72, 41, 41, 41,
41, 41, 41, 47, 75, 47, 47, 47, 47, 58,
68, 58, 69, 69, 67, 69, 66, 69, 70, 70,
70, 70, 70, 70, 84, 84, 89, 89, 91, 91,
70, 70, 65, 62, 61, 57, 56, 55, 49, 48,
46, 95, 13, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95
66, 70, 40, 40, 40, 40, 40, 40, 46, 65,
46, 46, 46, 46, 57, 64, 57, 67, 67, 63,
67, 60, 67, 68, 68, 68, 68, 68, 68, 81,
81, 85, 85, 86, 86, 68, 68, 56, 55, 54,
48, 47, 45, 87, 13, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87
} ; } ;
static yyconst flex_int16_t yy_chk[190] = static yyconst flex_int16_t yy_chk[199] =
{ 0, { 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 11, 12, 43, 11, 12, 15, 1, 1, 1, 1, 1, 11, 12, 44, 11, 12,
15, 16, 16, 25, 26, 25, 26, 27, 33, 25, 15, 15, 16, 16, 25, 26, 25, 26, 27, 33,
61, 33, 27, 26, 28, 61, 28, 11, 12, 80, 25, 63, 33, 27, 26, 28, 63, 28, 11, 12,
26, 35, 35, 28, 44, 44, 86, 49, 43, 49, 36, 36, 26, 83, 28, 45, 45, 50, 93, 50,
28, 85, 51, 81, 51, 79, 49, 51, 77, 76, 44, 92, 28, 52, 91, 52, 50, 90, 52, 89,
72, 71, 70, 49, 68, 65, 62, 60, 58, 52, 85, 84, 82, 80, 50, 79, 77, 74, 73, 72,
70, 67, 64, 62, 61, 59, 83, 96, 96, 96,
96, 96, 96, 97, 53, 97, 97, 97, 97, 98,
40, 98, 99, 99, 39, 99, 38, 99, 100, 100,
100, 100, 100, 100, 101, 101, 102, 102, 103, 103,
104, 104, 37, 35, 34, 31, 30, 29, 24, 23,
17, 13, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95
39, 80, 88, 88, 88, 88, 88, 88, 89, 38,
89, 89, 89, 89, 90, 37, 90, 91, 91, 36,
91, 34, 91, 92, 92, 92, 92, 92, 92, 93,
93, 94, 94, 95, 95, 96, 96, 31, 30, 29,
24, 23, 17, 13, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87
} ; } ;
/* The intent behind this definition is that it'll catch /* The intent behind this definition is that it'll catch
@@ -522,7 +538,7 @@ struct lexer_param;
static int enter(int opening, int state, yyscan_t yyscanner); static int enter(int opening, int state, yyscan_t yyscanner);
static int try_exit(int closing, int state, yyscan_t yyscanner); static int try_exit(int closing, int state, yyscan_t yyscanner);
#define YY_NO_INPUT 1 #define YY_NO_INPUT 1
#line 526 "lexer.gen.c" #line 542 "lexer.gen.c"
#define INITIAL 0 #define INITIAL 0
#define IN_PAREN 1 #define IN_PAREN 1
@@ -554,8 +570,8 @@ struct yyguts_t
size_t yy_buffer_stack_max; /**< capacity of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char; char yy_hold_char;
yy_size_t yy_n_chars; int yy_n_chars;
yy_size_t yyleng_r; int yyleng_r;
char *yy_c_buf_p; char *yy_c_buf_p;
int yy_init; int yy_init;
int yy_start; int yy_start;
@@ -612,7 +628,7 @@ FILE *jq_yyget_out (yyscan_t yyscanner );
void jq_yyset_out (FILE * out_str ,yyscan_t yyscanner ); void jq_yyset_out (FILE * out_str ,yyscan_t yyscanner );
yy_size_t jq_yyget_leng (yyscan_t yyscanner ); int jq_yyget_leng (yyscan_t yyscanner );
char *jq_yyget_text (yyscan_t yyscanner ); char *jq_yyget_text (yyscan_t yyscanner );
@@ -620,10 +636,6 @@ int jq_yyget_lineno (yyscan_t yyscanner );
void jq_yyset_lineno (int line_number ,yyscan_t yyscanner ); void jq_yyset_lineno (int line_number ,yyscan_t yyscanner );
int jq_yyget_column (yyscan_t yyscanner );
void jq_yyset_column (int column_no ,yyscan_t yyscanner );
YYSTYPE * jq_yyget_lval (yyscan_t yyscanner ); YYSTYPE * jq_yyget_lval (yyscan_t yyscanner );
void jq_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); void jq_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
@@ -670,7 +682,12 @@ static int input (yyscan_t yyscanner );
/* Amount of stuff to slurp up with each read. */ /* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE #ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k */
#define YY_READ_BUF_SIZE 16384
#else
#define YY_READ_BUF_SIZE 8192 #define YY_READ_BUF_SIZE 8192
#endif /* __ia64__ */
#endif #endif
/* Copy whatever the last rule matched to the standard output. */ /* Copy whatever the last rule matched to the standard output. */
@@ -777,7 +794,7 @@ YY_DECL
#line 35 "lexer.l" #line 35 "lexer.l"
#line 781 "lexer.gen.c" #line 798 "lexer.gen.c"
yylval = yylval_param; yylval = yylval_param;
@@ -834,13 +851,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 88 ) if ( yy_current_state >= 96 )
yy_c = yy_meta[(unsigned int) yy_c]; yy_c = yy_meta[(unsigned int) yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp; ++yy_cp;
} }
while ( yy_base[yy_current_state] != 145 ); while ( yy_base[yy_current_state] != 153 );
yy_find_action: yy_find_action:
yy_act = yy_accept[yy_current_state]; yy_act = yy_accept[yy_current_state];
@@ -972,57 +989,62 @@ YY_RULE_SETUP
case 22: case 22:
YY_RULE_SETUP YY_RULE_SETUP
#line 59 "lexer.l" #line 59 "lexer.l"
{ return yytext[0];} { return CONTAINS; }
YY_BREAK YY_BREAK
case 23: case 23:
YY_RULE_SETUP YY_RULE_SETUP
#line 61 "lexer.l" #line 60 "lexer.l"
{ return yytext[0];}
YY_BREAK
case 24:
YY_RULE_SETUP
#line 62 "lexer.l"
{ {
return enter(yytext[0], YY_START, yyscanner); return enter(yytext[0], YY_START, yyscanner);
} }
YY_BREAK YY_BREAK
case 24: case 25:
YY_RULE_SETUP YY_RULE_SETUP
#line 65 "lexer.l" #line 66 "lexer.l"
{ {
return try_exit(yytext[0], YY_START, yyscanner); return try_exit(yytext[0], YY_START, yyscanner);
} }
YY_BREAK YY_BREAK
case 25: case 26:
YY_RULE_SETUP YY_RULE_SETUP
#line 70 "lexer.l" #line 71 "lexer.l"
{ {
yylval->literal = jv_parse_sized(yytext, yyleng); return LITERAL; yylval->literal = jv_parse_sized(yytext, yyleng); return LITERAL;
} }
YY_BREAK YY_BREAK
case 26: case 27:
YY_RULE_SETUP YY_RULE_SETUP
#line 74 "lexer.l" #line 75 "lexer.l"
{ {
yy_push_state(IN_QQSTRING, yyscanner); yy_push_state(IN_QQSTRING, yyscanner);
return QQSTRING_START; return QQSTRING_START;
} }
YY_BREAK YY_BREAK
case 27: case 28:
YY_RULE_SETUP YY_RULE_SETUP
#line 80 "lexer.l" #line 81 "lexer.l"
{ {
return enter(QQSTRING_INTERP_START, YY_START, yyscanner); return enter(QQSTRING_INTERP_START, YY_START, yyscanner);
} }
YY_BREAK YY_BREAK
case 28: case 29:
YY_RULE_SETUP YY_RULE_SETUP
#line 83 "lexer.l" #line 84 "lexer.l"
{ {
yy_pop_state(yyscanner); yy_pop_state(yyscanner);
return QQSTRING_END; return QQSTRING_END;
} }
YY_BREAK YY_BREAK
case 29: case 30:
/* rule 29 can match eol */ /* rule 30 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 87 "lexer.l" #line 88 "lexer.l"
{ {
/* pass escapes to the json parser */ /* pass escapes to the json parser */
jv escapes = jv_string_fmt("\"%.*s\"", yyleng, yytext); jv escapes = jv_string_fmt("\"%.*s\"", yyleng, yytext);
@@ -1031,45 +1053,45 @@ YY_RULE_SETUP
return QQSTRING_TEXT; return QQSTRING_TEXT;
} }
YY_BREAK YY_BREAK
case 30: case 31:
/* rule 30 can match eol */ /* rule 31 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 94 "lexer.l" #line 95 "lexer.l"
{ {
yylval->literal = jv_string_sized(yytext, yyleng); yylval->literal = jv_string_sized(yytext, yyleng);
return QQSTRING_TEXT; return QQSTRING_TEXT;
} }
YY_BREAK YY_BREAK
case 31: case 32:
YY_RULE_SETUP YY_RULE_SETUP
#line 98 "lexer.l" #line 99 "lexer.l"
{ {
return INVALID_CHARACTER; return INVALID_CHARACTER;
} }
YY_BREAK YY_BREAK
case 32: case 33:
YY_RULE_SETUP YY_RULE_SETUP
#line 104 "lexer.l" #line 105 "lexer.l"
{ yylval->literal = jv_string(yytext); return IDENT;} { yylval->literal = jv_string(yytext); return IDENT;}
YY_BREAK YY_BREAK
case 33:
/* rule 33 can match eol */
YY_RULE_SETUP
#line 106 "lexer.l"
{}
YY_BREAK
case 34: case 34:
/* rule 34 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 108 "lexer.l" #line 107 "lexer.l"
{ return INVALID_CHARACTER; } {}
YY_BREAK YY_BREAK
case 35: case 35:
YY_RULE_SETUP YY_RULE_SETUP
#line 110 "lexer.l" #line 109 "lexer.l"
{ return INVALID_CHARACTER; }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 111 "lexer.l"
YY_FATAL_ERROR( "flex scanner jammed" ); YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK YY_BREAK
#line 1073 "lexer.gen.c" #line 1095 "lexer.gen.c"
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(IN_PAREN): case YY_STATE_EOF(IN_PAREN):
case YY_STATE_EOF(IN_BRACKET): case YY_STATE_EOF(IN_BRACKET):
@@ -1261,21 +1283,21 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else else
{ {
yy_size_t num_to_read = int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 ) while ( num_to_read <= 0 )
{ /* Not enough room in the buffer - grow it. */ { /* Not enough room in the buffer - grow it. */
/* just a shorter name for the current buffer */ /* just a shorter name for the current buffer */
YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
int yy_c_buf_p_offset = int yy_c_buf_p_offset =
(int) (yyg->yy_c_buf_p - b->yy_ch_buf); (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
if ( b->yy_is_our_buffer ) if ( b->yy_is_our_buffer )
{ {
yy_size_t new_size = b->yy_buf_size * 2; int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 ) if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8; b->yy_buf_size += b->yy_buf_size / 8;
@@ -1306,7 +1328,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* Read in more data. */ /* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
yyg->yy_n_chars, num_to_read ); yyg->yy_n_chars, (size_t) num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
} }
@@ -1368,7 +1390,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 88 ) if ( yy_current_state >= 96 )
yy_c = yy_meta[(unsigned int) yy_c]; yy_c = yy_meta[(unsigned int) yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1397,13 +1419,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 88 ) if ( yy_current_state >= 96 )
yy_c = yy_meta[(unsigned int) yy_c]; yy_c = yy_meta[(unsigned int) yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 87); yy_is_jam = (yy_current_state == 95);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state; return yy_is_jam ? 0 : yy_current_state;
} }
@@ -1432,7 +1453,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else else
{ /* need more input */ { /* need more input */
yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
++yyg->yy_c_buf_p; ++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) ) switch ( yy_get_next_buffer( yyscanner ) )
@@ -1596,6 +1617,10 @@ static void jq_yy_load_buffer_state (yyscan_t yyscanner)
jq_yyfree((void *) b ,yyscanner ); jq_yyfree((void *) b ,yyscanner );
} }
#ifndef __cplusplus
extern int isatty (int );
#endif /* __cplusplus */
/* Initializes or reinitializes a buffer. /* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer, * This function is sometimes called more than once on the same buffer,
* such as during a jq_yyrestart() or at EOF. * such as during a jq_yyrestart() or at EOF.
@@ -1712,7 +1737,7 @@ void jq_yypop_buffer_state (yyscan_t yyscanner)
*/ */
static void jq_yyensure_buffer_stack (yyscan_t yyscanner) static void jq_yyensure_buffer_stack (yyscan_t yyscanner)
{ {
yy_size_t num_to_alloc; int num_to_alloc;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (!yyg->yy_buffer_stack) { if (!yyg->yy_buffer_stack) {
@@ -1810,7 +1835,7 @@ YY_BUFFER_STATE jq_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
* @param yyscanner The scanner object. * @param yyscanner The scanner object.
* @return the newly allocated buffer state object. * @return the newly allocated buffer state object.
*/ */
YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{ {
YY_BUFFER_STATE b; YY_BUFFER_STATE b;
char *buf; char *buf;
@@ -1965,7 +1990,7 @@ FILE *jq_yyget_out (yyscan_t yyscanner)
/** Get the length of the current token. /** Get the length of the current token.
* @param yyscanner The scanner object. * @param yyscanner The scanner object.
*/ */
yy_size_t jq_yyget_leng (yyscan_t yyscanner) int jq_yyget_leng (yyscan_t yyscanner)
{ {
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng; return yyleng;
@@ -2001,7 +2026,7 @@ void jq_yyset_lineno (int line_number , yyscan_t yyscanner)
/* lineno is only valid if an input buffer exists. */ /* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER ) if (! YY_CURRENT_BUFFER )
YY_FATAL_ERROR( "jq_yyset_lineno called with no buffer" ); yy_fatal_error( "jq_yyset_lineno called with no buffer" , yyscanner);
yylineno = line_number; yylineno = line_number;
} }
@@ -2016,7 +2041,7 @@ void jq_yyset_column (int column_no , yyscan_t yyscanner)
/* column is only valid if an input buffer exists. */ /* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER ) if (! YY_CURRENT_BUFFER )
YY_FATAL_ERROR( "jq_yyset_column called with no buffer" ); yy_fatal_error( "jq_yyset_column called with no buffer" , yyscanner);
yycolumn = column_no; yycolumn = column_no;
} }
@@ -2252,7 +2277,7 @@ void jq_yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables" #define YYTABLES_NAME "yytables"
#line 110 "lexer.l" #line 111 "lexer.l"
/* perhaps these should be calls... */ /* perhaps these should be calls... */

View File

@@ -13,7 +13,7 @@
#define FLEX_SCANNER #define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 37 #define YY_FLEX_SUBMINOR_VERSION 35
#if YY_FLEX_SUBMINOR_VERSION > 0 #if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA #define FLEX_BETA
#endif #endif
@@ -132,7 +132,15 @@ typedef void* yyscan_t;
/* Size of default input buffer. */ /* Size of default input buffer. */
#ifndef YY_BUF_SIZE #ifndef YY_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k.
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
* Ditto for the __ia64__ case accordingly.
*/
#define YY_BUF_SIZE 32768
#else
#define YY_BUF_SIZE 16384 #define YY_BUF_SIZE 16384
#endif /* __ia64__ */
#endif #endif
#ifndef YY_TYPEDEF_YY_BUFFER_STATE #ifndef YY_TYPEDEF_YY_BUFFER_STATE
@@ -162,7 +170,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB /* Number of characters read into yy_ch_buf, not including EOB
* characters. * characters.
*/ */
yy_size_t yy_n_chars; int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it, /* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to * and can realloc() it to grow it, and should free() it to
@@ -206,7 +214,7 @@ void jq_yypop_buffer_state (yyscan_t yyscanner );
YY_BUFFER_STATE jq_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE jq_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
YY_BUFFER_STATE jq_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); YY_BUFFER_STATE jq_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
void *jq_yyalloc (yy_size_t ,yyscan_t yyscanner ); void *jq_yyalloc (yy_size_t ,yyscan_t yyscanner );
void *jq_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); void *jq_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
@@ -214,7 +222,7 @@ void jq_yyfree (void * ,yyscan_t yyscanner );
/* Begin user sect3 */ /* Begin user sect3 */
#define jq_yywrap(yyscanner) 1 #define jq_yywrap(n) 1
#define YY_SKIP_YYWRAP #define YY_SKIP_YYWRAP
#define yytext_ptr yytext_r #define yytext_ptr yytext_r
@@ -264,7 +272,7 @@ FILE *jq_yyget_out (yyscan_t yyscanner );
void jq_yyset_out (FILE * out_str ,yyscan_t yyscanner ); void jq_yyset_out (FILE * out_str ,yyscan_t yyscanner );
yy_size_t jq_yyget_leng (yyscan_t yyscanner ); int jq_yyget_leng (yyscan_t yyscanner );
char *jq_yyget_text (yyscan_t yyscanner ); char *jq_yyget_text (yyscan_t yyscanner );
@@ -272,10 +280,6 @@ int jq_yyget_lineno (yyscan_t yyscanner );
void jq_yyset_lineno (int line_number ,yyscan_t yyscanner ); void jq_yyset_lineno (int line_number ,yyscan_t yyscanner );
int jq_yyget_column (yyscan_t yyscanner );
void jq_yyset_column (int column_no ,yyscan_t yyscanner );
YYSTYPE * jq_yyget_lval (yyscan_t yyscanner ); YYSTYPE * jq_yyget_lval (yyscan_t yyscanner );
void jq_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); void jq_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
@@ -310,7 +314,12 @@ static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
/* Amount of stuff to slurp up with each read. */ /* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE #ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k */
#define YY_READ_BUF_SIZE 16384
#else
#define YY_READ_BUF_SIZE 8192 #define YY_READ_BUF_SIZE 8192
#endif /* __ia64__ */
#endif #endif
/* Number of entries by which start-condition stack grows. */ /* Number of entries by which start-condition stack grows. */
@@ -345,9 +354,9 @@ extern int jq_yylex \
#undef YY_DECL #undef YY_DECL
#endif #endif
#line 110 "lexer.l" #line 111 "lexer.l"
#line 352 "lexer.gen.h" #line 361 "lexer.gen.h"
#undef jq_yyIN_HEADER #undef jq_yyIN_HEADER
#endif /* jq_yyHEADER_H */ #endif /* jq_yyHEADER_H */

View File

@@ -56,6 +56,7 @@ struct lexer_param;
"//=" { return SETDEFINEDOR; } "//=" { return SETDEFINEDOR; }
"<=" { return LESSEQ; } "<=" { return LESSEQ; }
">=" { return GREATEREQ; } ">=" { return GREATEREQ; }
"contains" { return CONTAINS; }
"."|"="|";"|","|":"|"|"|"+"|"-"|"*"|"/"|"\$"|"<"|">" { return yytext[0];} "."|"="|";"|","|":"|"|"|"+"|"-"|"*"|"/"|"\$"|"<"|">" { return yytext[0];}
"["|"{"|"(" { "["|"{"|"(" {

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 2.6.2. */ /* A Bison parser, made by GNU Bison 2.5. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -30,17 +30,9 @@
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
#ifndef YY_PARSER_GEN_H
# define YY_PARSER_GEN_H
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* "%code requires" blocks. */ /* "%code requires" blocks. */
/* Line 2049 of yacc.c */
/* Line 2068 of yacc.c */
#line 9 "parser.y" #line 9 "parser.y"
#include "locfile.h" #include "locfile.h"
@@ -57,8 +49,9 @@ extern int yydebug;
} while (0) } while (0)
/* Line 2049 of yacc.c */
#line 62 "parser.gen.h" /* Line 2068 of yacc.c */
#line 55 "parser.gen.h"
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
@@ -89,33 +82,39 @@ extern int yydebug;
SETDEFINEDOR = 278, SETDEFINEDOR = 278,
LESSEQ = 279, LESSEQ = 279,
GREATEREQ = 280, GREATEREQ = 280,
QQSTRING_START = 281, CONTAINS = 281,
QQSTRING_TEXT = 282, QQSTRING_START = 282,
QQSTRING_INTERP_START = 283, QQSTRING_TEXT = 283,
QQSTRING_INTERP_END = 284, QQSTRING_INTERP_START = 284,
QQSTRING_END = 285 QQSTRING_INTERP_END = 285,
QQSTRING_END = 286
}; };
#endif #endif
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE typedef union YYSTYPE
{ {
/* Line 2049 of yacc.c */
/* Line 2068 of yacc.c */
#line 27 "parser.y" #line 27 "parser.y"
jv literal; jv literal;
block blk; block blk;
/* Line 2049 of yacc.c */
#line 113 "parser.gen.h" /* Line 2068 of yacc.c */
#line 110 "parser.gen.h"
} YYSTYPE; } YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
#endif #endif
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE typedef struct YYLTYPE
{ {
@@ -130,18 +129,4 @@ typedef struct YYLTYPE
#endif #endif
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int yyparse (block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_PARSER_GEN_H */

View File

File diff suppressed because it is too large Load Diff

View File

@@ -65,6 +65,7 @@ struct lexer_param;
%token SETDEFINEDOR "//=" %token SETDEFINEDOR "//="
%token LESSEQ "<=" %token LESSEQ "<="
%token GREATEREQ ">=" %token GREATEREQ ">="
%token CONTAINS "contains"
%token QQSTRING_START %token QQSTRING_START
%token <literal> QQSTRING_TEXT %token <literal> QQSTRING_TEXT
@@ -80,7 +81,7 @@ struct lexer_param;
%nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETDEFINEDOR %nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETDEFINEDOR
%left OR %left OR
%left AND %left AND
%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ %nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ CONTAINS
%left '+' '-' %left '+' '-'
%left '*' '/' %left '*' '/'
@@ -152,6 +153,7 @@ static block gen_binop(block a, block b, int op) {
case '>': funcname = "_greater"; break; case '>': funcname = "_greater"; break;
case LESSEQ: funcname = "_lesseq"; break; case LESSEQ: funcname = "_lesseq"; break;
case GREATEREQ: funcname = "_greatereq"; break; case GREATEREQ: funcname = "_greatereq"; break;
case CONTAINS: funcname = "_contains"; break;
} }
assert(funcname); assert(funcname);
@@ -308,6 +310,10 @@ Exp ">=" Exp {
$$ = gen_binop($1, $3, GREATEREQ); $$ = gen_binop($1, $3, GREATEREQ);
} | } |
Exp "contains" Exp {
$$ = gen_binop($1, $3, CONTAINS);
} |
String { String {
$$ = $1; $$ = $1;
} | } |

View File

@@ -395,3 +395,28 @@ def inc(x): x |= .+1; inc(.[].a)
[{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":18},"world"]},{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":19},"world"]}] [{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":18},"world"]},{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":19},"world"]}]
{} {}
[true,false] [true,false]
# containment operator
["foo" contains "foo", "foobar" contains "foo", "foo" contains "foobar"]
{}
[true, true, false]
[[] contains [], [1,2,3] contains [1,2], [1,2,3] contains [3,1], [1,2,3] contains [4], [1,2,3] contains [1,4]]
{}
[true, true, true, false, false]
[["foobar", "foobaz"] contains ["baz", "bar"], ["foobar", "foobaz"] contains ["foo"], ["foobar", "foobaz"] contains ["blap"]]
{}
[true, true, false]
[{foo: 12, bar:13} contains {foo: 12}, {foo: 12} contains {}, {foo: 12, bar:13} contains {baz:14}]
{}
[true, true, false]
{foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {}}}
{}
true
{foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {bar: 14}}}
{}
false