# HG changeset patch # User Mike Becker # Date 1432037088 -7200 # Node ID 39f4c5fcaa60739d361d1564fc13f0479a2dc460 # Parent 53895e9a4bbbe6455c99d6ce49011292e4397fe6 parser for ParExpression diff -r 53895e9a4bbb -r 39f4c5fcaa60 libidav/davqlparser.c --- 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; diff -r 53895e9a4bbb -r 39f4c5fcaa60 libidav/davqlparser.h --- 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