libidav/davqlparser.c

changeset 107
a0903d2d8e3e
parent 106
9cec78f23cbf
child 108
0199f13c7fe2
equal deleted inserted replaced
106:9cec78f23cbf 107:a0903d2d8e3e
354 #define _error_context "(%.*s [->]%.*s %.*s)" 354 #define _error_context "(%.*s [->]%.*s %.*s)"
355 #define _error_invalid "invalid statement" 355 #define _error_invalid "invalid statement"
356 #define _error_unhandled "unhandled error " _error_context 356 #define _error_unhandled "unhandled error " _error_context
357 #define _error_unexpected_token "unexpected token " _error_context 357 #define _error_unexpected_token "unexpected token " _error_context
358 #define _error_invalid_token "invalid token " _error_context 358 #define _error_invalid_token "invalid token " _error_context
359 #define _error_missing_from "missing FROM keyword " _error_context 359 #define _error_missing_path "expected path " _error_context
360 #define _error_missing_by "missing BY keyword " _error_context 360 #define _error_missing_from "expecting FROM keyword " _error_context
361 #define _error_missing_by "expecting BY keyword " _error_context
361 #define _error_invalid_depth "invalid depth " _error_context 362 #define _error_invalid_depth "invalid depth " _error_context
362 #define _error_missing_expr "missing expression " _error_context 363 #define _error_missing_expr "missing expression " _error_context
363 #define _error_invalid_unary_op "invalid unary operator " _error_context 364 #define _error_invalid_unary_op "invalid unary operator " _error_context
365 #define _error_invalid_fmtspec "invalid format specifier " _error_context
364 366
365 #define token_sstr(token) (((DavQLToken*)(token)->data)->value) 367 #define token_sstr(token) (((DavQLToken*)(token)->data)->value)
366 368
367 static void dav_error_in_context(int errorcode, const char *errormsg, 369 static void dav_error_in_context(int errorcode, const char *errormsg,
368 DavQLStatement *stmt, UcxList *token) { 370 DavQLStatement *stmt, UcxList *token) {
537 539
538 static int dav_parse_binary_expr(DavQLStatement* stmt, UcxList* token, 540 static int dav_parse_binary_expr(DavQLStatement* stmt, UcxList* token,
539 DavQLExpression* expr, exprparser_f parseL, char* opc, int* opv, 541 DavQLExpression* expr, exprparser_f parseL, char* opc, int* opv,
540 exprparser_f parseR) { 542 exprparser_f parseR) {
541 543
542 int total_consumed = 0, consumed; 544 if (!token) {
545 return 0;
546 }
547
548 int total_consumed = 0, consumed;
543 549
544 // save temporarily on stack (copy to heap later on) 550 // save temporarily on stack (copy to heap later on)
545 DavQLExpression left, right; 551 DavQLExpression left, right;
546 552
547 // RULE: LEFT, [Operator, RIGHT] 553 // RULE: LEFT, [Operator, RIGHT]
551 return 0; 557 return 0;
552 } 558 }
553 total_consumed += consumed; 559 total_consumed += consumed;
554 token = ucx_list_get(token, consumed); 560 token = ucx_list_get(token, consumed);
555 561
556 char *op = strchr(opc, token_sstr(token).ptr[0]); // locate operator 562 char *op;
557 if (token_is(token, DAVQL_TOKEN_OPERATOR) && op) { 563 if (token_is(token, DAVQL_TOKEN_OPERATOR) &&
564 (op = strchr(opc, token_sstr(token).ptr[0]))) {
558 expr->op = opv[op-opc]; 565 expr->op = opv[op-opc];
559 total_consumed++; 566 total_consumed++;
560 token = token->next; 567 token = token->next;
561 memset(&right, 0, sizeof(DavQLExpression)); 568 memset(&right, 0, sizeof(DavQLExpression));
562 consumed = parseR(stmt, token, &right); 569 consumed = parseR(stmt, token, &right);
578 } 585 }
579 586
580 return total_consumed; 587 return total_consumed;
581 } 588 }
582 589
590 static int dav_parse_literal(DavQLStatement* stmt, UcxList* token,
591 DavQLExpression* expr) {
592
593 expr->srctext = token_sstr(token);
594 if (token_is(token, DAVQL_TOKEN_NUMBER)) {
595 expr->type = DAVQL_NUMBER;
596 } else if (token_is(token, DAVQL_TOKEN_STRING)) {
597 expr->type = DAVQL_STRING;
598 } else if (token_is(token, DAVQL_TOKEN_TIMESTAMP)) {
599 expr->type = DAVQL_TIMESTAMP;
600 } else if (token_is(token, DAVQL_TOKEN_FMTSPEC)
601 && expr->srctext.length == 2) {
602 switch (expr->srctext.ptr[1]) {
603 case 'd': expr->type = DAVQL_NUMBER; break;
604 case 's': expr->type = DAVQL_STRING; break;
605 case 't': expr->type = DAVQL_TIMESTAMP; break;
606 default:
607 dav_error_in_context(DAVQL_ERROR_INVALID_FMTSPEC,
608 _error_invalid_fmtspec, stmt, token);
609 return 0;
610 }
611 } else {
612 return 0;
613 }
614
615 return 1;
616 }
617
618 static int dav_parse_funccall(DavQLStatement* stmt, UcxList* token,
619 DavQLExpression* expr) {
620
621 // TODO: make it so
622 return 0;
623 }
583 624
584 static int dav_parse_unary_expr(DavQLStatement* stmt, UcxList* token, 625 static int dav_parse_unary_expr(DavQLStatement* stmt, UcxList* token,
585 DavQLExpression* expr) { 626 DavQLExpression* expr) {
586 627
587 int total_consumed = 0; 628 int total_consumed = 0;
588 DavQLExpression *litexpr = expr; 629
589
590 // optional unary operator 630 // optional unary operator
591 if (token_is(token, DAVQL_TOKEN_OPERATOR)) { 631 if (token_is(token, DAVQL_TOKEN_OPERATOR)) {
592 char *op = strchr("+-~", token_sstr(token).ptr[0]); 632 char *op = strchr("+-~", token_sstr(token).ptr[0]);
593 if (op) { 633 if (op) {
594 expr->type = DAVQL_UNARY; 634 expr->type = DAVQL_UNARY;
596 case '+': expr->op = DAVQL_ADD; break; 636 case '+': expr->op = DAVQL_ADD; break;
597 case '-': expr->op = DAVQL_SUB; break; 637 case '-': expr->op = DAVQL_SUB; break;
598 case '~': expr->op = DAVQL_NEG; break; 638 case '~': expr->op = DAVQL_NEG; break;
599 } 639 }
600 expr->left = calloc(sizeof(DavQLExpression), 1); 640 expr->left = calloc(sizeof(DavQLExpression), 1);
601 litexpr = expr->left; 641 expr = expr->left;
602 total_consumed++; 642 total_consumed++;
603 token = token->next; 643 token = token->next;
604 } else { 644 } else {
605 dav_error_in_context(DAVQL_ERROR_INVALID_UNARY_OP, 645 dav_error_in_context(DAVQL_ERROR_INVALID_UNARY_OP,
606 _error_invalid_unary_op, stmt, token); 646 _error_invalid_unary_op, stmt, token);
611 // RULE: (ParExpression | AtomicExpression) 651 // RULE: (ParExpression | AtomicExpression)
612 if (token_is(token, DAVQL_TOKEN_OPENP)) { 652 if (token_is(token, DAVQL_TOKEN_OPENP)) {
613 // TODO: make it so (and don't forget CLOSEP) 653 // TODO: make it so (and don't forget CLOSEP)
614 } else { 654 } else {
615 // RULE: FunctionCall 655 // RULE: FunctionCall
616 // TODO: make it so 656 int consumed = dav_parse_funccall(stmt, token, expr);
617 657 if (consumed) {
618 // RULE: Identifier 658 total_consumed += consumed;
619 /*else*/ if (token_is(token, DAVQL_TOKEN_IDENTIFIER)) { 659 } else if (token_is(token, DAVQL_TOKEN_IDENTIFIER)) {
660 // RULE: Identifier
620 total_consumed++; 661 total_consumed++;
621 litexpr->type = DAVQL_IDENTIFIER; 662 expr->type = DAVQL_IDENTIFIER;
622 litexpr->srctext = token_sstr(token); 663 expr->srctext = token_sstr(token);
623 } 664 } else {
624 665 // RULE: Literal
625 // RULE: Literal 666 total_consumed += dav_parse_literal(stmt, token, expr);
626 // TODO: make it so 667 }
627 } 668 }
628 669
629 670
630 return total_consumed; 671 return total_consumed;
631 } 672 }
655 696
656 return dav_parse_binary_expr(stmt, token, expr, 697 return dav_parse_binary_expr(stmt, token, expr,
657 dav_parse_multexpr, 698 dav_parse_multexpr,
658 "+-", (int[]){DAVQL_ADD, DAVQL_SUB}, 699 "+-", (int[]){DAVQL_ADD, DAVQL_SUB},
659 dav_parse_expression); 700 dav_parse_expression);
660 }
661
662 static int dav_parse_format_spec(DavQLStatement* stmt, UcxList* token) {
663
664 return 0;
665 } 701 }
666 702
667 static int dav_parse_fieldlist(DavQLStatement *stmt, UcxList *token) { 703 static int dav_parse_fieldlist(DavQLStatement *stmt, UcxList *token) {
668 704
669 // RULE: "-" 705 // RULE: "-"
817 while (!token_is(tokens, DAVQL_TOKEN_KEYWORD)) { 853 while (!token_is(tokens, DAVQL_TOKEN_KEYWORD)) {
818 sstr_t toksstr = token_sstr(tokens); 854 sstr_t toksstr = token_sstr(tokens);
819 stmt->path.length = toksstr.ptr-stmt->path.ptr+toksstr.length; 855 stmt->path.length = toksstr.ptr-stmt->path.ptr+toksstr.length;
820 tokens = tokens->next; 856 tokens = tokens->next;
821 } 857 }
822 } else if (token_is(tokens, DAVQL_TOKEN_FMTSPEC)) { 858 } else if (token_is(tokens, DAVQL_TOKEN_FMTSPEC) &&
823 // TODO: make it so 859 tokenvalue_is(tokens, "%s")) {
860 stmt->path = token_sstr(tokens);
861 tokens = tokens->next;
862 } else {
863 dav_error_in_context(DAVQL_ERROR_MISSING_TOKEN,
864 _error_missing_path, stmt, tokens);
865 return;
824 } 866 }
825 867
826 // Consume with clause (if any) 868 // Consume with clause (if any)
827 if (token_is(tokens, DAVQL_TOKEN_KEYWORD) 869 if (token_is(tokens, DAVQL_TOKEN_KEYWORD)
828 && tokenvalue_is(tokens, "with")) { 870 && tokenvalue_is(tokens, "with")) {

mercurial