libidav/davqlparser.c

changeset 92
e073cf4afc6a
parent 91
838b427267bb
child 93
2176ffbf1346
equal deleted inserted replaced
91:838b427267bb 92:e073cf4afc6a
244 244
245 #define _unexpected_end_msg "unexpected end of statement" 245 #define _unexpected_end_msg "unexpected end of statement"
246 #define _invalid_msg "invalid statement" 246 #define _invalid_msg "invalid statement"
247 #define _unexpected_token "unexpected token (%.*s [->]%.*s %.*s)" 247 #define _unexpected_token "unexpected token (%.*s [->]%.*s %.*s)"
248 #define _expected_token "expected token '%s' before '%.*s'" 248 #define _expected_token "expected token '%s' before '%.*s'"
249 #define _expected_by "expected by after order (order [->]%.*s)"
249 #define _missing_quote "missing closing quote symbol (%.*s)" 250 #define _missing_quote "missing closing quote symbol (%.*s)"
250 #define _parser_state "parser reached invalid state" 251 #define _parser_state "parser reached invalid state"
251 #define _unknown_attribute "unknown attribute '%.*s'" 252 #define _unknown_attribute "unknown attribute '%.*s'"
252 #define _duplicated_attribute "duplicated attribute '%.*s'" 253 #define _duplicated_attribute "duplicated attribute '%.*s'"
253 #define _invalid_depth "invalid depth" 254 #define _invalid_depth "invalid depth"
481 } 482 }
482 483
483 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) { 484 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) {
484 stmt->type = DAVQL_GET; 485 stmt->type = DAVQL_GET;
485 486
486 /* 487 #define _step_fieldlist_ 10 // field list
487 * 10: field list 488 #define _step_FROM_ 20 // FROM clause
488 * 20: FROM clause 489 #define _step_expect_WWO_ 530 // expecting WITH, WHERE or ORDER BY clause
489 * 530: expecting WHERE or WITH clause 490 #define _step_comma_WITH_ 531 // expecting comma for WITH clause
490 * 30: WHERE clause 491 #define _step_WITH_ 30 // WITH clause
491 * 540: expecting WITH clause 492 #define _step_expect_WO 540 // expecting WHERE or ORDER BY clause
492 * 541: expecting comma for WITH clause 493 #define _step_WHERE_ 40 // WHERE clause
493 * 40: WITH clause 494 #define _step_expect_O 550 // expecting ORDER BY clause
494 * 500: expect end 495 #define _step_expect_BY 551 // expecting the BY token for the ORDER BY clause
495 * 496 #define _step_ORDER_BY_ 50 // ORDER BY clause
496 */ 497 #define _step_end_ 500 // expect end
497 int step = 10; 498
499 int step = _step_fieldlist_;
498 500
499 // Variables for token sublists for expressions 501 // Variables for token sublists for expressions
500 UcxList *exprstart = NULL; 502 UcxList *exprstart = NULL;
501 size_t exprlen = 0; 503 size_t exprlen = 0;
502 504
508 510
509 sstr_t tokendata = *token_sstr(token); 511 sstr_t tokendata = *token_sstr(token);
510 512
511 switch (step) { 513 switch (step) {
512 // too much input data 514 // too much input data
513 case 500: 515 case _step_end_:
514 dav_parse_unexpected_token(stmt, token); 516 dav_parse_unexpected_token(stmt, token);
515 goto ultrabreak; 517 goto ultrabreak;
516 // optional clauses 518 // optional clauses
517 case 530: 519 case _step_expect_WWO_:
520 if (!sstrcasecmp(tokendata, S("with"))) {
521 step = _step_WITH_;
522 continue;
523 }
524 /* no break and no else*/
525 case _step_expect_WO:
518 if (!sstrcasecmp(tokendata, S("where"))) { 526 if (!sstrcasecmp(tokendata, S("where"))) {
519 step = 30; 527 step = _step_WHERE_;
528 continue;
520 } 529 }
521 /* no break and no else*/ 530 /* no break and no else*/
522 case 540: 531 case _step_expect_O:
523 if (!sstrcasecmp(tokendata, S("with"))) { 532 if (!sstrcasecmp(tokendata, S("order"))) {
524 step = 40; 533 step = _step_expect_BY;
534 continue;
535 } else { // last possible clause checked and not present
536 dav_parse_unexpected_token(stmt, token);
537 goto ultrabreak;
538 }
539 break;
540 case _step_expect_BY:
541 if (!sstrcasecmp(tokendata, S("by"))) {
542 step = _step_ORDER_BY_;
543 } else {
544 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN;
545 stmt->errormessage = ucx_sprintf(_expected_by,
546 sfmtarg(tokendata)).ptr;
547 goto ultrabreak;
548 }
549 break;
550 case _step_comma_WITH_:
551 // a with clause may be continued with a comma
552 // or another clause may follow
553 if (!sstrcmp(tokendata, S(","))) {
554 step = _step_WITH_;
555 } if (!sstrcasecmp(tokendata, S("where"))) {
556 step = _step_WHERE_;
557 } else if (!sstrcasecmp(tokendata, S("order"))) {
558 step = _step_expect_BY;
525 } else { 559 } else {
526 dav_parse_unexpected_token(stmt, token); 560 dav_parse_unexpected_token(stmt, token);
527 goto ultrabreak; 561 goto ultrabreak;
528 } 562 }
529 break; 563 break;
530 case 541:
531 if (!sstrcmp(tokendata, S(","))) {
532 step = 40;
533 } else {
534 dav_parse_unexpected_token(stmt, token);
535 goto ultrabreak;
536 }
537 break;
538 // field list 564 // field list
539 case 10: { 565 case _step_fieldlist_: {
540 _Bool fromkeyword = !sstrcasecmp(tokendata, S("from")); 566 _Bool fromkeyword = !sstrcasecmp(tokendata, S("from"));
541 if (fromkeyword || !sstrcmp(tokendata, S(","))) { 567 if (fromkeyword || !sstrcmp(tokendata, S(","))) {
542 if (exprstart) { 568 if (exprstart) {
543 stmt->fields = ucx_list_append(stmt->fields, 569 stmt->fields = ucx_list_append(stmt->fields,
544 dav_parse_expression(stmt, exprstart, exprlen)); 570 dav_parse_expression(stmt, exprstart, exprlen));
547 } else { 573 } else {
548 // TODO: throw syntax error 574 // TODO: throw syntax error
549 } 575 }
550 576
551 if (fromkeyword) { 577 if (fromkeyword) {
552 step = 20; 578 step = _step_FROM_;
553 } 579 }
554 } else { 580 } else {
555 // collect tokens for field expression 581 // collect tokens for field expression
556 if (exprstart) { 582 if (exprstart) {
557 exprlen++; 583 exprlen++;
561 } 587 }
562 } 588 }
563 break; 589 break;
564 } 590 }
565 // from clause 591 // from clause
566 case 20: { 592 case _step_FROM_: {
567 DavQLExpression *expr = dav_parse_expression(stmt, token, 1); 593 DavQLExpression *expr = dav_parse_expression(stmt, token, 1);
568 stmt->path = expr->srctext; 594 stmt->path = expr->srctext;
569 int exprtype = expr->type; 595 int exprtype = expr->type;
570 dav_free_expression(expr); 596 dav_free_expression(expr);
571 if (exprtype != DAVQL_IDENTIFIER) { 597 if (exprtype != DAVQL_IDENTIFIER) {
572 stmt->errorcode = DAVQL_ERROR_IDENTIFIER_EXPECTED; 598 stmt->errorcode = DAVQL_ERROR_IDENTIFIER_EXPECTED;
573 stmt->errormessage = ucx_sprintf(_identifier_expected, 599 stmt->errormessage = ucx_sprintf(_identifier_expected,
574 sfmtarg(tokendata)).ptr; 600 sfmtarg(tokendata)).ptr;
575 } 601 }
576 step = 530; 602 step = _step_expect_WWO_;
577 break; 603 break;
578 } 604 }
579 // where clause
580 case 30:
581 step = 540;
582 break;
583 // with clause 605 // with clause
584 case 40: { 606 case _step_WITH_: {
585 int withclause_result = dav_parse_with_clause(stmt, token); 607 int withclause_result = dav_parse_with_clause(stmt, token);
586 if (withclause_result < 0) { 608 if (withclause_result < 0) {
587 stmt->errorcode = DAVQL_ERROR_INVALID; 609 stmt->errorcode = DAVQL_ERROR_INVALID;
588 stmt->errormessage = strdup(_parser_state); 610 stmt->errormessage = strdup(_parser_state);
589 } else if (withclause_result > 0) { 611 } else if (withclause_result > 0) {
590 step = 541; 612 step = _step_comma_WITH_;
591 } 613 }
592 break; 614 break;
593 } 615 }
616 // where clause
617 case _step_WHERE_:
618 // TODO: implement
619 step = _step_end_;
620 break;
621 // order by clause
622 case _step_ORDER_BY_:
623 // TODO: implement
624 step = _step_end_;
625 break;
594 default: 626 default:
595 stmt->errorcode = DAVQL_ERROR_INVALID; 627 stmt->errorcode = DAVQL_ERROR_INVALID;
596 stmt->errormessage = strdup(_parser_state); 628 stmt->errormessage = strdup(_parser_state);
597 } 629 }
598 } 630 }
599 631
600 if (!stmt->errorcode && step < 500) { 632 if (!stmt->errorcode && step < _step_end_) {
601 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_END; 633 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_END;
602 stmt->errormessage = strdup(_unexpected_end_msg); 634 stmt->errormessage = strdup(_unexpected_end_msg);
603 } 635 }
604 } 636 }
605 637

mercurial