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

Reply via email to