Changeset: ebf76a0435cb for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ebf76a0435cb
Modified Files:
monetdb5/extras/jaql/jaql.h
monetdb5/extras/jaql/parser/jaql.l
monetdb5/extras/jaql/parser/jaql.y
Branch: jacqueline
Log Message:
parsing: rewrite scanner and parser to explicitly ask for JSON fragments
We need to have access to [ and { chars in the parser, for things like
"var[x]", "sort by [<expr>]" or "transform {$t}" syntax. Make it
explicit when the parser expects a JSON bit (because parsing of that is
deferred to the JSON shredder) so we can prevent parsing JSON twice.
diffs (117 lines):
diff --git a/monetdb5/extras/jaql/jaql.h b/monetdb5/extras/jaql/jaql.h
--- a/monetdb5/extras/jaql/jaql.h
+++ b/monetdb5/extras/jaql/jaql.h
@@ -47,6 +47,7 @@ typedef struct _jvar {
typedef struct _jc {
struct _tree *p;
int esc_depth;
+ char expect_json;
char *buf;
char err[1024];
void *scanner;
diff --git a/monetdb5/extras/jaql/parser/jaql.l
b/monetdb5/extras/jaql/parser/jaql.l
--- a/monetdb5/extras/jaql/parser/jaql.l
+++ b/monetdb5/extras/jaql/parser/jaql.l
@@ -35,6 +35,17 @@ static void readinput(jc *j, char *buf,
%x ARR OBJ
%%
+ /* if the parser expects a JSON bit, give it */
+ if (yyextra->expect_json == '[') {
+ yyextra->esc_depth = 1;
+ yyextra->expect_json = 0;
+ BEGIN(ARR);
+ } else if (yyextra->expect_json == '{') {
+ yyextra->esc_depth = 1;
+ yyextra->expect_json = 0;
+ BEGIN(OBJ);
+ }
+
/* core language */
each return EACH;
filter return FILTER;
@@ -79,30 +90,38 @@ true return _TRUE;
false return _FALSE;
; return _SCOLON;
\. return _DOT;
-"[" yyextra->esc_depth = 1; BEGIN(ARR);
-<ARR>"]" %{
- if (--yyextra->esc_depth == 0) {
- yylval->j_json = GDKstrdup(yytext - 1);
- BEGIN(INITIAL);
- return _ARRAY;
- } else {
- yymore();
- }
-%}
-<ARR>"[" yymore(); yyextra->esc_depth++;
-<ARR>. yymore();
-"{" yyextra->esc_depth = 1; BEGIN(OBJ);
-<OBJ>"}" %{
- if (--yyextra->esc_depth == 0) {
- yylval->j_json = GDKstrdup(yytext - 1);
- BEGIN(INITIAL);
- return _OBJECT;
- } else {
- yymore();
- }
-%}
-<OBJ>"{" yymore(); yyextra->esc_depth++;
-<OBJ>. yymore();
+"(" return '(';
+")" return ')';
+<ARR>{
+ "]" %{
+ if (--yyextra->esc_depth == 0) {
+ yylval->j_json = GDKstrdup(yytext - 1);
+ BEGIN(INITIAL);
+ return _ARRAY;
+ } else {
+ yymore();
+ }
+ %}
+ "[" yymore(); yyextra->esc_depth++;
+ . yymore();
+}
+"]" return ']';
+"[" return '[';
+<OBJ>{
+ "}" %{
+ if (--yyextra->esc_depth == 0) {
+ yylval->j_json = GDKstrdup(yytext - 1);
+ BEGIN(INITIAL);
+ return _OBJECT;
+ } else {
+ yymore();
+ }
+ %}
+ "{" yymore(); yyextra->esc_depth++;
+ . yymore();
+}
+"}" return '}';
+"{" return '{';
[ \t\r\n]+ /* ignore whitespace */;
[a-zA-Z_][a-zA-Z0-9_]* {yylval->j_ident = GDKstrdup(yytext); return _IDENT;}
<<EOF>> {yyextra->buf = NULL; return EOF;}
diff --git a/monetdb5/extras/jaql/parser/jaql.y
b/monetdb5/extras/jaql/parser/jaql.y
--- a/monetdb5/extras/jaql/parser/jaql.y
+++ b/monetdb5/extras/jaql/parser/jaql.y
@@ -109,7 +109,8 @@ jaql: jaqlpipe {$$ = ap
;
jaqlpipe: _IDENT opt_actions {$$ = append_jaql_pipe(make_varname($1), $2);}
- | _ARRAY opt_actions {$$ = append_jaql_pipe(make_json($1),
$2);}
+ | '[' {j->expect_json = '[';}
+ _ARRAY opt_actions {$$ = append_jaql_pipe(make_json($3),
$4);}
;
opt_actions: /* empty */ {$$ = NULL;}
@@ -182,6 +183,6 @@ literal: _NUMBER {$$ = make_number($1);
| _FALSE {$$ = make_bool(0);}
;
-json_fragment: _ARRAY {$$ = make_json($1);}
- | _OBJECT {$$ = make_json($1);}
+json_fragment: '[' {j->expect_json = '[';} _ARRAY {$$ = make_json($3);}
+ | '{' {j->expect_json = '{';} _OBJECT {$$ =
make_json($3);}
;
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list