📄 finsh_parser.c.svn-base
字号:
#include <finsh.h>#include "finsh_token.h"#include "finsh_node.h"#include "finsh_error.h"#include "finsh_parser.h"#include "finsh_var.h"/* * the structure of abstract syntax tree: * root____________ * | \ * child__ sibling__ * | \ | \ * child sibling child sibling * ... */static enum finsh_type proc_type(struct finsh_parser* self);static int proc_identifier(struct finsh_parser* self, char* id);static struct finsh_node* proc_variable_decl(struct finsh_parser* self);static struct finsh_node* proc_expr(struct finsh_parser* self);static struct finsh_node* proc_assign_expr(struct finsh_parser* self);static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self);static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self);static struct finsh_node* proc_and_expr(struct finsh_parser* self);static struct finsh_node* proc_shift_expr(struct finsh_parser* self);static struct finsh_node* proc_additive_expr(struct finsh_parser* self);static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self);static struct finsh_node* proc_cast_expr(struct finsh_parser* self);static struct finsh_node* proc_unary_expr(struct finsh_parser* self);static struct finsh_node* proc_postfix_expr(struct finsh_parser* self);static struct finsh_node* proc_primary_expr(struct finsh_parser* self);static struct finsh_node* proc_param_list(struct finsh_parser* self);static struct finsh_node* proc_expr_statement(struct finsh_parser* self);static struct finsh_node* make_sys_node(u_char type, struct finsh_node* node1, struct finsh_node* node2);/* check token */#define check_token(token, lex, type) if ( (token) != (type) ) \ { \ finsh_error_set(FINSH_ERROR_INVALID_TOKEN); \ finsh_token_replay(lex); \ }/* is the token a data type? */#define is_base_type(token) ((token) == finsh_token_type_void \ || (token) == finsh_token_type_char \ || (token) == finsh_token_type_short \ || (token) == finsh_token_type_int \ || (token) == finsh_token_type_long)/* get the next token */#define next_token(token, lex) (token) = finsh_token_token(lex)/* match a specified token */#define match_token(token, lex, type) next_token(token, lex); \ check_token(token, lex, type)/**process for function and variable declaration.decl_variable -> type declaration_list ';'declarator_list -> declarator_list ',' declarator | declaratordeclarator -> identifier | identifier ASSIGN expr_assign*/static struct finsh_node* proc_variable_decl(struct finsh_parser* self){ enum finsh_token_type token; enum finsh_type type; char id[FINSH_NAME_MAX + 1]; struct finsh_node *node; struct finsh_node *end; struct finsh_node *assign; node = NULL; end = NULL; /* get type */ type = proc_type(self); /*process id.*/ if (proc_identifier(self, id) == 0) { /* if add variable failed */ if (finsh_var_insert(id, type) < 0) { finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); } } next_token(token, &(self->token)); switch ( token ) { case finsh_token_type_comma:/*',', it's a variable_list declaration.*/ if (proc_identifier(self, id) == 0) { /* if add variable failed */ if (finsh_var_insert(id, type) < 0) { finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); } } next_token(token, &(self->token)); if ( token == finsh_token_type_assign ) { /* get the right side of assign expression */ assign = proc_assign_expr(self); if (assign != NULL) { struct finsh_node* idnode; idnode = finsh_node_new_id(id); end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); node = end; next_token(token, &(self->token)); } } while ( token == finsh_token_type_comma ) { if (proc_identifier(self, id) == 0) { /* if add variable failed */ if (finsh_var_insert(id, type) < 0) { finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); } } next_token(token, &(self->token)); if ( token == finsh_token_type_assign ) { /* get the right side of assign expression */ assign = proc_assign_expr(self); if (assign != NULL) { struct finsh_node* idnode; idnode = finsh_node_new_id(id); /* make assign expression node */ if (node != NULL) { finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); end = finsh_node_sibling(end); } else { end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); node = end; } next_token(token, &(self->token)); } } } check_token(token, &(self->token), finsh_token_type_semicolon); return node; case finsh_token_type_assign:/*'=', it's a variable with assign declaration.*/ { struct finsh_node *idnode; assign = proc_assign_expr(self); if (assign != NULL) { idnode = finsh_node_new_id(id); /* make assign expression node */ end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); node = end; next_token(token, &(self->token)); } while ( token == finsh_token_type_comma ) { if (proc_identifier(self, id) == 0) { /* if add variable failed */ if (finsh_var_insert(id, type) < 0) { finsh_error_set(FINSH_ERROR_VARIABLE_EXIST); } } next_token(token, &(self->token)); if (token == finsh_token_type_assign) { /* get the right side of assign expression */ assign = proc_assign_expr(self); if (assign != NULL) { idnode = finsh_node_new_id(id); /* make assign expression node */ if (node != NULL) { finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); end = finsh_node_sibling(end); } else { end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign); node = end; } next_token(token, &(self->token)); } } } check_token(token, &(self->token), finsh_token_type_semicolon); return node; } case finsh_token_type_semicolon:/*';', it's a variable declaration.*/ return node; default: finsh_error_set(FINSH_ERROR_EXPECT_TYPE); return NULL; }}/**type -> type_prefix type_basic | type_basictype_prefix -> UNSIGNEDtype_basic -> VOID | CHAR | SHORT | INT | STRING*/static enum finsh_type proc_type(struct finsh_parser* self){ enum finsh_type type; enum finsh_token_type token; /* set init type */ type = finsh_type_unknown; next_token(token, &(self->token)); if ( is_base_type(token) ) /* base_type */ { switch (token) { case finsh_token_type_void: type = finsh_type_void; break; case finsh_token_type_char: type = finsh_type_char; break; case finsh_token_type_short: type = finsh_type_short; break; case finsh_token_type_int: type = finsh_type_int; break; case finsh_token_type_long: type = finsh_type_long; break; default: goto __return; break; } } else if ( token == finsh_token_type_unsigned ) /* unsigned base_type */ { next_token(token, &(self->token)); if ( is_base_type(token) ) { switch (token) { case finsh_token_type_char: type = finsh_type_uchar; break; case finsh_token_type_short: type = finsh_type_ushort; break; case finsh_token_type_int: type = finsh_type_uint; break; case finsh_token_type_long: type = finsh_type_ulong; break; default: goto __return; break; } } else { finsh_token_replay(&(self->token)); finsh_error_set(FINSH_ERROR_EXPECT_TYPE); } } else { goto __return; } /* parse for pointer */ next_token(token, &(self->token)); if (token == finsh_token_type_mul) { switch (type) { case finsh_type_void: type = finsh_type_voidp; break; case finsh_type_char: case finsh_type_uchar: type = finsh_type_charp; break; case finsh_type_short: case finsh_type_ushort: type = finsh_type_shortp; break; case finsh_type_int: case finsh_type_uint: type = finsh_type_intp; break; case finsh_type_long: case finsh_type_ulong: type = finsh_type_longp; break; default: type = finsh_type_voidp; break; } } else finsh_token_replay(&(self->token)); return type;__return: finsh_token_replay(&(self->token)); finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE); return type;}/**identifier -> IDENTIFIER*/static int proc_identifier(struct finsh_parser* self, char* id){ enum finsh_token_type token; match_token(token, &(self->token), finsh_token_type_identifier); strncpy(id, (char*)self->token.string, FINSH_NAME_MAX); return 0;}/**statement_expr -> ';' | expr ';'*/static struct finsh_node* proc_expr_statement(struct finsh_parser* self){ enum finsh_token_type token; struct finsh_node* expr; expr = NULL; next_token(token, &(self->token)); if ( token != finsh_token_type_semicolon ) { finsh_token_replay(&(self->token)); expr = proc_expr(self); match_token(token, &(self->token), finsh_token_type_semicolon); } return expr;}/**expr -> expr_assign*/static struct finsh_node* proc_expr(struct finsh_parser* self){ return proc_assign_expr(self);}/**expr_assign -> expr_inclusive_or | expr_unary ASSIGN expr_assign*/static struct finsh_node* proc_assign_expr(struct finsh_parser* self){ enum finsh_token_type token; struct finsh_node* or; struct finsh_node* assign; or = proc_inclusive_or_expr(self); next_token(token, &(self->token)); if (token == finsh_token_type_assign) { assign = proc_assign_expr(self); return make_sys_node(FINSH_NODE_SYS_ASSIGN, or, assign); } else finsh_token_replay(&(self->token)); return or;}/**expr_inclusive_or -> expr_exclusive_or | expr_inclusive_or '|' expr_exclusive_or*/static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self){ enum finsh_token_type token; struct finsh_node* xor; struct finsh_node* xor_new; xor = proc_exclusive_or_expr(self); next_token(token, &(self->token)); while ( token == finsh_token_type_or ) { xor_new = proc_exclusive_or_expr(self); if (xor_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); else xor = make_sys_node(FINSH_NODE_SYS_OR, xor, xor_new); next_token(token, &(self->token)); } finsh_token_replay(&(self->token)); return xor;}/**expr_exclusive_or -> expr_and | expr_exclusive '^' expr_and*/static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self){ enum finsh_token_type token; struct finsh_node* and; struct finsh_node* and_new; and = proc_and_expr(self); next_token(token, &(self->token)); while ( token == finsh_token_type_xor ) { and_new = proc_and_expr(self); if (and_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR); else and = make_sys_node(FINSH_NODE_SYS_XOR, and, and_new); next_token(token, &(self->token)); } finsh_token_replay(&(self->token)); return and;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -