libidav/davqlparser.c

changeset 109
020a5b5aa510
parent 108
0199f13c7fe2
child 111
39f4c5fcaa60
equal deleted inserted replaced
108:0199f13c7fe2 109:020a5b5aa510
179 sfmtarg(expr->right?expr->right->srctext:empty)); 179 sfmtarg(expr->right?expr->right->srctext:empty));
180 } 180 }
181 } 181 }
182 } 182 }
183 183
184 static void dav_debug_ql_tree_print(DavQLExpression *expr, int depth) {
185 if (expr) {
186 if (expr->left) {
187 printf("%*c%s\n", depth, ' ', _map_operator(expr->op));
188 dav_debug_ql_tree_print(expr->left, depth+1);
189 dav_debug_ql_tree_print(expr->right, depth+1);
190 } else if (expr->type == DAVQL_UNARY) {
191 printf("%*c%s %.*s\n", depth, ' ', _map_operator(expr->op),
192 sfmtarg(expr->srctext));
193 } else {
194 printf("%*c%.*s\n", depth, ' ', sfmtarg(expr->srctext));
195 }
196 }
197 }
198
184 #define DQLD_CMD_Q 0 199 #define DQLD_CMD_Q 0
185 #define DQLD_CMD_PS 1 200 #define DQLD_CMD_PS 1
186 #define DQLD_CMD_PE 2 201 #define DQLD_CMD_PE 2
187 #define DQLD_CMD_PF 3 202 #define DQLD_CMD_PF 3
203 #define DQLD_CMD_PT 4
188 #define DQLD_CMD_F 10 204 #define DQLD_CMD_F 10
189 #define DQLD_CMD_W 11 205 #define DQLD_CMD_W 11
190 #define DQLD_CMD_O 12 206 #define DQLD_CMD_O 12
191 #define DQLD_CMD_L 21 207 #define DQLD_CMD_L 21
192 #define DQLD_CMD_R 22 208 #define DQLD_CMD_R 22
211 return DQLD_CMD_PS; 227 return DQLD_CMD_PS;
212 } else if (!strcmp(buffer, "pe\n")) { 228 } else if (!strcmp(buffer, "pe\n")) {
213 return DQLD_CMD_PE; 229 return DQLD_CMD_PE;
214 } else if (!strcmp(buffer, "pf\n")) { 230 } else if (!strcmp(buffer, "pf\n")) {
215 return DQLD_CMD_PF; 231 return DQLD_CMD_PF;
232 } else if (!strcmp(buffer, "pt\n")) {
233 return DQLD_CMD_PT;
216 } else if (!strcmp(buffer, "l\n")) { 234 } else if (!strcmp(buffer, "l\n")) {
217 return DQLD_CMD_L; 235 return DQLD_CMD_L;
218 } else if (!strcmp(buffer, "r\n")) { 236 } else if (!strcmp(buffer, "r\n")) {
219 return DQLD_CMD_R; 237 return DQLD_CMD_R;
220 } else if (!strcmp(buffer, "h\n")) { 238 } else if (!strcmp(buffer, "h\n")) {
255 int cmd = dav_debug_ql_command(); 273 int cmd = dav_debug_ql_command();
256 switch (cmd) { 274 switch (cmd) {
257 case DQLD_CMD_Q: return; 275 case DQLD_CMD_Q: return;
258 case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break; 276 case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break;
259 case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break; 277 case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break;
278 case DQLD_CMD_PT: dav_debug_ql_tree_print(examineexpr, 1); break;
260 case DQLD_CMD_PF: dav_debug_ql_fnames_print(stmt); break; 279 case DQLD_CMD_PF: dav_debug_ql_fnames_print(stmt); break;
261 case DQLD_CMD_F: 280 case DQLD_CMD_F:
262 if (examineclause != DQLD_CMD_F) { 281 if (examineclause != DQLD_CMD_F) {
263 examineclause = DQLD_CMD_F; 282 examineclause = DQLD_CMD_F;
264 examineelem = stmt->fields; 283 examineelem = stmt->fields;
337 "p: examine previous expression " 356 "p: examine previous expression "
338 "(in order by clause or field list)\n" 357 "(in order by clause or field list)\n"
339 "q: quit\n\n" 358 "q: quit\n\n"
340 "\nExpression examination:\n" 359 "\nExpression examination:\n"
341 "pe: print expression information\n" 360 "pe: print expression information\n"
361 "pt: print full syntax tree of current (sub-)expression\n"
342 "l: enter left subtree\n" 362 "l: enter left subtree\n"
343 "r: enter right subtree\n"); 363 "r: enter right subtree\n");
344 break; 364 break;
345 default: printf("unknown command\n"); 365 default: printf("unknown command\n");
346 } 366 }
582 } else { 602 } else {
583 expr->left = malloc(sizeof(DavQLExpression)); 603 expr->left = malloc(sizeof(DavQLExpression));
584 memcpy(expr->left, &left, sizeof(DavQLExpression)); 604 memcpy(expr->left, &left, sizeof(DavQLExpression));
585 expr->right = malloc(sizeof(DavQLExpression)); 605 expr->right = malloc(sizeof(DavQLExpression));
586 memcpy(expr->right, &right, sizeof(DavQLExpression)); 606 memcpy(expr->right, &right, sizeof(DavQLExpression));
607
608 expr->srctext.ptr = expr->left->srctext.ptr;
609 expr->srctext.length =
610 expr->right->srctext.ptr -
611 expr->left->srctext.ptr + expr->right->srctext.length;
587 } 612 }
588 613
589 return total_consumed; 614 return total_consumed;
590 } 615 }
591 616
625 } 650 }
626 651
627 static int dav_parse_unary_expr(DavQLStatement* stmt, UcxList* token, 652 static int dav_parse_unary_expr(DavQLStatement* stmt, UcxList* token,
628 DavQLExpression* expr) { 653 DavQLExpression* expr) {
629 654
655 DavQLExpression* atom = expr;
656 expr->srctext.ptr = token_sstr(token).ptr;
657
630 int total_consumed = 0; 658 int total_consumed = 0;
631 659
632 // optional unary operator 660 // optional unary operator
633 if (token_is(token, DAVQL_TOKEN_OPERATOR)) { 661 if (token_is(token, DAVQL_TOKEN_OPERATOR)) {
634 char *op = strchr("+-~", token_sstr(token).ptr[0]); 662 char *op = strchr("+-~", token_sstr(token).ptr[0]);
638 case '+': expr->op = DAVQL_ADD; break; 666 case '+': expr->op = DAVQL_ADD; break;
639 case '-': expr->op = DAVQL_SUB; break; 667 case '-': expr->op = DAVQL_SUB; break;
640 case '~': expr->op = DAVQL_NEG; break; 668 case '~': expr->op = DAVQL_NEG; break;
641 } 669 }
642 expr->left = calloc(sizeof(DavQLExpression), 1); 670 expr->left = calloc(sizeof(DavQLExpression), 1);
643 expr = expr->left; 671 atom = expr->left;
644 total_consumed++; 672 total_consumed++;
645 token = token->next; 673 token = token->next;
646 } else { 674 } else {
647 dav_error_in_context(DAVQL_ERROR_INVALID_UNARY_OP, 675 dav_error_in_context(DAVQL_ERROR_INVALID_UNARY_OP,
648 _error_invalid_unary_op, stmt, token); 676 _error_invalid_unary_op, stmt, token);
653 // RULE: (ParExpression | AtomicExpression) 681 // RULE: (ParExpression | AtomicExpression)
654 if (token_is(token, DAVQL_TOKEN_OPENP)) { 682 if (token_is(token, DAVQL_TOKEN_OPENP)) {
655 // TODO: make it so (and don't forget CLOSEP) 683 // TODO: make it so (and don't forget CLOSEP)
656 } else { 684 } else {
657 // RULE: FunctionCall 685 // RULE: FunctionCall
658 int consumed = dav_parse_funccall(stmt, token, expr); 686 int consumed = dav_parse_funccall(stmt, token, atom);
659 if (consumed) { 687 if (consumed) {
660 total_consumed += consumed; 688 total_consumed += consumed;
661 } else if (token_is(token, DAVQL_TOKEN_IDENTIFIER)) { 689 } else if (token_is(token, DAVQL_TOKEN_IDENTIFIER)) {
662 // RULE: Identifier 690 // RULE: Identifier
663 total_consumed++; 691 total_consumed++;
664 expr->type = DAVQL_IDENTIFIER; 692 atom->type = DAVQL_IDENTIFIER;
665 expr->srctext = token_sstr(token); 693 atom->srctext = token_sstr(token);
666 } else { 694 } else {
667 // RULE: Literal 695 // RULE: Literal
668 total_consumed += dav_parse_literal(stmt, token, expr); 696 total_consumed += dav_parse_literal(stmt, token, atom);
669 } 697 }
698 }
699
700 // recover source text
701 if (atom != expr) {
702 expr->srctext.length =
703 atom->srctext.ptr - expr->srctext.ptr + atom->srctext.length;
670 } 704 }
671 705
672 706
673 return total_consumed; 707 return total_consumed;
674 } 708 }
691 dav_parse_multexpr); 725 dav_parse_multexpr);
692 } 726 }
693 727
694 static int dav_parse_expression(DavQLStatement* stmt, UcxList* token, 728 static int dav_parse_expression(DavQLStatement* stmt, UcxList* token,
695 DavQLExpression* expr) { 729 DavQLExpression* expr) {
696
697 // TODO: save source text
698 730
699 return dav_parse_binary_expr(stmt, token, expr, 731 return dav_parse_binary_expr(stmt, token, expr,
700 dav_parse_multexpr, 732 dav_parse_multexpr,
701 "+-", (int[]){DAVQL_ADD, DAVQL_SUB}, 733 "+-", (int[]){DAVQL_ADD, DAVQL_SUB},
702 dav_parse_expression); 734 dav_parse_expression);

mercurial