1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2010-03-22 Bernard first version 9 * 2013-10-09 Bernard fix the command line too long issue. 10 */ 11 #include <finsh.h> 12 13 #include "finsh_token.h" 14 #include "finsh_node.h" 15 #include "finsh_error.h" 16 #include "finsh_parser.h" 17 #include "finsh_var.h" 18 19 /* 20 * the structure of abstract syntax tree: 21 * root____________ 22 * | \ 23 * child__ sibling__ 24 * | \ | \ 25 * child sibling child sibling 26 * ... 27 */ 28 static enum finsh_type proc_type(struct finsh_parser* self); 29 static int proc_identifier(struct finsh_parser* self, char* id); 30 static struct finsh_node* proc_variable_decl(struct finsh_parser* self); 31 static struct finsh_node* proc_expr(struct finsh_parser* self); 32 static struct finsh_node* proc_assign_expr(struct finsh_parser* self); 33 static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self); 34 static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self); 35 static struct finsh_node* proc_and_expr(struct finsh_parser* self); 36 static struct finsh_node* proc_shift_expr(struct finsh_parser* self); 37 static struct finsh_node* proc_additive_expr(struct finsh_parser* self); 38 static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self); 39 static struct finsh_node* proc_cast_expr(struct finsh_parser* self); 40 static struct finsh_node* proc_unary_expr(struct finsh_parser* self); 41 static struct finsh_node* proc_postfix_expr(struct finsh_parser* self); 42 static struct finsh_node* proc_primary_expr(struct finsh_parser* self); 43 static struct finsh_node* proc_param_list(struct finsh_parser* self); 44 static struct finsh_node* proc_expr_statement(struct finsh_parser* self); 45 static struct finsh_node* make_sys_node(uint8_t type, struct finsh_node* node1, 46 struct finsh_node* node2); 47 48 /* check token */ 49 #define check_token(token, lex, type) if ( (token) != (type) ) \ 50 { \ 51 finsh_error_set(FINSH_ERROR_INVALID_TOKEN); \ 52 finsh_token_replay(lex); \ 53 } 54 55 /* is the token a data type? */ 56 #define is_base_type(token) ((token) == finsh_token_type_void \ 57 || (token) == finsh_token_type_char \ 58 || (token) == finsh_token_type_short \ 59 || (token) == finsh_token_type_int \ 60 || (token) == finsh_token_type_long) 61 62 /* get the next token */ 63 #define next_token(token, lex) (token) = finsh_token_token(lex) 64 65 /* match a specified token */ 66 #define match_token(token, lex, type) next_token(token, lex); \ 67 check_token(token, lex, type) 68 69 /* 70 process for function and variable declaration. 71 decl_variable -> type declaration_list ';' 72 declarator_list -> declarator_list ',' declarator 73 | declarator 74 declarator -> identifier 75 | identifier ASSIGN expr_assign 76 */ 77 static struct finsh_node* proc_variable_decl(struct finsh_parser* self) 78 { 79 enum finsh_token_type token; 80 enum finsh_type type; 81 char id[FINSH_NAME_MAX + 1]; 82 83 struct finsh_node *node; 84 struct finsh_node *end; 85 struct finsh_node *assign; 86 87 node = NULL; 88 end = NULL; 89 90 /* get type */ 91 type = proc_type(self); 92 93 /*process id.*/ 94 if (proc_identifier(self, id) == 0) 95 { 96 /* if add variable failed */ 97 if (finsh_var_insert(id, type) < 0) 98 { 99 finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); 100 } 101 } 102 103 next_token(token, &(self->token)); 104 switch ( token ) 105 { 106 case finsh_token_type_comma:/*',', it's a variable_list declaration.*/ 107 if (proc_identifier(self, id) == 0) 108 { 109 /* if add variable failed */ 110 if (finsh_var_insert(id, type) < 0) 111 { 112 finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); 113 } 114 } 115 116 next_token(token, &(self->token)); 117 if ( token == finsh_token_type_assign ) 118 { 119 /* get the right side of assign expression */ 120 assign = proc_assign_expr(self); 121 122 if (assign != NULL) 123 { 124 struct finsh_node* idnode; 125 126 idnode = finsh_node_new_id(id); 127 end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); 128 node = end; 129 130 next_token(token, &(self->token)); 131 } 132 } 133 134 while ( token == finsh_token_type_comma ) 135 { 136 if (proc_identifier(self, id) == 0) 137 { 138 /* if add variable failed */ 139 if (finsh_var_insert(id, type) < 0) 140 { 141 finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); 142 } 143 } 144 145 next_token(token, &(self->token)); 146 if ( token == finsh_token_type_assign ) 147 { 148 /* get the right side of assign expression */ 149 assign = proc_assign_expr(self); 150 151 if (assign != NULL) 152 { 153 struct finsh_node* idnode; 154 155 idnode = finsh_node_new_id(id); 156 157 /* make assign expression node */ 158 if (node != NULL) 159 { 160 finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); 161 end = finsh_node_sibling(end); 162 } 163 else 164 { 165 end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); 166 node = end; 167 } 168 169 next_token(token, &(self->token)); 170 } 171 } 172 } 173 174 check_token(token, &(self->token), finsh_token_type_semicolon); 175 return node; 176 177 case finsh_token_type_assign:/*'=', it's a variable with assign declaration.*/ 178 { 179 struct finsh_node *idnode; 180 181 assign = proc_assign_expr(self); 182 if (assign != NULL) 183 { 184 idnode = finsh_node_new_id(id); 185 186 /* make assign expression node */ 187 end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); 188 node = end; 189 190 next_token(token, &(self->token)); 191 } 192 193 while ( token == finsh_token_type_comma ) 194 { 195 if (proc_identifier(self, id) == 0) 196 { 197 /* if add variable failed */ 198 if (finsh_var_insert(id, type) < 0) 199 { 200 finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); 201 } 202 } 203 204 next_token(token, &(self->token)); 205 if (token == finsh_token_type_assign) 206 { 207 /* get the right side of assign expression */ 208 assign = proc_assign_expr(self); 209 210 if (assign != NULL) 211 { 212 idnode = finsh_node_new_id(id); 213 214 /* make assign expression node */ 215 if (node != NULL) 216 { 217 finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); 218 end = finsh_node_sibling(end); 219 } 220 else 221 { 222 end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); 223 node = end; 224 } 225 226 next_token(token, &(self->token)); 227 } 228 } 229 } 230 231 check_token(token, &(self->token), finsh_token_type_semicolon); 232 return node; 233 } 234 235 case finsh_token_type_semicolon:/*';', it's a variable declaration.*/ 236 return node; 237 238 default: 239 finsh_error_set(FINSH_ERROR_EXPECT_TYPE); 240 241 return NULL; 242 } 243 } 244 245 /* 246 type -> type_prefix type_basic | type_basic 247 type_prefix -> UNSIGNED 248 type_basic -> VOID 249 | CHAR 250 | SHORT 251 | INT 252 | STRING 253 */ 254 static enum finsh_type proc_type(struct finsh_parser* self) 255 { 256 enum finsh_type type; 257 enum finsh_token_type token; 258 259 /* set init type */ 260 type = finsh_type_unknown; 261 262 next_token(token, &(self->token)); 263 if ( is_base_type(token) ) /* base_type */ 264 { 265 switch (token) 266 { 267 case finsh_token_type_void: 268 type = finsh_type_void; 269 break; 270 271 case finsh_token_type_char: 272 type = finsh_type_char; 273 break; 274 275 case finsh_token_type_short: 276 type = finsh_type_short; 277 break; 278 279 case finsh_token_type_int: 280 type = finsh_type_int; 281 break; 282 283 case finsh_token_type_long: 284 type = finsh_type_long; 285 break; 286 287 default: 288 goto __return; 289 } 290 } 291 else if ( token == finsh_token_type_unsigned ) /* unsigned base_type */ 292 { 293 next_token(token, &(self->token)); 294 if ( is_base_type(token) ) 295 { 296 switch (token) 297 { 298 case finsh_token_type_char: 299 type = finsh_type_uchar; 300 break; 301 302 case finsh_token_type_short: 303 type = finsh_type_ushort; 304 break; 305 306 case finsh_token_type_int: 307 type = finsh_type_uint; 308 break; 309 310 case finsh_token_type_long: 311 type = finsh_type_ulong; 312 break; 313 314 default: 315 goto __return; 316 } 317 } 318 else 319 { 320 finsh_token_replay(&(self->token)); 321 finsh_error_set(FINSH_ERROR_EXPECT_TYPE); 322 } 323 } 324 else 325 { 326 goto __return; 327 } 328 329 /* parse for pointer */ 330 next_token(token, &(self->token)); 331 if (token == finsh_token_type_mul) 332 { 333 switch (type) 334 { 335 case finsh_type_void: 336 type = finsh_type_voidp; 337 break; 338 339 case finsh_type_char: 340 case finsh_type_uchar: 341 type = finsh_type_charp; 342 break; 343 344 case finsh_type_short: 345 case finsh_type_ushort: 346 type = finsh_type_shortp; 347 break; 348 349 case finsh_type_int: 350 case finsh_type_uint: 351 type = finsh_type_intp; 352 break; 353 354 case finsh_type_long: 355 case finsh_type_ulong: 356 type = finsh_type_longp; 357 break; 358 359 default: 360 type = finsh_type_voidp; 361 break; 362 } 363 } 364 else finsh_token_replay(&(self->token)); 365 366 return type; 367 368 __return: 369 finsh_token_replay(&(self->token)); 370 finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE); 371 372 return type; 373 } 374 375 /* 376 identifier -> IDENTIFIER 377 */ 378 static int proc_identifier(struct finsh_parser* self, char* id) 379 { 380 enum finsh_token_type token; 381 382 match_token(token, &(self->token), finsh_token_type_identifier); 383 384 strncpy(id, (char*)self->token.string, FINSH_NAME_MAX); 385 386 return 0; 387 } 388 389 /* 390 statement_expr -> ';' 391 | expr ';' 392 */ 393 static struct finsh_node* proc_expr_statement(struct finsh_parser* self) 394 { 395 enum finsh_token_type token; 396 struct finsh_node* expr; 397 398 expr = NULL; 399 next_token(token, &(self->token)); 400 if ( token != finsh_token_type_semicolon ) 401 { 402 finsh_token_replay(&(self->token)); 403 expr = proc_expr(self); 404 405 match_token(token, &(self->token), finsh_token_type_semicolon); 406 } 407 408 return expr; 409 } 410 411 /* 412 expr -> expr_assign 413 */ 414 static struct finsh_node* proc_expr(struct finsh_parser* self) 415 { 416 return proc_assign_expr(self); 417 } 418 419 /* 420 expr_assign -> expr_inclusive_or 421 | expr_unary ASSIGN expr_assign 422 */ 423 static struct finsh_node* proc_assign_expr(struct finsh_parser* self) 424 { 425 enum finsh_token_type token; 426 struct finsh_node* or; 427 struct finsh_node* assign; 428 429 or = proc_inclusive_or_expr(self); 430 431 next_token(token, &(self->token)); 432 433 if (token == finsh_token_type_assign) 434 { 435 assign = proc_assign_expr(self); 436 437 return make_sys_node(FINSH_NODE_SYS_ASSIGN, or, assign); 438 } 439 else finsh_token_replay(&(self->token)); 440 441 return or; 442 } 443 444 /* 445 expr_inclusive_or -> expr_exclusive_or 446 | expr_inclusive_or '|' expr_exclusive_or 447 */ 448 static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self) 449 { 450 enum finsh_token_type token; 451 struct finsh_node* xor; 452 struct finsh_node* xor_new; 453 454 xor = proc_exclusive_or_expr(self); 455 456 next_token(token, &(self->token)); 457 while ( token == finsh_token_type_or ) 458 { 459 xor_new = proc_exclusive_or_expr(self); 460 461 if (xor_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 462 else xor = make_sys_node(FINSH_NODE_SYS_OR, xor, xor_new); 463 464 next_token(token, &(self->token)); 465 } 466 467 finsh_token_replay(&(self->token)); 468 return xor; 469 } 470 471 /* 472 expr_exclusive_or -> expr_and 473 | expr_exclusive '^' expr_and 474 */ 475 static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self) 476 { 477 enum finsh_token_type token; 478 struct finsh_node* and; 479 struct finsh_node* and_new; 480 481 and = proc_and_expr(self); 482 next_token(token, &(self->token)); 483 while ( token == finsh_token_type_xor ) 484 { 485 and_new = proc_and_expr(self); 486 if (and_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 487 else and = make_sys_node(FINSH_NODE_SYS_XOR, and, and_new); 488 489 next_token(token, &(self->token)); 490 } 491 492 finsh_token_replay(&(self->token)); 493 return and; 494 } 495 496 /* 497 expr_and -> expr_shift 498 | expr_and '&' expr_shift 499 */ 500 static struct finsh_node* proc_and_expr(struct finsh_parser* self) 501 { 502 enum finsh_token_type token; 503 struct finsh_node* shift; 504 struct finsh_node* shift_new; 505 506 shift = proc_shift_expr(self); 507 508 next_token(token, &(self->token)); 509 while ( token == finsh_token_type_and ) 510 { 511 shift_new = proc_shift_expr(self); 512 513 if (shift_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 514 else shift = make_sys_node(FINSH_NODE_SYS_AND, shift, shift_new); 515 516 next_token(token, &(self->token)); 517 } 518 519 finsh_token_replay(&(self->token)); 520 return shift; 521 } 522 523 /* 524 expr_shift -> expr_additive 525 | expr_shift '<<' expr_additive 526 | expr_shift '>>' expr_additive 527 */ 528 static struct finsh_node* proc_shift_expr(struct finsh_parser* self) 529 { 530 enum finsh_token_type token; 531 struct finsh_node* add; 532 struct finsh_node* add_new; 533 534 add = proc_additive_expr(self); 535 536 next_token(token, &(self->token)); 537 while ( token == finsh_token_type_shl || token == finsh_token_type_shr) 538 { 539 add_new = proc_additive_expr(self); 540 if (add_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 541 else 542 { 543 switch (token) 544 { 545 case finsh_token_type_shl: 546 add = make_sys_node(FINSH_NODE_SYS_SHL, add, add_new); 547 break; 548 case finsh_token_type_shr: 549 add = make_sys_node(FINSH_NODE_SYS_SHR, add, add_new); 550 break; 551 default: 552 finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 553 break; 554 } 555 } 556 next_token(token, &(self->token)); 557 } 558 559 finsh_token_replay(&(self->token)); 560 return add; 561 } 562 563 /* 564 expr_additive -> expr_multiplicative 565 | expr_additive SUB expr_multiplicative 566 | expr_additive ADD expr_multiplicative 567 */ 568 static struct finsh_node* proc_additive_expr(struct finsh_parser* self) 569 { 570 enum finsh_token_type token; 571 struct finsh_node* mul; 572 struct finsh_node* mul_new; 573 574 mul = proc_multiplicative_expr(self); 575 576 next_token(token, &(self->token)); 577 while ( token == finsh_token_type_sub || token == finsh_token_type_add ) 578 { 579 mul_new = proc_multiplicative_expr(self); 580 if (mul_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 581 else 582 { 583 switch (token) 584 { 585 case finsh_token_type_sub: 586 mul = make_sys_node(FINSH_NODE_SYS_SUB, mul, mul_new); 587 break; 588 case finsh_token_type_add: 589 mul = make_sys_node(FINSH_NODE_SYS_ADD, mul, mul_new); 590 break; 591 default: 592 finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 593 break; 594 } 595 } 596 next_token(token, &(self->token)); 597 } 598 599 finsh_token_replay(&(self->token)); 600 return mul; 601 } 602 603 /* 604 expr_multiplicative -> expr_cast 605 | expr_multiplicative '*' expr_cast 606 | expr_multiplicative '/' expr_cast 607 | expr_multiplicative '%' expr_cast 608 */ 609 static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self) 610 { 611 enum finsh_token_type token; 612 struct finsh_node* cast; 613 struct finsh_node* cast_new; 614 615 cast = proc_cast_expr(self); 616 next_token(token, &(self->token)); 617 while (token == finsh_token_type_mul || 618 token == finsh_token_type_div || 619 token == finsh_token_type_mod ) 620 { 621 cast_new = proc_cast_expr(self); 622 if (cast_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 623 else 624 { 625 switch (token) 626 { 627 case finsh_token_type_mul: 628 cast = make_sys_node(FINSH_NODE_SYS_MUL, cast, cast_new); 629 break; 630 631 case finsh_token_type_div: 632 cast = make_sys_node(FINSH_NODE_SYS_DIV, cast, cast_new); 633 break; 634 635 case finsh_token_type_mod: 636 cast = make_sys_node(FINSH_NODE_SYS_MOD, cast, cast_new); 637 break; 638 639 default: 640 finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 641 break; 642 } 643 } 644 next_token(token, &(self->token)); 645 } 646 647 finsh_token_replay(&(self->token)); 648 return cast; 649 } 650 651 /* 652 20060313, add recast parse 653 expr_cast -> expr_unary 654 | '(' type ')' expr_cast 655 */ 656 static struct finsh_node* proc_cast_expr(struct finsh_parser* self) 657 { 658 enum finsh_token_type token; 659 enum finsh_type type; 660 struct finsh_node* cast; 661 662 next_token(token, &(self->token)); 663 if (token == finsh_token_type_left_paren) 664 { 665 type = proc_type(self); 666 match_token(token, &(self->token), finsh_token_type_right_paren); 667 668 cast = proc_cast_expr(self); 669 if (cast != NULL) 670 { 671 cast->data_type = type; 672 return cast; 673 } 674 } 675 676 finsh_token_replay(&(self->token)); 677 return proc_unary_expr(self); 678 } 679 680 /* 681 20050921, add '*' and '&' 682 expr_unary -> expr_postfix 683 | ADD expr_cast 684 | INC expr_cast 685 | SUB expr_cast 686 | DEC expr_cast 687 | '~' expr_cast 688 | '*' expr_cast 689 | '&' expr_cast 690 */ 691 static struct finsh_node* proc_unary_expr(struct finsh_parser* self) 692 { 693 enum finsh_token_type token; 694 struct finsh_node *cast; 695 696 next_token(token, &(self->token)); 697 switch (token) 698 { 699 case finsh_token_type_add: /* + */ 700 cast = proc_cast_expr(self); 701 return cast; 702 703 case finsh_token_type_inc: /* ++ */ 704 cast = proc_cast_expr(self); 705 return make_sys_node(FINSH_NODE_SYS_PREINC, cast, NULL); 706 707 case finsh_token_type_sub: /* - */ 708 cast = proc_cast_expr(self); 709 return make_sys_node(FINSH_NODE_SYS_SUB, finsh_node_new_long(0), cast); 710 711 case finsh_token_type_dec: /* -- */ 712 cast = proc_cast_expr(self); 713 return make_sys_node(FINSH_NODE_SYS_PREDEC, cast, NULL); 714 715 case finsh_token_type_bitwise: /* ~ */ 716 cast = proc_cast_expr(self); 717 return make_sys_node(FINSH_NODE_SYS_BITWISE, cast, NULL); 718 719 case finsh_token_type_mul: /* * */ 720 cast = proc_cast_expr(self); 721 return make_sys_node(FINSH_NODE_SYS_GETVALUE, cast, NULL); 722 723 case finsh_token_type_and: /* & */ 724 cast = proc_cast_expr(self); 725 return make_sys_node(FINSH_NODE_SYS_GETADDR, cast, NULL); 726 727 default: 728 finsh_token_replay(&(self->token)); 729 return proc_postfix_expr(self); 730 } 731 } 732 733 /* 734 expr_postfix -> expr_primary 735 | expr_postfix INC 736 | expr_postfix DEC 737 | expr_postfix '(' param_list ')' 738 */ 739 static struct finsh_node* proc_postfix_expr(struct finsh_parser* self) 740 { 741 enum finsh_token_type token; 742 struct finsh_node* postfix; 743 744 postfix = proc_primary_expr(self); 745 746 next_token(token, &(self->token)); 747 while ( token == finsh_token_type_inc || 748 token == finsh_token_type_dec || 749 token == finsh_token_type_left_paren ) 750 { 751 switch (token) 752 { 753 case finsh_token_type_inc :/* '++' */ 754 postfix = make_sys_node(FINSH_NODE_SYS_INC, postfix, NULL); 755 break; 756 757 case finsh_token_type_dec :/* '--' */ 758 postfix = make_sys_node(FINSH_NODE_SYS_DEC, postfix, NULL); 759 break; 760 761 case finsh_token_type_left_paren :/* '(' */ 762 { 763 struct finsh_node* param_list; 764 765 param_list = NULL; 766 next_token(token, &(self->token)); 767 if (token != finsh_token_type_right_paren) 768 { 769 finsh_token_replay(&(self->token)); 770 param_list = proc_param_list(self); 771 772 match_token(token, &(self->token), finsh_token_type_right_paren); 773 } 774 775 postfix = make_sys_node(FINSH_NODE_SYS_FUNC, postfix, param_list); 776 } 777 break; 778 779 default: 780 break; 781 } 782 783 next_token(token, &(self->token)); 784 } 785 786 finsh_token_replay(&(self->token)); 787 return postfix; 788 } 789 790 /* 791 expr_primary -> literal 792 | '(' expr ')' 793 | identifier 794 */ 795 static struct finsh_node* proc_primary_expr(struct finsh_parser* self) 796 { 797 enum finsh_token_type token; 798 struct finsh_node* expr; 799 800 next_token(token, &(self->token)); 801 switch ( token ) 802 { 803 case finsh_token_type_identifier: 804 { 805 char id[FINSH_NAME_MAX + 1]; 806 807 finsh_token_replay(&(self->token)); 808 proc_identifier(self, id); 809 return finsh_node_new_id(id); 810 } 811 812 case finsh_token_type_left_paren: 813 expr = proc_expr(self); 814 match_token(token, &(self->token), finsh_token_type_right_paren); 815 return expr; 816 817 case finsh_token_type_value_int: 818 return finsh_node_new_int(self->token.value.int_value); 819 820 case finsh_token_type_value_long: 821 return finsh_node_new_long(self->token.value.long_value); 822 823 case finsh_token_type_value_char: 824 return finsh_node_new_char(self->token.value.char_value); 825 826 case finsh_token_type_value_string: 827 return finsh_node_new_string((char*)self->token.string); 828 829 case finsh_token_type_value_null: 830 return finsh_node_new_ptr(NULL); 831 832 default: 833 finsh_error_set(FINSH_ERROR_INVALID_TOKEN); 834 break; 835 } 836 837 return NULL; 838 } 839 840 /* 841 param_list -> empty 842 | expr_assign 843 | param_list ',' expr_assign 844 */ 845 static struct finsh_node* proc_param_list(struct finsh_parser* self) 846 { 847 enum finsh_token_type token; 848 struct finsh_node *node, *assign; 849 850 assign = proc_assign_expr(self); 851 if (assign == NULL) return NULL; 852 node = assign; 853 854 next_token(token, &(self->token)); 855 while (token == finsh_token_type_comma ) 856 { 857 finsh_node_sibling(assign) = proc_assign_expr(self); 858 859 if (finsh_node_sibling(assign) != NULL) assign = finsh_node_sibling(assign); 860 else finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); 861 862 next_token(token, &(self->token)); 863 } 864 865 finsh_token_replay(&(self->token)); 866 867 return node; 868 } 869 870 /* 871 make a new node as following tree: 872 new_node 873 | 874 node1__ 875 \ 876 node2 877 */ 878 static struct finsh_node* make_sys_node(uint8_t type, struct finsh_node* node1, struct finsh_node* node2) 879 { 880 struct finsh_node* node; 881 882 node = finsh_node_allocate(type); 883 884 if ((node1 != NULL) && (node != NULL)) 885 { 886 finsh_node_child(node) = node1; 887 finsh_node_sibling(node1) = node2; 888 } 889 else finsh_error_set(FINSH_ERROR_NULL_NODE); 890 891 return node; 892 } 893 894 /* 895 start -> statement_expr | decl_variable 896 */ 897 void finsh_parser_run(struct finsh_parser* self, const uint8_t* string) 898 { 899 enum finsh_token_type token; 900 struct finsh_node *node; 901 902 node = NULL; 903 904 /* init parser */ 905 self->parser_string = (uint8_t*)string; 906 907 /* init token */ 908 finsh_token_init(&(self->token), self->parser_string); 909 910 /* get next token */ 911 next_token(token, &(self->token)); 912 while (token != finsh_token_type_eof && token != finsh_token_type_bad) 913 { 914 switch (token) 915 { 916 case finsh_token_type_identifier: 917 /* process expr_statement */ 918 finsh_token_replay(&(self->token)); 919 920 if (self->root != NULL) 921 { 922 finsh_node_sibling(node) = proc_expr_statement(self); 923 if (finsh_node_sibling(node) != NULL) 924 node = finsh_node_sibling(node); 925 } 926 else 927 { 928 node = proc_expr_statement(self); 929 self->root = node; 930 } 931 break; 932 933 default: 934 if (is_base_type(token) || token == finsh_token_type_unsigned) 935 { 936 /* variable decl */ 937 finsh_token_replay(&(self->token)); 938 939 if (self->root != NULL) 940 { 941 finsh_node_sibling(node) = proc_variable_decl(self); 942 if (finsh_node_sibling(node) != NULL) 943 node = finsh_node_sibling(node); 944 } 945 else 946 { 947 node = proc_variable_decl(self); 948 self->root = node; 949 } 950 } 951 else 952 { 953 /* process expr_statement */ 954 finsh_token_replay(&(self->token)); 955 956 if (self->root != NULL) 957 { 958 finsh_node_sibling(node) = proc_expr_statement(self); 959 if (finsh_node_sibling(node) != NULL) 960 node = finsh_node_sibling(node); 961 else next_token(token, &(self->token)); 962 } 963 else 964 { 965 node = proc_expr_statement(self); 966 self->root = node; 967 } 968 } 969 970 break; 971 } 972 973 /* no root found, break out */ 974 if (self->root == NULL) break; 975 976 /* get next token */ 977 next_token(token, &(self->token)); 978 } 979 } 980 981 int finsh_parser_init(struct finsh_parser* self) 982 { 983 memset(self, 0, sizeof(struct finsh_parser)); 984 985 return 0; 986 } 987