| ... | ... | @@ -136,6 +136,7 @@ struct RuleTuple { |
| 136 | 136 | Buf name; |
| 137 | 137 | ZigList<RuleNode *> children; |
| 138 | 138 | Buf body; |
| 139 | Buf union_field_name; |
| 139 | 140 | }; |
| 140 | 141 | |
| 141 | 142 | struct RuleMany { |
| ... | ... | @@ -161,6 +162,9 @@ struct RuleList { |
| 161 | 162 | |
| 162 | 163 | struct RuleSubRule { |
| 163 | 164 | RuleNode *child; |
| 165 | |
| 166 | // for lexer use only |
| 167 | Buf name; |
| 164 | 168 | }; |
| 165 | 169 | |
| 166 | 170 | enum RuleNodeType { |
| ... | ... | @@ -175,6 +179,8 @@ enum RuleNodeType { |
| 175 | 179 | |
| 176 | 180 | struct RuleNode { |
| 177 | 181 | RuleNodeType type; |
| 182 | int lex_line; |
| 183 | int lex_column; |
| 178 | 184 | union { |
| 179 | 185 | RuleTuple tuple; |
| 180 | 186 | RuleMany many; |
| ... | ... | @@ -205,6 +211,7 @@ struct CodeGenCapture { |
| 205 | 211 | Buf *body; |
| 206 | 212 | bool is_root; |
| 207 | 213 | Buf *field_names; |
| 214 | Buf *union_field_name; |
| 208 | 215 | }; |
| 209 | 216 | |
| 210 | 217 | struct CodeGen { |
| ... | ... | @@ -225,6 +232,8 @@ struct ParserState { |
| 225 | 232 | enum LexState { |
| 226 | 233 | LexStateStart, |
| 227 | 234 | LexStateRuleName, |
| 235 | LexStateRuleFieldNameStart, |
| 236 | LexStateRuleFieldName, |
| 228 | 237 | LexStateWaitForColon, |
| 229 | 238 | LexStateTupleRule, |
| 230 | 239 | LexStateFnName, |
| ... | ... | @@ -232,6 +241,7 @@ enum LexState { |
| 232 | 241 | LexStateToken, |
| 233 | 242 | LexStateBody, |
| 234 | 243 | LexStateEndOrOr, |
| 244 | LexStateSubTupleName, |
| 235 | 245 | }; |
| 236 | 246 | |
| 237 | 247 | struct LexStack { |
| ... | ... | @@ -258,6 +268,8 @@ struct Gen { |
| 258 | 268 | int lex_token_name_begin; |
| 259 | 269 | int lex_body_begin; |
| 260 | 270 | int lex_body_end; |
| 271 | int lex_sub_tuple_begin; |
| 272 | int lex_field_name_begin; |
| 261 | 273 | }; |
| 262 | 274 | |
| 263 | 275 | static ParserState *create_state(Gen *g) { |
| ... | ... | @@ -303,12 +315,13 @@ static void state_add_push_node(ParserState *state) { |
| 303 | 315 | state_add_code(state, code); |
| 304 | 316 | } |
| 305 | 317 | |
| 306 | | static CodeGen *codegen_create_capture(Buf *body, bool is_root, int field_name_count) { |
| 318 | static CodeGen *codegen_create_capture(Buf *body, bool is_root, int field_name_count, Buf *union_field_name) { |
| 307 | 319 | CodeGen *code = allocate<CodeGen>(1); |
| 308 | 320 | code->type = CodeGenTypeCapture; |
| 309 | 321 | code->capture.body = body; |
| 310 | 322 | code->capture.is_root = is_root; |
| 311 | 323 | code->capture.field_names = allocate<Buf>(field_name_count); |
| 324 | code->capture.union_field_name = union_field_name; |
| 312 | 325 | return code; |
| 313 | 326 | } |
| 314 | 327 | |
| ... | ... | @@ -325,6 +338,7 @@ static void state_add_eat_token(ParserState *state) { |
| 325 | 338 | } |
| 326 | 339 | |
| 327 | 340 | static void gen(Gen *g, RuleNode *node, Buf *out_field_name) { |
| 341 | assert(node); |
| 328 | 342 | switch (node->type) { |
| 329 | 343 | case RuleNodeTypeToken: |
| 330 | 344 | { |
| ... | ... | @@ -346,13 +360,14 @@ static void gen(Gen *g, RuleNode *node, Buf *out_field_name) { |
| 346 | 360 | break; |
| 347 | 361 | case RuleNodeTypeTuple: |
| 348 | 362 | { |
| 349 | | buf_init_from_str(out_field_name, "node"); |
| 363 | buf_init_from_buf(out_field_name, &node->tuple.union_field_name); |
| 350 | 364 | |
| 351 | 365 | state_add_push_node(g->cur_state); |
| 352 | 366 | |
| 353 | 367 | bool is_root = (node == g->root); |
| 354 | 368 | int field_name_count = node->tuple.children.length; |
| 355 | | CodeGen *code = codegen_create_capture(&node->tuple.body, is_root, field_name_count); |
| 369 | CodeGen *code = codegen_create_capture(&node->tuple.body, is_root, field_name_count, |
| 370 | &node->tuple.union_field_name); |
| 356 | 371 | |
| 357 | 372 | for (int i = 0; i < node->tuple.children.length; i += 1) { |
| 358 | 373 | RuleNode *child = node->tuple.children.at(i); |
| ... | ... | @@ -411,7 +426,7 @@ static void lex_error(Gen *g, const char *format, ...) { |
| 411 | 426 | |
| 412 | 427 | va_list ap; |
| 413 | 428 | va_start(ap, format); |
| 414 | | fprintf(stderr, "Error: Line %d, column %d: ", line, column); |
| 429 | fprintf(stderr, "Grammar Error: Line %d, column %d: ", line, column); |
| 415 | 430 | vfprintf(stderr, format, ap); |
| 416 | 431 | fprintf(stderr, "\n"); |
| 417 | 432 | va_end(ap); |
| ... | ... | @@ -428,10 +443,16 @@ static void lex_pop_stack(Gen *g) { |
| 428 | 443 | g->lex_stack.pop(); |
| 429 | 444 | } |
| 430 | 445 | |
| 446 | static RuleNode *create_rule_node(Gen *g) { |
| 447 | RuleNode *node = allocate<RuleNode>(1); |
| 448 | node->lex_line = g->lex_line; |
| 449 | node->lex_column = g->lex_column; |
| 450 | return node; |
| 451 | } |
| 431 | 452 | |
| 432 | 453 | static void begin_rule(Gen *g) { |
| 433 | 454 | assert(!g->lex_cur_rule); |
| 434 | | g->lex_cur_rule = allocate<RuleNode>(1); |
| 455 | g->lex_cur_rule = create_rule_node(g); |
| 435 | 456 | g->lex_cur_rule->type = RuleNodeTypeTuple; |
| 436 | 457 | g->lex_cur_rule_begin = g->lex_pos; |
| 437 | 458 | |
| ... | ... | @@ -452,6 +473,18 @@ static void end_rule_name(Gen *g) { |
| 452 | 473 | buf_init_from_mem(&g->lex_cur_rule->tuple.name, ptr, len); |
| 453 | 474 | } |
| 454 | 475 | |
| 476 | static void begin_rule_field_name(Gen *g) { |
| 477 | assert(g->lex_cur_rule); |
| 478 | g->lex_field_name_begin = g->lex_pos; |
| 479 | } |
| 480 | |
| 481 | static void end_rule_field_name(Gen *g) { |
| 482 | assert(g->lex_cur_rule); |
| 483 | char *ptr = &buf_ptr(g->in_buf)[g->lex_field_name_begin]; |
| 484 | int len = g->lex_pos - g->lex_field_name_begin; |
| 485 | buf_init_from_mem(&g->lex_cur_rule->tuple.union_field_name, ptr, len); |
| 486 | } |
| 487 | |
| 455 | 488 | static void begin_fn_name(Gen *g) { |
| 456 | 489 | g->lex_fn_name_begin = g->lex_pos; |
| 457 | 490 | lex_push_stack(g); |
| ... | ... | @@ -478,15 +511,13 @@ static void end_token_name(Gen *g) { |
| 478 | 511 | buf_init_from_mem(&token_name, ptr, len); |
| 479 | 512 | |
| 480 | 513 | Token *token = find_or_create_token(g, &token_name); |
| 481 | | RuleNode *node = allocate<RuleNode>(1); |
| 514 | RuleNode *node = create_rule_node(g); |
| 482 | 515 | node->type = RuleNodeTypeToken; |
| 483 | 516 | node->token.token = token; |
| 484 | 517 | |
| 485 | 518 | assert(g->lex_cur_rule->type == RuleNodeTypeTuple); |
| 486 | 519 | g->lex_cur_rule->tuple.children.append(node); |
| 487 | 520 | |
| 488 | | g->biggest_tuple_len = max(g->biggest_tuple_len, g->lex_cur_rule->tuple.children.length); |
| 489 | | |
| 490 | 521 | |
| 491 | 522 | lex_pop_stack(g); |
| 492 | 523 | } |
| ... | ... | @@ -504,6 +535,36 @@ static void end_tuple_body(Gen *g) { |
| 504 | 535 | buf_init_from_mem(&g->lex_cur_rule->tuple.body, ptr, len); |
| 505 | 536 | } |
| 506 | 537 | |
| 538 | static void begin_sub_tuple(Gen *g) { |
| 539 | g->lex_sub_tuple_begin = g->lex_pos; |
| 540 | lex_push_stack(g); |
| 541 | } |
| 542 | |
| 543 | static void end_sub_tuple(Gen *g) { |
| 544 | assert(g->lex_cur_rule->type == RuleNodeTypeTuple); |
| 545 | char *ptr = &buf_ptr(g->in_buf)[g->lex_sub_tuple_begin]; |
| 546 | int len = g->lex_pos - g->lex_sub_tuple_begin; |
| 547 | |
| 548 | RuleNode *node = create_rule_node(g); |
| 549 | node->type = RuleNodeTypeSubRule; |
| 550 | buf_init_from_mem(&node->sub_rule.name, ptr, len); |
| 551 | |
| 552 | g->lex_cur_rule->tuple.children.append(node); |
| 553 | |
| 554 | lex_pop_stack(g); |
| 555 | } |
| 556 | |
| 557 | static RuleNode *find_rule_node(Gen *g, Buf *name) { |
| 558 | for (int i = 0; i < g->rules.length; i += 1) { |
| 559 | RuleNode *node = g->rules.at(i); |
| 560 | assert(node->type == RuleNodeTypeTuple); |
| 561 | if (buf_eql_buf(&node->tuple.name, name)) { |
| 562 | return node; |
| 563 | } |
| 564 | } |
| 565 | return nullptr; |
| 566 | } |
| 567 | |
| 507 | 568 | static void initialize_rules(Gen *g) { |
| 508 | 569 | g->lex_state = LexStateStart; |
| 509 | 570 | for (g->lex_pos = 0; g->lex_pos < buf_len(g->in_buf); g->lex_pos += 1) { |
| ... | ... | @@ -524,18 +585,36 @@ static void initialize_rules(Gen *g) { |
| 524 | 585 | break; |
| 525 | 586 | case LexStateRuleName: |
| 526 | 587 | switch (c) { |
| 527 | | case WHITESPACE: |
| 588 | case '<': |
| 528 | 589 | end_rule_name(g); |
| 529 | | g->lex_state = LexStateWaitForColon; |
| 590 | g->lex_state = LexStateRuleFieldNameStart; |
| 530 | 591 | break; |
| 531 | | case ':': |
| 532 | | end_rule_name(g); |
| 533 | | g->lex_state = LexStateTupleRule; |
| 592 | case SYMBOL_CHAR: |
| 593 | // ok |
| 534 | 594 | break; |
| 595 | default: |
| 596 | lex_error(g, "expected '<', not '%c'", c); |
| 597 | } |
| 598 | break; |
| 599 | case LexStateRuleFieldNameStart: |
| 600 | switch (c) { |
| 535 | 601 | case SYMBOL_CHAR: |
| 602 | begin_rule_field_name(g); |
| 603 | g->lex_state = LexStateRuleFieldName; |
| 536 | 604 | break; |
| 537 | 605 | default: |
| 538 | | lex_error(g, "invalid char: '%c'", c); |
| 606 | lex_error(g, "expected field name, not '%c'", c); |
| 607 | } |
| 608 | break; |
| 609 | case LexStateRuleFieldName: |
| 610 | switch (c) { |
| 611 | case SYMBOL_CHAR: |
| 612 | // ok |
| 613 | break; |
| 614 | case '>': |
| 615 | end_rule_field_name(g); |
| 616 | g->lex_state = LexStateWaitForColon; |
| 617 | break; |
| 539 | 618 | } |
| 540 | 619 | break; |
| 541 | 620 | case LexStateWaitForColon: |
| ... | ... | @@ -559,12 +638,16 @@ static void initialize_rules(Gen *g) { |
| 559 | 638 | begin_fn_name(g); |
| 560 | 639 | g->lex_state = LexStateFnName; |
| 561 | 640 | break; |
| 641 | case UPPER_ALPHA: |
| 642 | begin_sub_tuple(g); |
| 643 | g->lex_state = LexStateSubTupleName; |
| 644 | break; |
| 562 | 645 | case '{': |
| 563 | 646 | begin_tuple_body(g); |
| 564 | 647 | g->lex_state = LexStateBody; |
| 565 | 648 | break; |
| 566 | 649 | default: |
| 567 | | lex_error(g, "invalid char: '%c'", c); |
| 650 | lex_error(g, "expected rule, not '%c'", c); |
| 568 | 651 | } |
| 569 | 652 | break; |
| 570 | 653 | case LexStateFnName: |
| ... | ... | @@ -589,7 +672,7 @@ static void initialize_rules(Gen *g) { |
| 589 | 672 | g->lex_state = LexStateToken; |
| 590 | 673 | break; |
| 591 | 674 | default: |
| 592 | | lex_error(g, "invalid char '%c'", c); |
| 675 | lex_error(g, "expected token name, not '%c'", c); |
| 593 | 676 | } |
| 594 | 677 | break; |
| 595 | 678 | case LexStateToken: |
| ... | ... | @@ -601,7 +684,7 @@ static void initialize_rules(Gen *g) { |
| 601 | 684 | end_token_name(g); |
| 602 | 685 | break; |
| 603 | 686 | default: |
| 604 | | lex_error(g, "invalid char '%c'", c); |
| 687 | lex_error(g, "expected token name or ')', not '%c'", c); |
| 605 | 688 | } |
| 606 | 689 | break; |
| 607 | 690 | case LexStateBody: |
| ... | ... | @@ -627,6 +710,20 @@ static void initialize_rules(Gen *g) { |
| 627 | 710 | default: |
| 628 | 711 | lex_error(g, "expected ';' or '|'"); |
| 629 | 712 | } |
| 713 | break; |
| 714 | case LexStateSubTupleName: |
| 715 | switch (c) { |
| 716 | case ALPHA: |
| 717 | // ignore |
| 718 | break; |
| 719 | case WHITESPACE: |
| 720 | end_sub_tuple(g); |
| 721 | assert(g->lex_state == LexStateTupleRule); |
| 722 | break; |
| 723 | default: |
| 724 | lex_error(g, "expected rule name, not '%c'", c); |
| 725 | } |
| 726 | break; |
| 630 | 727 | } |
| 631 | 728 | if (c == '\n') { |
| 632 | 729 | g->lex_line += 1; |
| ... | ... | @@ -647,9 +744,40 @@ static void initialize_rules(Gen *g) { |
| 647 | 744 | case LexStateTokenStart: |
| 648 | 745 | case LexStateToken: |
| 649 | 746 | case LexStateBody: |
| 747 | case LexStateSubTupleName: |
| 748 | case LexStateRuleFieldNameStart: |
| 749 | case LexStateRuleFieldName: |
| 650 | 750 | lex_error(g, "unexpected EOF"); |
| 651 | 751 | break; |
| 652 | 752 | } |
| 753 | |
| 754 | // Resolve child references into pointers |
| 755 | for (int tuple_i = 0; tuple_i < g->rules.length; tuple_i += 1) { |
| 756 | RuleNode *node = g->rules.at(tuple_i); |
| 757 | assert(node->type == RuleNodeTypeTuple); |
| 758 | |
| 759 | for (int child_i = 0; child_i < node->tuple.children.length; child_i += 1) { |
| 760 | RuleNode *child = node->tuple.children.at(child_i); |
| 761 | if (child->type == RuleNodeTypeSubRule) { |
| 762 | int line = child->lex_line + 1; |
| 763 | int column = child->lex_column + 1; |
| 764 | RuleNode *referenced_node = find_rule_node(g, &child->sub_rule.name); |
| 765 | if (!referenced_node) { |
| 766 | fprintf(stderr, "Grammar Error: Line %d, column %d: Rule not defined: '%s'\n", |
| 767 | line, column, buf_ptr(&child->sub_rule.name)); |
| 768 | } |
| 769 | child->sub_rule.child = referenced_node; |
| 770 | } |
| 771 | } |
| 772 | } |
| 773 | |
| 774 | |
| 775 | // calculate the biggest tuple len |
| 776 | for (int i = 0; i < g->rules.length; i += 1) { |
| 777 | RuleNode *node = g->rules.at(i); |
| 778 | assert(node->type == RuleNodeTypeTuple); |
| 779 | g->biggest_tuple_len = max(g->biggest_tuple_len, node->tuple.children.length); |
| 780 | } |
| 653 | 781 | } |
| 654 | 782 | |
| 655 | 783 | enum TemplateState { |
| ... | ... | @@ -828,6 +956,8 @@ int main(int argc, char **argv) { |
| 828 | 956 | fprintf(out_f, " state = transition[%d][token->id];\n", state->index); |
| 829 | 957 | break; |
| 830 | 958 | case CodeGenTypeError: |
| 959 | fprintf(out_f, " token_index -= 1;\n"); |
| 960 | fprintf(out_f, " token = &tokens->at(token_index);\n"); |
| 831 | 961 | fprintf(out_f, " ast_error(token, \"%s\");\n", buf_ptr(code->error.msg)); |
| 832 | 962 | break; |
| 833 | 963 | case CodeGenTypeSave: |
| ... | ... | @@ -843,7 +973,12 @@ int main(int argc, char **argv) { |
| 843 | 973 | fprintf(out_f, "%s\n", buf_ptr(code_text)); |
| 844 | 974 | fprintf(out_f, " return root;\n"); |
| 845 | 975 | } else { |
| 846 | | zig_panic("TODO capture non-root"); |
| 976 | fprintf(out_f, " ParserGenNode *parent_node = stack.at(stack.length - 2);\n"); |
| 977 | Buf *dest = buf_sprintf("parent_node->data[parent_node->next_index++].%s", |
| 978 | buf_ptr(code->capture.union_field_name)); |
| 979 | Buf *code_text = fill_template(code->capture.body, buf_ptr(dest), |
| 980 | code->capture.field_names); |
| 981 | fprintf(out_f, "%s\n", buf_ptr(code_text)); |
| 847 | 982 | } |
| 848 | 983 | break; |
| 849 | 984 | case CodeGenTypePopNode: |