180 sfmtarg(expr->right?expr->right->srctext:empty)); |
180 sfmtarg(expr->right?expr->right->srctext:empty)); |
181 } |
181 } |
182 } |
182 } |
183 } |
183 } |
184 |
184 |
|
185 static void dav_debug_ql_field_print(DavQLField *field) { |
|
186 if (field) { |
|
187 printf("Name: %.*s\n", sfmtarg(field->name)); |
|
188 if (field->expr) { |
|
189 dav_debug_ql_expr_print(field->expr); |
|
190 } else { |
|
191 printf("No expression.\n"); |
|
192 } |
|
193 } else { |
|
194 printf("No field selected.\n"); |
|
195 } |
|
196 } |
|
197 |
185 static void dav_debug_ql_tree_print(DavQLExpression *expr, int depth) { |
198 static void dav_debug_ql_tree_print(DavQLExpression *expr, int depth) { |
186 if (expr) { |
199 if (expr) { |
187 if (expr->left) { |
200 if (expr->left) { |
188 printf("%*c%s\n", depth, ' ', _map_operator(expr->op)); |
201 printf("%*c%s\n", depth, ' ', _map_operator(expr->op)); |
189 dav_debug_ql_tree_print(expr->left, depth+1); |
202 dav_debug_ql_tree_print(expr->left, depth+1); |
279 case DQLD_CMD_PT: dav_debug_ql_tree_print(examineexpr, 1); break; |
292 case DQLD_CMD_PT: dav_debug_ql_tree_print(examineexpr, 1); break; |
280 case DQLD_CMD_PF: dav_debug_ql_fnames_print(stmt); break; |
293 case DQLD_CMD_PF: dav_debug_ql_fnames_print(stmt); break; |
281 case DQLD_CMD_F: |
294 case DQLD_CMD_F: |
282 examineclause = DQLD_CMD_F; |
295 examineclause = DQLD_CMD_F; |
283 examineelem = stmt->fields; |
296 examineelem = stmt->fields; |
284 examineexpr = stmt->fields ? |
297 if (stmt->fields) { |
285 ((DavQLField*)stmt->fields->data)->expr : NULL; |
298 DavQLField* field = ((DavQLField*)stmt->fields->data); |
286 dav_debug_ql_expr_print(examineexpr); |
299 examineexpr = field->expr; |
|
300 dav_debug_ql_field_print(field); |
|
301 } else { |
|
302 examineexpr = NULL; |
|
303 } |
287 break; |
304 break; |
288 case DQLD_CMD_W: |
305 case DQLD_CMD_W: |
289 examineclause = 0; examineelem = NULL; |
306 examineclause = 0; examineelem = NULL; |
290 examineexpr = stmt->where; |
307 examineexpr = stmt->where; |
291 dav_debug_ql_expr_print(examineexpr); |
308 dav_debug_ql_expr_print(examineexpr); |
305 if (newelem) { |
322 if (newelem) { |
306 examineelem = newelem; |
323 examineelem = newelem; |
307 if (examineclause == DQLD_CMD_O) { |
324 if (examineclause == DQLD_CMD_O) { |
308 examineexpr = ((DavQLOrderCriterion*) |
325 examineexpr = ((DavQLOrderCriterion*) |
309 examineelem->data)->column; |
326 examineelem->data)->column; |
|
327 dav_debug_ql_expr_print(examineexpr); |
310 } else if (examineclause == DQLD_CMD_F) { |
328 } else if (examineclause == DQLD_CMD_F) { |
311 examineexpr = ((DavQLField*)examineelem->data)->expr; |
329 DavQLField* field = (DavQLField*)examineelem->data; |
|
330 examineexpr = field->expr; |
|
331 dav_debug_ql_field_print(field); |
312 } else { |
332 } else { |
313 printf("Examining unknown clause type."); |
333 printf("Examining unknown clause type."); |
314 } |
334 } |
315 dav_debug_ql_expr_print(examineexpr); |
|
316 } else { |
335 } else { |
317 printf("Reached end of list.\n"); |
336 printf("Reached end of list.\n"); |
318 } |
337 } |
319 } else { |
338 } else { |
320 printf("Currently not examining an expression list.\n"); |
339 printf("Currently not examining an expression list.\n"); |
377 #define _error_missing_from "expecting FROM keyword " _error_context |
396 #define _error_missing_from "expecting FROM keyword " _error_context |
378 #define _error_missing_by "expecting BY keyword " _error_context |
397 #define _error_missing_by "expecting BY keyword " _error_context |
379 #define _error_missing_as "expecting alias ('as <identifier>') " _error_context |
398 #define _error_missing_as "expecting alias ('as <identifier>') " _error_context |
380 #define _error_missing_identifier "expecting identifier " _error_context |
399 #define _error_missing_identifier "expecting identifier " _error_context |
381 #define _error_missing_par "missing closed parenthesis " _error_context |
400 #define _error_missing_par "missing closed parenthesis " _error_context |
|
401 #define _error_missing_assign "expecting assignment ('=') " _error_context |
382 #define _error_invalid_depth "invalid depth " _error_context |
402 #define _error_invalid_depth "invalid depth " _error_context |
383 #define _error_missing_expr "missing expression " _error_context |
403 #define _error_missing_expr "missing expression " _error_context |
384 #define _error_invalid_expr "invalid expression " _error_context |
404 #define _error_invalid_expr "invalid expression " _error_context |
385 #define _error_invalid_unary_op "invalid unary operator " _error_context |
405 #define _error_invalid_unary_op "invalid unary operator " _error_context |
386 #define _error_invalid_logical_op "invalid logical operator " _error_context |
406 #define _error_invalid_logical_op "invalid logical operator " _error_context |
1456 } while (consumed); |
1476 } while (consumed); |
1457 |
1477 |
1458 return total_consumed; |
1478 return total_consumed; |
1459 } |
1479 } |
1460 |
1480 |
|
1481 |
|
1482 static int dav_parse_assignments(DavQLStatement *stmt, UcxList *token) { |
|
1483 |
|
1484 // RULE: Assignment, {",", Assignment} |
|
1485 int total_consumed = 0, consumed; |
|
1486 do { |
|
1487 // RULE: Identifier, "=", Expression |
|
1488 if (token_is(token, DAVQL_TOKEN_IDENTIFIER)) { |
|
1489 |
|
1490 // Identifier |
|
1491 DavQLField *field; |
|
1492 dqlsec_malloc(stmt, field, DavQLField); |
|
1493 field->name = token_sstr(token); |
|
1494 total_consumed++; |
|
1495 token = token->next; |
|
1496 |
|
1497 // "=" |
|
1498 if (!token_is(token, DAVQL_TOKEN_OPERATOR) |
|
1499 || !tokenvalue_is(token, "=")) { |
|
1500 dav_free_field(field); |
|
1501 |
|
1502 dav_error_in_context(DAVQL_ERROR_MISSING_ASSIGN, |
|
1503 _error_missing_assign, stmt, token); |
|
1504 return total_consumed; |
|
1505 } |
|
1506 total_consumed++; |
|
1507 token = token->next; |
|
1508 |
|
1509 // Expression |
|
1510 dqlsec_mallocz(stmt, field->expr, DavQLExpression); |
|
1511 consumed = dav_parse_expression(stmt, token, field->expr); |
|
1512 if (stmt->errorcode) { |
|
1513 dav_free_field(field); |
|
1514 return total_consumed; |
|
1515 } |
|
1516 token = ucx_list_get(token, consumed); |
|
1517 total_consumed += consumed; |
|
1518 |
|
1519 // Add assignment to list and check if there's another one |
|
1520 dqlsec_list_append_or_free(stmt, stmt->fields, field); |
|
1521 consumed = token_is(token, DAVQL_TOKEN_COMMA) ? 1 : 0; |
|
1522 if (consumed) { |
|
1523 token = token->next; |
|
1524 total_consumed++; |
|
1525 } |
|
1526 } else { |
|
1527 dav_error_in_context(DAVQL_ERROR_MISSING_TOKEN, |
|
1528 _error_missing_identifier, stmt, token); |
|
1529 return total_consumed; |
|
1530 } |
|
1531 } while (consumed); |
|
1532 |
|
1533 return total_consumed; |
|
1534 } |
|
1535 |
1461 /** |
1536 /** |
1462 * Parser of a select statement. |
1537 * Parser of a select statement. |
1463 * @param stmt the statement object that shall contain the syntax tree |
1538 * @param stmt the statement object that shall contain the syntax tree |
1464 * @param tokens the token list |
1539 * @param tokens the token list |
1465 */ |
1540 */ |
1560 } |
1635 } |
1561 |
1636 |
1562 static void dav_parse_set_statement(DavQLStatement *stmt, UcxList *tokens) { |
1637 static void dav_parse_set_statement(DavQLStatement *stmt, UcxList *tokens) { |
1563 stmt->type = DAVQL_SET; |
1638 stmt->type = DAVQL_SET; |
1564 |
1639 |
|
1640 // Consume assignments |
|
1641 tokens = ucx_list_get(tokens, dav_parse_assignments(stmt, tokens)); |
|
1642 if (stmt->errorcode) { |
|
1643 return; |
|
1644 } |
|
1645 |
1565 // TODO: make it so |
1646 // TODO: make it so |
1566 } |
1647 } |
1567 |
1648 |
1568 DavQLStatement* dav_parse_statement(sstr_t srctext) { |
1649 DavQLStatement* dav_parse_statement(sstr_t srctext) { |
1569 DavQLStatement *stmt = calloc(1, sizeof(DavQLStatement)); |
1650 DavQLStatement *stmt = calloc(1, sizeof(DavQLStatement)); |