xref: /nrf52832-nimble/rt-thread/components/finsh/finsh_parser.c (revision 104654410c56c573564690304ae786df310c91fc)
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