📄 spl.y.c
字号:
snprintf(mini_buf, sizeof(mini_buf) - 1, "switch_exit_%d", top_lbl_stack()); mini_buf[sizeof(mini_buf) - 1] = 0; exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID); t = jump_tree(exit_label); list_append(&ast_forest, t);#else do_case_jump();#endif}oSEMI|yNAME{ p = find_symbol( top_symtab_stack(),$1); if(!p){ parse_error("Undeclared identifier",$1); install_temporary_symbol($1, DEF_CONST, TYPE_INTEGER); /* return 0; */ } if(p->defn != DEF_ELEMENT &&p->defn != DEF_CONST){ parse_error("Element name expected",""); return 0; }#ifdef GENERATE_AST case_label_count = top_case_stack(); snprintf(mini_buf, sizeof(mini_buf) - 1, "case_%d_%d", top_lbl_stack(), case_label_count++); mini_buf[sizeof(mini_buf) - 1] = 0; push_case_stack(case_label_count); new_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID); t = label_tree(new_label); list_append(&ast_forest, t); case_list = top_case_ast_stack(); list_append(case_list, t); t = id_factor_tree(NULL, p); list_append(case_list, t);#else emit_load_value(p); add_case_const(p);#endif}oCOLON stmt{#ifdef GENERATE_AST snprintf(mini_buf, sizeof(mini_buf) - 1, "switch_exit_%d", top_lbl_stack()); mini_buf[sizeof(mini_buf) - 1] = 0; exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID); t = jump_tree(exit_label); list_append(&ast_forest, t);#else do_case_jump();#endif}oSEMI;goto_stmt:kGOTO cINTEGER;expression_list:expression_list oCOMMA expression{#ifdef GENERATE_AST rtn = top_call_stack(); /* next argument. */ if (arg) { arg = arg->next; } /* append to right tree of args. */ args = arg_tree(args, rtn, arg, $3); $$ = args;#endif}|expression{#ifdef GENERATE_AST args = NULL; /* first argument. set rtn to symtab of current function call. */ rtn = top_call_stack(); if(rtn) arg = rtn->args; else { parse_error("error parse sys call list.", ""); return 0; } args = arg_tree(args, rtn, arg, $1); $$ = args;#endif};expression:expression{#ifdef GENERATE_AST#else emit_push_op($1);#endif}oGE expr{#ifdef GENERATE_AST $$ = compare_expr_tree(GE, $1, $4);#else do_expression($4, oGE); $$ = TYPE_BOOLEAN;#endif}|expression{#ifdef GENERATE_AST#else emit_push_op($1);#endif}oGT expr{#ifdef GENERATE_AST $$ = compare_expr_tree(GT, $1, $4);#else do_expression($4, oGT); $$ = TYPE_BOOLEAN;#endif}|expression{#ifdef GENERATE_AST#else emit_push_op($1);#endif}oLE expr{#ifdef GENERATE_AST $$ = compare_expr_tree(LE, $1, $4);#else do_expression($4,oLE); $$ = TYPE_BOOLEAN;#endif}|expression{#ifdef GENERATE_AST#else emit_push_op($1);#endif}oLT expr{#ifdef GENERATE_AST $$ = compare_expr_tree(LT, $1, $4);#else do_expression($4,oLT); $$ = TYPE_BOOLEAN;#endif}|expression{#ifdef GENERATE_AST#else emit_push_op($1);#endif}oEQUAL expr{#ifdef GENERATE_AST $$ = compare_expr_tree(EQ, $1, $4);#else do_expression($4,oEQUAL); $$ = TYPE_BOOLEAN;#endif}|expression{#ifdef GENERATE_AST#else emit_push_op($1);#endif}oUNEQU expr{#ifdef GENERATE_AST $$ = compare_expr_tree(NE, $1, $4);#else do_expression($4,oUNEQU); $$ = TYPE_BOOLEAN;#endif}|expr{#ifdef GENERATE_AST $$ = $1;#else $$ = $1->type->type_id;#endif};expr:expr{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}oPLUS term{#ifdef GENERATE_AST $$ = binary_expr_tree(ADD, $1, $4);#else do_expr($4,oPLUS);#endif}|expr{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}oMINUS term{#ifdef GENERATE_AST $$ = binary_expr_tree(SUB, $1, $4);#else do_expr($4 ,oMINUS);#endif}|expr{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}kOR term{#ifdef GENERATE_AST $$ = binary_expr_tree(OR, $1, $4);#else do_expression($4,kOR);#endif}|term{#ifdef GENERATE_AST $$ = $1;#endif};term :term{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}oMUL factor{#ifdef GENERATE_AST $$ = binary_expr_tree(MUL, $1, $4);#else do_term($4,oMUL);#endif}| term{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}oDIV factor{#ifdef GENERATE_AST $$ = binary_expr_tree(DIV, $1, $4);#else do_term($4,kDIV);#endif}|term{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}kDIV factor{#ifdef GENERATE_AST $$ = binary_expr_tree(DIV, $1, $4);#else do_term($4, kDIV);#endif}|term{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}kMOD factor{#ifdef GENERATE_AST $$ = binary_expr_tree(MOD, $1, $4);#else do_term($4, kMOD);#endif}|term{#ifdef GENERATE_AST#else emit_push_op($1->type->type_id);#endif}kAND factor{#ifdef GENERATE_AST $$ = binary_expr_tree(AND, $1, $4);#else do_term($4,kAND);#endif}|factor{ $$ = $1;};factor: yNAME{ p = NULL; if((p = find_symbol( top_symtab_stack(),$1))) { if(p->type->type_id == TYPE_ARRAY ||p->type->type_id == TYPE_RECORD) { parse_error("rvalue expected", ""); return 0; } } else if ((ptab = find_routine($1)) == NULL) { parse_error("Undeclard identificr",$1); p = install_temporary_symbol($1, DEF_VAR, TYPE_INTEGER); /* return 0; */ }#ifdef GENERATE_AST if (p) { $$ = id_factor_tree(NULL, p); } else { /* call functions with no arguments. */ $$ = call_tree(ptab, NULL); }#else if(p) { $$ = p; do_factor(p); } else { $$ = do_function_call(ptab); }#endif}|yNAME{ if((ptab = find_routine($1))) push_call_stack(ptab); else { parse_error("Undeclared funtion",$1); return 0; }}oLP args_list oRP{#ifdef GENERATE_AST $$ = call_tree(ptab, args);#else $$ = do_function_call(top_call_stack());#endif pop_call_stack();}|SYS_FUNCT{ ptab = find_sys_routine($1->attr);#ifdef GENERATE_AST $$ = sys_tree($1->attr, NULL);#else do_sys_routine(ptab->id, ptab->type->type_id); $$ = ptab->locals;#endif}|SYS_FUNCT{ ptab = find_sys_routine($1->attr); push_call_stack(ptab);}oLP args_list oRP{ ptab = top_call_stack();#ifdef GENERATE_AST $$ = sys_tree($1->attr, args);#else ptab = top_call_stack(); do_sys_routine(-ptab->id, ptab->type->type_id); ptab = pop_call_stack(); $$ = ptab->locals;#endif}|const_value{ switch($1->type->type_id){ case TYPE_REAL: case TYPE_STRING: add_symbol_to_table(Global_symtab, $1); break; case TYPE_BOOLEAN: sprintf($1->rname, "%d", (int)($1->v.b)); break; case TYPE_INTEGER: if($1->v.i > 0) sprintf($1->rname,"0%xh", $1->v.i); else sprintf($1->rname, "-0%xh", -($1->v.i)); break; case TYPE_CHAR: sprintf($1->rname, "'%c'", $1->v.c); break; default: break; }#ifdef GENERATE_AST $$ = const_tree($1);#else do_factor($1);#endif}|oLP expression oRP{#ifdef GENERATE_AST $$ = $2;#else $$ = find_symbol(NULL, ""); $$->type = find_type_by_id($2);#endif}|kNOT factor{#ifdef GENERATE_AST $$ = not_tree($2);#else do_not_factor($2); $$ = $2;#endif}|oMINUS factor{#ifdef GENERATE_AST $$ = neg_tree($2);#else do_negate($2); $$ = $2;#endif}|yNAME oLB{ p = find_symbol( top_symtab_stack(), $1); if(!p || p->type->type_id != TYPE_ARRAY){ parse_error("Undeclared array name",$1); return 0; } push_term_stack(p);#ifdef GENERATE_AST#else emit_load_address(p); emit_push_op(TYPE_INTEGER);#endif}expression oRB{#ifdef GENERATE_AST p = pop_term_stack(p); t = array_factor_tree(p, $4); $$ = id_factor_tree(t, p);#else p = pop_term_stack(p); do_array_factor(p); emit_load_value(p); $$ = p->type_link->last;#endif}|yNAME oDOT yNAME{ p = find_symbol(top_symtab_stack(), $1); if(!p || p->type->type_id != TYPE_RECORD) { parse_error("Undeclared record variable",$1); return 0; } q = find_field(p, $3); if(!q || q->defn != DEF_FIELD){ parse_error("Undeclared field ",$3); return 0; } #ifdef GENERATE_AST t = field_tree(p, q); $$ = id_factor_tree(t, q);#else emit_load_address(p); emit_push_op(TYPE_INTEGER); do_record_factor(p,q); emit_load_field(q); $$ = q;#endif};args_list:args_list oCOMMA expression {#ifdef GENERATE_AST rtn = top_call_stack(); /* next argument. */ if (arg) { arg = arg->next; } /* append to right tree of args. */ args = arg_tree(args, rtn, arg, $3);#else do_args($3);#endif}|expression {#ifdef GENERATE_AST args = NULL; /* first argument. set rtn to symtab of current function call. */ rtn = top_call_stack(); if(rtn) arg = rtn->args; else { parse_error("parse argument list.", ""); return 0; } if(arg) { args = arg_tree(args, rtn, arg, $1); }#else do_first_arg($1);#endif};%%#define MAX_TERM 64symbol *term_stk[MAX_TERM];int term_stk_tos = MAX_TERM - 1;void push_term_stack(symbol * p){ if(term_stk_tos == 0) internal_error("teminal stak overtlow"); else term_stk[term_stk_tos--] = p; }symbol * pop_term_stack(){ if (term_stk_tos == MAX_TERM - 1) { internal_error("terminal stack underflow"); return NULL; } else return term_stk[++term_stk_tos];}symbol* top_term_stack(){ if(term_stk_tos == MAX_TERM - 1){ internal_error("terminal stack underflow"); return NULL; } else return term_stk[term_stk_tos + 1];}int parser_init(){#ifdef GENERATE_AST memset(&ast_forest, 0, sizeof(ast_forest)); memset(¶_list, 0, sizeof(para_list)); memset(&case_list, 0, sizeof(case_list)); if_label_count = repeat_label_count = do_label_count = while_label_count = case_label_count = switch_label_count = for_label_count = 0;#endif return 0;}#ifdef GENERATE_ASTTree ast_stk[MAX_TERM];int ast_stk_tos = MAX_TERM - 1;void push_ast_stack(Tree t){ if(ast_stk_tos == 0) internal_error("ast tree stak overtlow"); else ast_stk[ast_stk_tos--] = t;}Tree pop_ast_stack(){ if (ast_stk_tos == MAX_TERM - 1) { internal_error("ast tree stack underflow"); return NULL; } else return ast_stk[++ast_stk_tos];}Tree top_ast_stack(){ if(ast_stk_tos == MAX_TERM - 1){ internal_error("ast stack underflow"); return NULL; } else return ast_stk[ast_stk_tos + 1];}int lbl_stk[MAX_TERM];int lbl_stk_tos = MAX_TERM - 1;void push_lbl_stack(int id){ if(lbl_stk_tos == 0) internal_error("ast tree stak overtlow"); else lbl_stk[lbl_stk_tos--] = id;}int pop_lbl_stack(){ if (lbl_stk_tos == MAX_TERM - 1) { internal_error("ast tree stack underflow"); return 0; } else return lbl_stk[++lbl_stk_tos];}int top_lbl_stack(){ if(lbl_stk_tos == MAX_TERM - 1){ internal_error("ast stack underflow"); return 0; } else return lbl_stk[lbl_stk_tos + 1];}int case_stk[MAX_TERM];int case_stk_tos = MAX_TERM - 1;void push_case_stack(int id){ if(case_stk_tos == 0) internal_error("ast tree stak overtlow"); else case_stk[case_stk_tos--] = id;}int pop_case_stack(){ if (case_stk_tos == MAX_TERM - 1) { internal_error("ast tree stack underflow"); return 0; } else return case_stk[++case_stk_tos];}int top_case_stack(){ if(case_stk_tos == MAX_TERM - 1){ internal_error("ast stack underflow"); return 0; } else return case_stk[case_stk_tos + 1];}List case_ast_stk[MAX_TERM];int case_ast_stk_tos = MAX_TERM - 1;void push_case_ast_stack(List newlist){ if(case_ast_stk_tos == 0) internal_error("ast tree stak overtlow"); else case_ast_stk[case_ast_stk_tos--] = newlist;}List pop_case_ast_stack(){ if (case_ast_stk_tos == MAX_TERM - 1) { internal_error("ast tree stack underflow"); return NULL; } else return case_ast_stk[++case_ast_stk_tos];}List top_case_ast_stack(){ if(case_ast_stk_tos == MAX_TERM - 1){ internal_error("ast stack underflow"); return NULL; } else return case_ast_stk[case_ast_stk_tos + 1];}#endif/* add a temporary symbol when encounted a not defined symbol */Symbol install_temporary_symbol(char *name, int deftype, int typeid){ Symbol p = new_symbol(name, deftype, typeid); add_local_to_table(top_symtab_stack(), p); return p;}void trap_in_debug(){ printf("trap_in_debug()\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -