fincparser.c
来自「FinC编译器源代码」· C语言 代码 · 共 2,486 行 · 第 1/4 页
C
2,486 行
{ FinCTokenType token; FinCNode* expr; next_token(token, self->lex); switch ( token ) { case FinCTokenType_Identifier: finc_token_replay(self->lex); return proc_identifier(self); case FinCTokenType_Left_Paren: expr = proc_expr(self); match_token(token, self->lex, FinCTokenType_Right_Paren); return expr; case FinCTokenType_Int: return finc_node_new_integer((int)self->lex->last_double); #ifdef USING_FLOAT case FinCTokenType_Float: return finc_node_new_float((float)self->lex->last_float); #endif #ifdef USING_DOUBLE case FinCTokenType_Double: return finc_node_new_double((long)self->lex->last_double); #endif case FinCTokenType_Long: return finc_node_new_long((long)self->lex->last_double); case FinCTokenType_Char: return finc_node_new_char(self->lex->last_char); case FinCTokenType_String: return finc_node_new_string(string_get_str(self->lex->last_str)); case FinCTokenType_Null: return finc_node_new_pointer(NULL); case FinCTokenType_True: return finc_node_new_bool(TRUE); case FinCTokenType_False: return finc_node_new_bool(FALSE); default: finc_token_replay(self->lex); break; } return NULL;}/*param_list -> empty | expr_assign | param_list ',' expr_assign*/static FinCNode* proc_call_param_list(FinCParser* self){ FinCTokenType token; FinCNode* assign; assign = proc_assign_expr(self); make_call_add (self, assign); next_token(token, self->lex); while (token == FinCTokenType_Comma ) { assign = proc_assign_expr(self); next_token(token, self->lex); make_call_add (self, assign); } finc_token_replay(self->lex); return NULL;}/*statement -> decl_local | statement_block | statement_expr | statement_return | statement_for | statement_while | statement_if | statement_continue | statement_break*/static FinCNode* proc_statement(FinCParser* self){ FinCTokenType token; String* str; next_token(token, self->lex); switch ( token ) { case FinCTokenType_Left_Curly: finc_token_replay(self->lex); return proc_block_statement(self); break; case FinCTokenType_Return: case FinCTokenType_Continue: case FinCTokenType_Break: finc_token_replay(self->lex); return proc_simple_statement(self); break; case FinCTokenType_For: finc_token_replay(self->lex); return proc_for_statement(self); break; case FinCTokenType_While: finc_token_replay(self->lex); return proc_while_statement(self); break; case FinCTokenType_If: finc_token_replay(self->lex); return proc_if_statement(self); break; default: if (is_type(token)) { if ( token == FinCTokenType_Identifier ) /*if it's a function call.*/ { str = finc_token_get_token(self->lex); if (finc_lang_check_type(self->lang_env, str))/*it's a struct type.*/ { unref(str); finc_token_replay(self->lex); return make_efunc1("local", proc_variable_decl(self)); } else/*it's a function call.*/ { unref(str); finc_token_replay(self->lex); return proc_expr_statement(self); } } finc_token_replay(self->lex); return make_efunc1("local", proc_variable_decl(self)); } finc_lang_error_line(self->lex, "Parser Error: unexpecting token."); finc_context_error_inc(g_finc_context); finc_token_replay(self->lex); break; } return NULL;}/*statement_in_block -> decl_local | statement_block | statement_node | statement_return | statement_for | statement_while | statement_if*/static FinCNode* proc_in_block_statement(FinCParser* self){ FinCTokenType token; String* str; next_token(token, self->lex); switch ( token ) { case FinCTokenType_Left_Curly: finc_token_replay(self->lex); return proc_block_statement(self); break; case FinCTokenType_Return: case FinCTokenType_Continue: case FinCTokenType_Break: finc_token_replay(self->lex); return proc_simple_statement(self); break; case FinCTokenType_For: finc_token_replay(self->lex); return proc_for_statement(self); break; case FinCTokenType_While: finc_token_replay(self->lex); return proc_while_statement(self); break; case FinCTokenType_If: finc_token_replay(self->lex); return proc_if_statement(self); break; default: if (is_type(token)) { if ( token == FinCTokenType_Identifier ) /*if it's a function call.*/ { str = finc_token_get_token(self->lex); if (finc_lang_check_type(self->lang_env, str))/*it's a struct type.*/ { unref(str); finc_token_replay(self->lex); return make_efunc1("local", proc_variable_decl(self)); } else/*it's a function call.*/ { unref(str); finc_token_replay(self->lex); return proc_expr_statement(self); } } finc_token_replay(self->lex); return make_efunc1("local", proc_variable_decl(self)); } finc_lang_error_line(self->lex, "Parser Error: unexpecting token."); finc_context_error_inc(g_finc_context); finc_token_replay(self->lex); break; } return NULL;}/*statement_block -> '{' statement_list '}'statement_list -> statement_in_block | statement_list statement_in_block*/static FinCNode* proc_block_statement(FinCParser* self){ FinCTokenType token; FinCNode* statement; match_token(token, self->lex, FinCTokenType_Left_Curly); make_block_begin(self); next_token(token, self->lex); while (token != FinCTokenType_Right_Curly) { finc_token_replay(self->lex); statement = proc_in_block_statement(self); if (statement) { make_block_add(self, statement); next_token(token, self->lex); } else break; } return make_block_finish(self);}/*statement_expr -> ';' | expr ';'*/static FinCNode* proc_expr_statement(FinCParser* self){ FinCTokenType token; FinCNode* expr; expr = NULL; next_token(token, self->lex); if ( token != FinCTokenType_Semicolon ) { finc_token_replay(self->lex); expr = proc_expr(self); match_token(token, self->lex, FinCTokenType_Semicolon); } return expr;}/*statement_for -> FOR '(' statement_expr statement_expr expr ')' statement*/static FinCNode* proc_for_statement(FinCParser* self){ FinCTokenType token; FinCNode *expr_s1, *expr_s2, *expr, *statement; expr = NULL; match_token(token, self->lex, FinCTokenType_For); match_token(token, self->lex, FinCTokenType_Left_Paren); expr_s1 = proc_expr_statement(self); expr_s2 = proc_expr_statement(self); next_token(token, self->lex); if (token != FinCTokenType_Right_Paren) { finc_token_replay(self->lex); expr = proc_expr(self); match_token(token, self->lex, FinCTokenType_Right_Paren); } statement = proc_statement(self); return make_efunc4 ("for", expr_s1, expr_s2, expr, statement);}/*statement_while -> WHILE '(' expr ')' statement*/static FinCNode* proc_while_statement(FinCParser* self){ FinCTokenType token; FinCNode *expr, *statement; match_token(token, self->lex, FinCTokenType_While); match_token(token, self->lex, FinCTokenType_Left_Paren); expr = proc_expr(self); match_token(token, self->lex, FinCTokenType_Right_Paren); statement = proc_statement(self); return make_efunc2 ("while", expr, statement);}/*statement_if -> IF '(' expr ')' statement statement_if_elsestatement_if_else -> empty | ELSE statement*/static FinCNode* proc_if_statement(FinCParser* self){ FinCTokenType token; FinCNode *expr, *statement_true, *statement_false; statement_false = NULL; match_token(token, self->lex, FinCTokenType_If); match_token(token, self->lex, FinCTokenType_Left_Paren); expr = proc_expr(self); match_token(token, self->lex, FinCTokenType_Right_Paren); statement_true = proc_statement(self); next_token(token, self->lex); if ( token == FinCTokenType_Else ) statement_false = proc_statement(self); else finc_token_replay(self->lex); if ( statement_false ) { return make_efunc3 ("if", expr, statement_true, statement_false); } else { return make_efunc2 ("if", expr, statement_true); } return NULL;}/*statement_continue -> CONTINUE ';'statement_break -> BREAK ';'statement_return -> RETURN expr ';'*/static FinCNode* proc_simple_statement(FinCParser* self){ FinCTokenType token; FinCNode* expr; expr = NULL; next_token(token, self->lex); switch ( token ) { case FinCTokenType_Continue: match_token(token, self->lex, FinCTokenType_Semicolon); return make_efunc("continue"); break; case FinCTokenType_Break: match_token(token, self->lex, FinCTokenType_Semicolon); return make_efunc("break"); break; case FinCTokenType_Return: next_token(token, self->lex); if ( token != FinCTokenType_Semicolon ) { finc_token_replay(self->lex); expr = proc_expr(self); next_token(token, self->lex); } check_token(token, self->lex, FinCTokenType_Semicolon); return make_efunc1("return", expr); break; default: break; } return NULL;}static void make_pkg_begin(FinCParser* self, unsigned char* p_package){ FinCNode* pkg_name; pkg_name = finc_node_new_name(p_package); self->current_pkg = finc_node_new_func("package"); finc_node_add(self->current_pkg, pkg_name); unref(pkg_name);}static void make_pkg_func_begin (FinCParser* self, FinCNode* p_type, FinCNode* p_identifier){ self->current_func = finc_node_new_func ("func"); finc_node_add (self->current_func, p_type); unref (p_type); finc_node_add (self->current_func, p_identifier); unref (p_identifier);}static FinCNode* make_pkg_func_finish (FinCParser* self){ FinCNode* l_func; l_func = self->current_func; self->current_func = NULL; return l_func;}static FinCNode* make_pkg_finish(FinCParser* self){ FinCNode* l_pkg; l_pkg = self->current_pkg; self->current_pkg = NULL; return l_pkg;}static void make_func_begin (FinCParser* self, FinCNode* p_type, FinCNode* p_identifier){ self->current_func = finc_node_new_func ("func"); finc_node_add (self->current_func, p_type); unref (p_type); finc_node_add (self->current_func, p_identifier); unref (p_identifier);}static void make_func_add_param (FinCParser* self, FinCNode* p_type, FinCNode* p_name){ finc_node_add (self->current_func, p_type); unref (p_type); finc_node_add (self->current_func, p_name); unref (p_name);}static void make_func_opt_param (FinCParser* self){ finc_node_add (self->current_func, NULL);}static FinCNode* make_func_finish (FinCParser* self, FinCNode* p_code){ FinCNode* l_func; finc_node_add (self->current_func, p_code); unref (p_code); l_func = self->current_func; self->current_func = NULL; return l_func;}static void make_block_begin (FinCParser* self){ if (self->current_block) { stack_push(self->stack_block, (ADT)self->current_block); unref(self->current_block); } self->current_block = finc_node_new_func ("@");}static void make_block_add (FinCParser* self, FinCNode* p_node){ finc_node_add (self->current_block, p_node); unref (p_node);}static FinCNode* make_block_finish (FinCParser* self){ FinCNode* l_block; if (stack_get_size(self->stack_block) > 0) { l_block = self->current_block; self->current_block = stack_pop(self->stack_block); } else { l_block = self->current_block; self->current_block = NULL; } return l_block;}static void make_call_begin (FinCParser* self, unsigned char* p_identifier){ if (self->current_call) { stack_push(self->stack_call, (ADT)self->current_call); unref(self->current_call); } self->current_call = finc_node_new_func (p_identifier);}static void make_call_add (FinCParser* self, FinCNode* p_node){ finc_node_add (self->current_call, p_node); unref (p_node);}static FinCNode* make_call_finish (FinCParser* self){ FinCNode* l_call; if (stack_get_size(self->stack_call) > 0) { l_call = self->current_call; self->current_call = stack_pop(self->stack_call); } else { l_call = self->current_call; self->current_call = NULL; } return l_call;}static FinCNode* make_efunc (unsigned char* p_func){ return finc_node_new_func (p_func);}static FinCNode* make_efunc1 (unsigned char* p_func, FinCNode* p_node1){ FinCNode* l_node; l_node = finc_node_new_func (p_func); finc_node_add (l_node, p_node1); unref (p_node1); return l_node;}static FinCNode* make_efunc2 (unsigned char* p_func, FinCNode* p_node1, FinCNode* p_node2){ FinCNode* l_node; l_node = finc_node_new_func (p_func); finc_node_add (l_node, p_node1); unref (p_node1); finc_node_add (l_node, p_node2); unref (p_node2); return l_node;}static FinCNode* make_efunc3 (unsigned char* p_func, FinCNode* p_node1, FinCNode* p_node2, FinCNode* p_node3){ FinCNode* l_node; l_node = finc_node_new_func (p_func); finc_node_add (l_node, p_node1); unref (p_node1); finc_node_add (l_node, p_node2); unref (p_node2); finc_node_add (l_node, p_node3); unref (p_node3); return l_node;}static FinCNode* make_efunc4 (unsigned char* p_func, FinCNode* p_node1, FinCNode* p_node2, FinCNode* p_node3, FinCNode* p_node4){ FinCNode* l_node; l_node = finc_node_new_func (p_func); finc_node_add (l_node, p_node1); unref (p_node1); finc_node_add (l_node, p_node2); unref (p_node2); finc_node_add (l_node, p_node3); unref (p_node3); finc_node_add (l_node, p_node4); unref (p_node4); return l_node;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?