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 */
proc_variable_decl(struct finsh_parser * self)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 */
proc_type(struct finsh_parser * self)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 */
proc_identifier(struct finsh_parser * self,char * id)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 */
proc_expr_statement(struct finsh_parser * self)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 */
proc_expr(struct finsh_parser * self)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 */
proc_assign_expr(struct finsh_parser * self)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 */
proc_inclusive_or_expr(struct finsh_parser * self)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 */
proc_exclusive_or_expr(struct finsh_parser * self)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 */
proc_and_expr(struct finsh_parser * self)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 */
proc_shift_expr(struct finsh_parser * self)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 */
proc_additive_expr(struct finsh_parser * self)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 */
proc_multiplicative_expr(struct finsh_parser * self)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 */
proc_cast_expr(struct finsh_parser * self)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 */
proc_unary_expr(struct finsh_parser * self)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 */
proc_postfix_expr(struct finsh_parser * self)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 */
proc_primary_expr(struct finsh_parser * self)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 */
proc_param_list(struct finsh_parser * self)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 */
make_sys_node(uint8_t type,struct finsh_node * node1,struct finsh_node * node2)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 */
finsh_parser_run(struct finsh_parser * self,const uint8_t * string)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
finsh_parser_init(struct finsh_parser * self)981 int finsh_parser_init(struct finsh_parser* self)
982 {
983 memset(self, 0, sizeof(struct finsh_parser));
984
985 return 0;
986 }
987