libidav/davqlparser.c

changeset 111
39f4c5fcaa60
parent 109
020a5b5aa510
child 113
412b06dc0162
equal deleted inserted replaced
110:53895e9a4bbb 111:39f4c5fcaa60
377 #define _error_unexpected_token "unexpected token " _error_context 377 #define _error_unexpected_token "unexpected token " _error_context
378 #define _error_invalid_token "invalid token " _error_context 378 #define _error_invalid_token "invalid token " _error_context
379 #define _error_missing_path "expected path " _error_context 379 #define _error_missing_path "expected path " _error_context
380 #define _error_missing_from "expecting FROM keyword " _error_context 380 #define _error_missing_from "expecting FROM keyword " _error_context
381 #define _error_missing_by "expecting BY keyword " _error_context 381 #define _error_missing_by "expecting BY keyword " _error_context
382 #define _error_missing_par "missing closed parenthesis " _error_context
382 #define _error_invalid_depth "invalid depth " _error_context 383 #define _error_invalid_depth "invalid depth " _error_context
383 #define _error_missing_expr "missing expression " _error_context 384 #define _error_missing_expr "missing expression " _error_context
384 #define _error_invalid_expr "invalid expression " _error_context 385 #define _error_invalid_expr "invalid expression " _error_context
385 #define _error_invalid_unary_op "invalid unary operator " _error_context 386 #define _error_invalid_unary_op "invalid unary operator " _error_context
386 #define _error_invalid_fmtspec "invalid format specifier " _error_context 387 #define _error_invalid_fmtspec "invalid format specifier " _error_context
647 648
648 // TODO: make it so 649 // TODO: make it so
649 return 0; 650 return 0;
650 } 651 }
651 652
653 // forward declaration
654 static int dav_parse_expression(DavQLStatement* stmt, UcxList* token,
655 DavQLExpression* expr);
656
652 static int dav_parse_unary_expr(DavQLStatement* stmt, UcxList* token, 657 static int dav_parse_unary_expr(DavQLStatement* stmt, UcxList* token,
653 DavQLExpression* expr) { 658 DavQLExpression* expr) {
654 659
660 UcxList *firsttoken = token; // save for srctext recovery
661
655 DavQLExpression* atom = expr; 662 DavQLExpression* atom = expr;
656 expr->srctext.ptr = token_sstr(token).ptr;
657
658 int total_consumed = 0; 663 int total_consumed = 0;
659 664
660 // optional unary operator 665 // optional unary operator
661 if (token_is(token, DAVQL_TOKEN_OPERATOR)) { 666 if (token_is(token, DAVQL_TOKEN_OPERATOR)) {
662 char *op = strchr("+-~", token_sstr(token).ptr[0]); 667 char *op = strchr("+-~", token_sstr(token).ptr[0]);
678 } 683 }
679 } 684 }
680 685
681 // RULE: (ParExpression | AtomicExpression) 686 // RULE: (ParExpression | AtomicExpression)
682 if (token_is(token, DAVQL_TOKEN_OPENP)) { 687 if (token_is(token, DAVQL_TOKEN_OPENP)) {
683 // TODO: make it so (and don't forget CLOSEP) 688 token = token->next; total_consumed++;
689 // RULE: "(", Expression, ")"
690 int consumed = dav_parse_expression(stmt, token, atom);
691 if (stmt->errorcode) {
692 return 0;
693 }
694 if (!consumed) {
695 dav_error_in_context(DAVQL_ERROR_INVALID_EXPR,
696 _error_invalid_expr, stmt, token);
697 return 0;
698 }
699 token = ucx_list_get(token, consumed);
700 total_consumed += consumed;
701 if (token_is(token, DAVQL_TOKEN_CLOSEP)) {
702 token = token->next; total_consumed++;
703 } else {
704 dav_error_in_context(DAVQL_ERROR_MISSING_PAR,
705 _error_missing_par, stmt, token);
706 return 0;
707 }
684 } else { 708 } else {
685 // RULE: FunctionCall 709 // RULE: FunctionCall
686 int consumed = dav_parse_funccall(stmt, token, atom); 710 int consumed = dav_parse_funccall(stmt, token, atom);
687 if (consumed) { 711 if (consumed) {
688 total_consumed += consumed; 712 total_consumed += consumed;
696 total_consumed += dav_parse_literal(stmt, token, atom); 720 total_consumed += dav_parse_literal(stmt, token, atom);
697 } 721 }
698 } 722 }
699 723
700 // recover source text 724 // recover source text
701 if (atom != expr) { 725 expr->srctext.ptr = token_sstr(firsttoken).ptr;
702 expr->srctext.length = 726 sstr_t lasttoken = token_sstr(ucx_list_get(firsttoken, total_consumed-1));
703 atom->srctext.ptr - expr->srctext.ptr + atom->srctext.length; 727 expr->srctext.length = lasttoken.ptr - expr->srctext.ptr + lasttoken.length;
704 }
705 728
706 729
707 return total_consumed; 730 return total_consumed;
708 } 731 }
709 732

mercurial