implement POSIX regexp support
[project/jsonpath.git] / parser.y
index 9c06c07..4d3581e 100644 (file)
--- a/parser.y
+++ b/parser.y
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
+ * Copyright (C) 2013-2014 Jo-Philipp Wich <jo@mein.io>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
 %left T_AND.
 %left T_OR.
 %left T_UNION.
-%nonassoc T_EQ T_NE T_GT T_GE T_LT T_LE.
+%nonassoc T_EQ T_NE T_GT T_GE T_LT T_LE T_MATCH.
 %right T_NOT.
 
 %include {
 }
 
 %syntax_error {
-       int n = sizeof(tokennames) / sizeof(tokennames[0]);
-       int l = strlen("Expecting ");
-       int c = 0;
        int i;
 
-       for (i = 0; i < n; i++)
-       {
+       for (i = 0; i < sizeof(tokennames) / sizeof(tokennames[0]); i++)
                if (yy_find_shift_action(yypParser, (YYCODETYPE)i) < YYNSTATE + YYNRULE)
-                       l += strlen(tokennames[i]) + 4;
-       }
-
-       s->error = malloc(l);
-
-       if (s->error)
-       {
-               s->erroff = s->off;
-               strcpy(s->error, "Expecting ");
-
-               for (i = 0; i < n; i++)
-               {
-                       if (yy_find_shift_action(yypParser, (YYCODETYPE)i) < YYNSTATE + YYNRULE)
-                       {
-                               if (c++)
-                                       strcat(s->error, " or ");
-
-                               strcat(s->error, tokennames[i]);
-                       }
-               }
-       }
+                       s->error_code |= (1 << i);
+
+       s->error_pos = s->off;
 }
 
 
@@ -78,6 +56,8 @@ expr(A) ::= path(B).                                                          { A = B; }
 
 path(A) ::= T_ROOT segments(B).                                                { A = alloc_op(T_ROOT, 0, NULL, B); }
 path(A) ::= T_THIS segments(B).                                                { A = alloc_op(T_THIS, 0, NULL, B); }
+path(A) ::= T_ROOT(B).                                                         { A = B; }
+path(A) ::= T_THIS(B).                                                         { A = B; }
 
 segments(A) ::= segments(B) segment(C).                                { A = append_op(B, C); }
 segments(A) ::= segment(B).                                                    { A = B; }
@@ -107,11 +87,13 @@ cmp_exp(A) ::= unary_exp(B) T_GT unary_exp(C).             { A = alloc_op(T_GT, 0, NULL, B,
 cmp_exp(A) ::= unary_exp(B) T_GE unary_exp(C).         { A = alloc_op(T_GE, 0, NULL, B, C); }
 cmp_exp(A) ::= unary_exp(B) T_EQ unary_exp(C).         { A = alloc_op(T_EQ, 0, NULL, B, C); }
 cmp_exp(A) ::= unary_exp(B) T_NE unary_exp(C).         { A = alloc_op(T_NE, 0, NULL, B, C); }
+cmp_exp(A) ::= unary_exp(B) T_MATCH unary_exp(C).      { A = alloc_op(T_MATCH, 0, NULL, B, C); }
 cmp_exp(A) ::= unary_exp(B).                                           { A = B; }
 
 unary_exp(A) ::= T_BOOL(B).                                                    { A = B; }
 unary_exp(A) ::= T_NUMBER(B).                                          { A = B; }
 unary_exp(A) ::= T_STRING(B).                                          { A = B; }
+unary_exp(A) ::= T_REGEXP(B).                                          { A = B; }
 unary_exp(A) ::= T_WILDCARD(B).                                                { A = B; }
 unary_exp(A) ::= T_POPEN or_exps(B) T_PCLOSE.          { A = B; }
 unary_exp(A) ::= T_NOT unary_exp(B).                           { A = alloc_op(T_NOT, 0, NULL, B); }