parser for ParExpression

Tue, 19 May 2015 14:04:48 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 19 May 2015 14:04:48 +0200
changeset 111
39f4c5fcaa60
parent 110
53895e9a4bbb
child 112
f62d271675bf

parser for ParExpression

libidav/davqlparser.c file | annotate | diff | comparison | revisions
libidav/davqlparser.h file | annotate | diff | comparison | revisions
--- a/libidav/davqlparser.c	Tue May 19 10:46:32 2015 +0200
+++ b/libidav/davqlparser.c	Tue May 19 14:04:48 2015 +0200
@@ -379,6 +379,7 @@
 #define _error_missing_path "expected path " _error_context
 #define _error_missing_from "expecting FROM keyword " _error_context
 #define _error_missing_by "expecting BY keyword " _error_context
+#define _error_missing_par "missing closed parenthesis " _error_context
 #define _error_invalid_depth "invalid depth " _error_context
 #define _error_missing_expr "missing expression " _error_context
 #define _error_invalid_expr "invalid expression " _error_context
@@ -649,12 +650,16 @@
     return 0;
 }
 
+// forward declaration
+static int dav_parse_expression(DavQLStatement* stmt, UcxList* token,
+        DavQLExpression* expr);
+
 static int dav_parse_unary_expr(DavQLStatement* stmt, UcxList* token,
         DavQLExpression* expr) {
     
+    UcxList *firsttoken = token; // save for srctext recovery
+    
     DavQLExpression* atom = expr;
-    expr->srctext.ptr = token_sstr(token).ptr;
-    
     int total_consumed = 0;
    
     // optional unary operator
@@ -680,7 +685,26 @@
     
     // RULE:    (ParExpression | AtomicExpression)
     if (token_is(token, DAVQL_TOKEN_OPENP)) {
-        // TODO: make it so (and don't forget CLOSEP)
+        token = token->next; total_consumed++;
+        // RULE:    "(", Expression, ")"
+        int consumed = dav_parse_expression(stmt, token, atom);
+        if (stmt->errorcode) {
+            return 0;
+        }
+        if (!consumed) {
+            dav_error_in_context(DAVQL_ERROR_INVALID_EXPR,
+                _error_invalid_expr, stmt, token);
+            return 0;
+        }
+        token = ucx_list_get(token, consumed);
+        total_consumed += consumed;
+        if (token_is(token, DAVQL_TOKEN_CLOSEP)) {
+            token = token->next; total_consumed++;
+        } else {
+            dav_error_in_context(DAVQL_ERROR_MISSING_PAR,
+                _error_missing_par, stmt, token);
+            return 0;
+        }
     } else {
         // RULE:    FunctionCall
         int consumed = dav_parse_funccall(stmt, token, atom);
@@ -698,10 +722,9 @@
     }
     
     // recover source text
-    if (atom != expr) {
-        expr->srctext.length =
-            atom->srctext.ptr - expr->srctext.ptr + atom->srctext.length;
-    }
+    expr->srctext.ptr = token_sstr(firsttoken).ptr;
+    sstr_t lasttoken = token_sstr(ucx_list_get(firsttoken, total_consumed-1));
+    expr->srctext.length = lasttoken.ptr - expr->srctext.ptr + lasttoken.length;
     
     
     return total_consumed;
--- a/libidav/davqlparser.h	Tue May 19 10:46:32 2015 +0200
+++ b/libidav/davqlparser.h	Tue May 19 14:04:48 2015 +0200
@@ -295,6 +295,9 @@
 /** An expression has been expected, but was not found. */
 #define DAVQL_ERROR_MISSING_EXPR 12
 
+/** A closed parenthesis ')' is missing. */
+#define DAVQL_ERROR_MISSING_PAR 13
+
 /** The type of the expression could not be determined. */
 #define DAVQL_ERROR_INVALID_EXPR 21
 

mercurial