static int parser_vardeclaration() { string testset[]={"",";"}; do{ if(!parser_vardefinition()) { parser_test(testset,2); if(lex_sym=="") { global_error(";","nothing"); return 0; } } if(lex_sym!=";") { global_error(";","nothing"); } else lex_getsym(); }while(lex_sym=="ident"); #ifdef PARSER_DEBUG cout << "变量声明" << endl; #endif return 1; }
static int parser_formalparalist(int ¶_size) { string testset[]={"",";",")"}; if(lex_sym!="(") { global_error("(",lex_sym); return 0; } else { do{ lex_getsym(); if(!parser_formalparasection(para_size)) { parser_test(testset,3); if(lex_sym=="") { global_error(")","nothing"); return 0; } } }while(lex_sym==";"); if(lex_sym!=")") { global_error(")",lex_sym); return 0; } lex_getsym(); } #ifdef PARSER_DEBUG cout << "形式参数表" << endl; #endif return 1; }
static int parser_condition(symbItem **src1,symbItem **src2,string &oprname)//传进lable1 { if(!parser_expression()) { string testset[]={"","<","<=",">",">=","=","<>"}; parser_test(testset,7); if(lex_sym=="") { global_error("relational operators","nothing"); return 0; } } else { *src1=operand_stack.top(); operand_stack.pop(); } oprname=lex_sym; if(!if_ralation_opr(oprname)) { global_error("relational operators","nothing"); return 0; } lex_getsym(); if(!parser_expression()) return 0; *src2=operand_stack.top(); operand_stack.pop(); #ifdef PARSER_DEBUG cout << "条件" << endl; #endif return 1; }
static int parser_compoundstatement()//require 读了begin 后面的一个单词 { string testset[]={"",";","end"}; if(!parser_statement(NULL)) { parser_test(testset,3); if(lex_sym=="") { global_error("end","nothing"); return 0; } } while(true) { if(lex_sym==";") lex_getsym(); else { string testset[]={"ident","end","","if","for","do","begin","write","read"}; parser_test(testset,9); if(lex_sym=="end") break; else if(lex_sym=="") { global_error("end","nothing"); return 0; } global_error(";","nothing"); } if(!parser_statement(NULL)) { parser_test(testset,3); if(lex_sym=="") { global_error("end","nothing"); return 0; } } } if(lex_sym!="end") { global_error("end","nothing"); return 0; } lex_getsym(); #ifdef PARSER_DEBUG cout << "复合语句" << endl; #endif return 1; }
void parser_program() { lex_getch(); lex_getsym(); string testset[]={".",""}; if(!parser_procedure()) { parser_test(testset,2); if(lex_sym=="") { global_error(".","nothing"); return; } } if(lex_sym!=".") global_error(".","nothing"); }
static int if_ralation_opr(string a) { if(a==":=") { global_error("=",a); return 1; } return a=="="|| a==">"||a==">="|| a=="<"||a=="<="|| a=="<>"; }
T const& get_global( std::string const& key ) { try { return boost::any_cast< T const& >( global( key ) ); } catch ( boost::bad_any_cast& ) { throw global_error( key ); } static T t; return t; }
static void parser_test(string a[],int num,int &flag) { flag=0; while(!parser_ifintestset(a,num,lex_sym)) { lex_getsym(); if(!flag) { global_error("Illegal parser in procedure"); flag=1; } } }
static int parser_constdeclaration() { string testset[]={",",";",""}; if(!parser_constdefinition())//去找他的合法后继们 { parser_test(testset,3); if(lex_sym=="")//找到了终止符号集 { global_error(";","nothing"); return 0; } }//读到了合法的后继之后就应该继续往下干。 while(lex_sym==",") { lex_getsym(); if(!parser_constdefinition()) { parser_test(testset,3); if(lex_sym=="") { global_error(";","nothing"); return 0; } } } if(lex_sym!=";") { global_error(";","nothing"); // string testset={"","var","function","procedure"}//找他的合法后继。。 return 0; } lex_getsym(); #ifdef PARSER_DEBUG cout << "常量声明" << endl; #endif return 1; }
int main(int ac, char **av) { char *buff; t_nbr res; if (ac != 4) { my_putstr("usage : "); my_putstr(av[0]); my_putstr("base ops\"()+-*/%\" exp_len\n"); return (1); } check_size(av); buff = buffer(av[3]); global_error(av, buff); trad_base_to_ascii(av, buff); my_init_zero(&res); eval_expr(buff, &res, my_strlen(av[1])); trad_ascii_to_base(av, &res); free(res.str); free(buff); return (0); }
static void vm_loop(su_state *s, function_t *func) { value_t tmpv, tmpv2; instruction_t inst; int tmp, narg, i, j, k; const char *tmpcs; su_debug_data dbg; s->frame = FRAME(); s->prot = func->prot; #define ARITH_OP(op) \ su_check_type(s, -2, SU_NUMBER); \ su_check_type(s, -1, SU_NUMBER); \ STK(-2)->obj.num = STK(-2)->obj.num op STK(-1)->obj.num; \ su_pop(s, 1); \ break; #define LOG_OP(op) \ su_check_type(s, -2, SU_NUMBER); \ su_check_type(s, -1, SU_NUMBER); \ STK(-2)->type = SU_BOOLEAN; \ STK(-2)->obj.b = STK(-2)->obj.num op STK(-1)->obj.num; \ su_pop(s, 1); \ break; for (s->pc = 0; s->pc < s->prot->num_inst; s->pc++) { tmp = s->interrupt | atomic_get(&s->msi->interrupt); if (tmp) { if ((tmp & ISCOLLECT) == ISCOLLECT) { su_thread_indisposable(s); su_thread_disposable(s); } if ((tmp & IGC) == IGC) { unmask_thread_interrupt(s, IGC); gc_trace(s); } if ((tmp & IBREAK) == IBREAK) { unmask_thread_interrupt(s, IBREAK); dbg.file = s->prot->name->str; dbg.line = s->prot->lineinf[s->pc]; s->debug_cb(s, &dbg, s->debug_cb_data); } } inst = s->prot->inst[s->pc]; switch (inst.id) { case OP_PUSH: push_value(s, &func->constants[inst.a]); break; case OP_POP: su_pop(s, inst.a); break; case OP_ADD: ARITH_OP(+) case OP_SUB: ARITH_OP(-) case OP_MUL: ARITH_OP(*) case OP_DIV: su_check_type(s, -2, SU_NUMBER); su_check_type(s, -1, SU_NUMBER); su_assert(s, STK(-1)->obj.num != 0.0, "Division by zero!"); STK(-2)->obj.num = STK(-2)->obj.num / STK(-1)->obj.num; su_pop(s, 1); break; case OP_MOD: su_check_type(s, -2, SU_NUMBER); su_check_type(s, -1, SU_NUMBER); STK(-2)->obj.num = (double)((int)STK(-2)->obj.num % (int)STK(-1)->obj.num); su_pop(s, 1); break; case OP_POW: su_check_type(s, -2, SU_NUMBER); su_check_type(s, -1, SU_NUMBER); STK(-2)->obj.num = pow(STK(-2)->obj.num, STK(-1)->obj.num); su_pop(s, 1); break; case OP_UNM: su_check_type(s, -1, SU_NUMBER); STK(-1)->obj.num = -STK(-1)->obj.num; break; case OP_EQ: STK(-2)->obj.b = value_eq(STK(-2), STK(-1)); STK(-2)->type = SU_BOOLEAN; su_pop(s, 1); break; case OP_LESS: LOG_OP(<); case OP_LEQUAL: LOG_OP(<=); case OP_NOT: if (STK(-1)->type == SU_BOOLEAN) { STK(-1)->obj.b = !STK(-1)->obj.b; } else { STK(-1)->obj.b = (STK(-1)->type == SU_NIL) ? 1 : 0; STK(-1)->type = SU_BOOLEAN; } break; case OP_AND: tmp = STK(-2)->type != SU_NIL && (STK(-2)->type != SU_BOOLEAN || STK(-2)->obj.b); if (tmp && STK(-1)->type != SU_NIL && (STK(-1)->type != SU_BOOLEAN || STK(-1)->obj.b)) { s->stack[s->stack_top - 2] = *STK(-1); } else { STK(-2)->obj.b = 0; STK(-2)->type = SU_BOOLEAN; } su_pop(s, 1); break; case OP_OR: if (STK(-2)->type != SU_NIL && (STK(-2)->type != SU_BOOLEAN || STK(-2)->obj.b)) { /* return -2 */ } else if (STK(-1)->type != SU_NIL && (STK(-1)->type != SU_BOOLEAN || STK(-1)->obj.b)) { s->stack[s->stack_top - 2] = *STK(-1); } else { STK(-2)->obj.b = 0; STK(-2)->type = SU_BOOLEAN; } su_pop(s, 1); break; case OP_TEST: if (STK(-1)->type != SU_NIL && (STK(-1)->type != SU_BOOLEAN || STK(-1)->obj.b)) s->pc = inst.b - 1; su_pop(s, 1); break; case OP_FOR: if (STK(-2)->type == SU_NIL) { su_swap(s, -2, -1); s->stack_top--; s->pc = inst.b - 1; } else { s->stack_top--; su_check_type(s, -1, SU_SEQ); su_rest(s, -1); su_swap(s, -2, -1); su_first(s, -1); su_swap(s, -2, -1); s->stack_top--; } break; case OP_JMP: s->pc = inst.b - 1; break; case OP_RETURN: s->pc = s->frame->ret_addr - 1; s->prot = s->frame->func->prot; func = s->frame->func; s->stack[s->frame->stack_top] = *STK(-1); s->stack_top = s->frame->stack_top + 1; s->frame_top--; s->frame = FRAME(); break; case OP_TCALL: s->pc = s->frame->ret_addr - 1; s->prot = s->frame->func->prot; func = s->frame->func; memmove(&s->stack[s->frame->stack_top], &s->stack[s->stack_top - (inst.a + 1)], sizeof(value_t) * (inst.a + 1)); s->stack_top = s->frame->stack_top + inst.a + 1; s->frame_top--; s->frame = FRAME(); /* Do a normal call. */ case OP_CALL: tmp = s->stack_top - inst.a - 1; switch (s->stack[tmp].type) { case SU_FUNCTION: s->frame = &s->frames[s->frame_top++]; assert(s->frame_top <= MAX_CALLS); s->frame->ret_addr = s->pc + 1; s->frame->func = func; s->frame->stack_top = tmp; func = s->stack[tmp].obj.func; if (func->narg < 0) su_vector(s, inst.a); else if (func->narg != inst.a) su_error(s, "Bad number of arguments to function! Expected %i, but got %i.", (int)func->narg, (int)inst.a); s->prot = func->prot; s->pc = -1; break; case SU_NATIVEFUNC: narg = s->narg; s->narg = inst.a; if (s->stack[tmp].obj.nfunc(s, inst.a)) { s->stack[tmp] = *STK(-1); } else { s->stack[tmp].type = SU_NIL; } s->stack_top = tmp + 1; s->narg = narg; break; case SU_VECTOR: if (inst.a == 1) { su_check_type(s, -1, SU_NUMBER); tmpv = vector_index(s, s->stack[tmp].obj.vec, su_tointeger(s, -1)); su_pop(s, 2); push_value(s, &tmpv); } else { for (i = -inst.a, j = 0; i; i++, j++) { su_check_type(s, i - j, SU_NUMBER); tmpv = vector_index(s, s->stack[tmp].obj.vec, su_tointeger(s, i - j)); push_value(s, &tmpv); } su_vector(s, inst.a); s->stack[tmp] = s->stack[s->stack_top - 1]; s->stack_top -= inst.a + 1; } break; case SU_MAP: if (inst.a == 1) { tmpv2 = *STK(-1); tmpv = map_get(s, s->stack[tmp].obj.m, &tmpv2, hash_value(&tmpv2)); su_assert(s, tmpv.type != SU_INV, "No value with key: %s", stringify(s, &tmpv2)); su_pop(s, 2); push_value(s, &tmpv); } else { for (i = -inst.a, j = 0; i; i++, j += 2) { tmpv2 = *STK(i - j); push_value(s, &tmpv2); tmpv = map_get(s, s->stack[tmp].obj.m, &tmpv2, hash_value(&tmpv2)); su_assert(s, tmpv.type != SU_INV, "No value with key: %s", stringify(s, &tmpv2)); push_value(s, &tmpv); } su_map(s, inst.a); s->stack[tmp] = s->stack[s->stack_top - 1]; s->stack_top -= inst.a + 1; } break; case SU_STRING: if (inst.a == 1) { su_check_type(s, -1, SU_NUMBER); j = su_tointeger(s, -1); su_assert(s, j < s->stack[tmp].obj.str->size, "Out of range!"); s->scratch_pad[0] = s->stack[tmp].obj.str->str[j]; su_pop(s, 2); su_pushbytes(s, s->scratch_pad, 1); } else { k = 0; for (i = -inst.a; i; i++) { su_check_type(s, i, SU_NUMBER); j = su_tointeger(s, i); su_assert(s, j < s->stack[tmp].obj.str->size, "Out of range!"); s->scratch_pad[k++] = s->stack[tmp].obj.str->str[j]; assert(k < SU_SCRATCHPAD_SIZE); } su_pushbytes(s, s->scratch_pad, k); s->stack[tmp] = s->stack[s->stack_top - 1]; s->stack_top -= inst.a + 1; } break; case SU_NATIVEDATA: tmpv = s->stack[tmp]; if (tmpv.obj.data->vt && tmpv.obj.data->vt->call) { narg = s->narg; s->narg = inst.a; if (tmpv.obj.data->vt->call(s, (void*)tmpv.obj.data->data, inst.a)) s->stack[tmp] = *STK(-1); else s->stack[tmp].type = SU_NIL; s->stack_top = tmp + 1; s->narg = narg; break; } default: if (inst.a == 1 && isseq(s, &s->stack[tmp])) { su_check_type(s, -1, SU_STRING); tmpcs = su_tostring(s, -1, NULL); if (!strcmp(tmpcs, "first")) { s->stack[(--s->stack_top) - 1] = seq_first(s, STK(-1)->obj.q); break; } else if (!strcmp(tmpcs, "rest")) { s->stack[(--s->stack_top) - 1] = seq_rest(s, STK(-1)->obj.q); break; } } su_error(s, "Can't apply '%s'.", type_name(s->stack[tmp].type)); } break; case OP_LAMBDA: assert(inst.a < s->prot->num_prot); lambda(s, &s->prot->prot[inst.a], inst.b); break; case OP_GETGLOBAL: tmpv = func->constants[inst.a]; su_assert(s, tmpv.type == SU_STRING, "Global key must be a string!"); tmpv = map_get(s, unref_local(s, s->stack[SU_GLOBAL_INDEX].obj.loc).obj.m, &tmpv, hash_value(&tmpv)); if (tmpv.type == SU_INV) global_error(s, "Undefined global variable", &func->constants[inst.a]); push_value(s, &tmpv); break; case OP_SETGLOBAL: tmpv = func->constants[inst.a]; su_assert(s, tmpv.type == SU_STRING, "Global key must be a string!"); i = hash_value(&tmpv); tmpv2 = unref_local(s, s->stack[SU_GLOBAL_INDEX].obj.loc); tmpv = map_insert(s, tmpv2.obj.m, &tmpv, i, STK(-1)); set_local(s, s->stack[SU_GLOBAL_INDEX].obj.loc, &tmpv); break; case OP_SHIFT: s->stack[s->stack_top - (inst.a + 1)] = *STK(-1); s->stack_top -= inst.a; break; case OP_LOAD: assert(FRAME()->stack_top + inst.a < s->stack_top); push_value(s, &s->stack[FRAME()->stack_top + inst.a]); break; case OP_LUP: assert(inst.a < func->num_ups); push_value(s, &func->upvalues[inst.a]); break; case OP_LCL: assert(inst.b < s->msi->num_c_lambdas); push_value(s, &s->msi->c_lambdas[inst.b]); break; default: assert(0); } #undef ARITH_OP #undef LOG_OP } }
static int parser_procedure() { if(lex_sym=="const") { lex_getsym(); if(!parser_constdeclaration()) { string testset[]={"","var","procedure","function","begin"}; parser_test(testset,5); if(lex_sym=="") { global_error("begin","nothing"); return 0; } } } { string testset[]={"","var","procedure","function","begin"}; int flag; parser_test(testset,5,flag); if(lex_sym=="") { global_error("begin","nothing"); return 0; } } if(lex_sym=="var") { lex_getsym(); if(!parser_vardeclaration()) { string testset[]={"","procedure","function","begin"}; parser_test(testset,4); if(lex_sym=="") { global_error("begin","nothing"); return 0; } } } { int flag; string testset[]={"","procedure","function","begin"}; parser_test(testset,4,flag); if(lex_sym=="") { global_error("begin","nothing"); return 0; } } while(lex_sym=="function"||lex_sym=="procedure") { string testset[]={"","procedure","function","begin"}; int flag=1; if(lex_sym=="function") { lex_getsym(); flag=parser_functiondeclaration(); } else { lex_getsym(); flag=parser_proceduredeclaration(); } if(!flag) { parser_test(testset,4); if(lex_sym=="") { global_error("begin","nothing"); return 0; } } } { int flag; string testset[]={"","begin"}; parser_test(testset,2,flag); if(lex_sym=="") { global_error("begin","nothing"); return 0; } } if(lex_sym!="begin") { global_error("begin","nothing"); return 0; } lex_getsym(); symbItem *func; if(symbtable_now->father) func=symbtable_now->father->last_item; else { func=new symbItem(); func->name="main"; func->kind="constpool"; func->type="lable"; func->link=NULL; global_const_pool.push(func); } func->adr=function_adr++; global_new_quadruple("func",func,NULL,NULL); if(!parser_compoundstatement()) return 0; global_new_quadruple("ret",func,NULL,NULL); symbtable_up_level(); #ifdef PARSER_DEBUG cout << "prcedure" << endl; #endif return 1; }
static int parser_statement(symbItem *forbid) { symbItem *tmp; if(lex_sym=="ident") { tmp=symbtable_check(lex_token); if(tmp==NULL) { global_error("legal ident",lex_token); return 0; } if(tmp==forbid)//该标识符不可以被赋值 { global_error("this ident\""+tmp->name+"\"can not be changed."); return 0; } if(tmp->kind=="const") { global_error(tmp->name+" can not be changed."); return 0; } else if(tmp->kind=="var"||tmp->kind=="parameter") { lex_getsym(); if(lex_sym==":="||lex_sym=="=") { if(lex_sym=="=") global_error(":=","="); } else { global_error(":=",lex_sym); return 0; } lex_getsym(); if(!parser_expression()) { return 0; } symbItem *expre=operand_stack.top(); operand_stack.pop(); if(expre->kind=="const") expre=parser_create_new_const(expre); if(tmp->type=="char"&&expre->type=="integer") { global_error("integer can not be asssigned to a char"); // mark_i=0; } global_new_quadruple("assign",expre,NULL,tmp); } else if(tmp->kind=="array") {//tmp [src1] symbItem *src2; lex_getsym(); if(lex_sym!="[") { global_error("[",lex_sym); return 0; } lex_getsym(); if(!parser_expression()) { string testset[]={"","]",":="}; parser_test(testset,3); if(lex_sym=="") { global_error("]","nothing"); return 0; } } else { src2=operand_stack.top(); operand_stack.pop(); if(src2->kind=="const") src2=parser_create_new_const(src2); } if(lex_sym!="]") { global_error("]",lex_sym); return 0; } lex_getsym(); if(lex_sym==":="||lex_sym=="=") { if(lex_sym=="=") global_error(":=",lex_sym); } else { global_error(":=",lex_sym); return 0; } lex_getsym(); if(!parser_expression()) return 0; symbItem *ans=operand_stack.top(); operand_stack.pop(); if(ans->kind=="const") ans=parser_create_new_const(ans); if(tmp->type=="char"&&ans->type=="integer") { global_error("integer can not be asssigned to a char"); } global_new_quadruple("sarray",tmp,src2,ans);//tmp[src2]=ans } else if(tmp->kind=="function")//函数标示符=表达式 {//函数标识符只能是本层函数或者他的父层函数 if(!symbtable_if_can_change_func(tmp->name)) { global_error("function \""+tmp->name+"\" can not be changed in this scope."); return 0; } lex_getsym(); if(lex_sym!="="&&lex_sym!=":=") { global_error(":=",lex_sym); return 0; } if(lex_sym=="=") global_error(":=",lex_sym); lex_getsym(); if(!parser_expression()) return 0; symbItem *src1=operand_stack.top(); operand_stack.pop(); if(src1&&src1->kind=="const") src1=parser_create_new_const(src1); if(src1->type=="integer"&&tmp->type=="char") global_error("integer can not be assigined to a char "); global_new_quadruple("assign",src1,NULL,tmp); } else if(tmp->kind=="procedure")//过程调用语句,tmp已经经过差表 { if(!tmp->size) { lex_getsym(); if(lex_sym=="(") { global_error("no parameter",lex_sym); return 0; } } else { lex_getsym(); if(!parser_realparameterlist(tmp)) return 0; } global_new_quadruple("call",tmp,NULL,NULL); } else { global_error("no possible."); return 0; } } else if(lex_sym=="if")// { symbItem *lable1,*lable2,*src1,*src2; string oprname; lable1=parser_create_new_lable(); lex_getsym(); if(!parser_condition(&src1,&src2,oprname)) { string testset[]={"","then","else"}; parser_test(testset,3); if(lex_sym=="") { global_error("then","nothing"); return 0; } } else { oprname=global_anti_ralation[oprname]; if(src1&&src1->kind=="const") src1=parser_create_new_const(src1); if(src2&&src2->kind=="const") src2=parser_create_new_const(src2); global_new_quadruple(oprname,src1,src2,lable1); } if(lex_sym!="then") { global_error("then",lex_sym);//容忍缺then的行为 } else lex_getsym(); if(!parser_statement(NULL)) { return 0;//???? } if(lex_sym!="else") { global_new_quadruple("lab",lable1,NULL,NULL); } else { lable2=parser_create_new_lable(); global_new_quadruple("jmp",lable2,NULL,NULL); global_new_quadruple("lab",lable1,NULL,NULL); lex_getsym(); if(!parser_statement(NULL)) return 0; global_new_quadruple("lab",lable2,NULL,NULL); } } else if(lex_sym=="begin") { lex_getsym(); if(!parser_compoundstatement()) return 0; } else if(lex_sym=="do") { symbItem *lable1=parser_create_new_lable(); symbItem *src1,*src2; string oprname; global_new_quadruple("lab",lable1,NULL,NULL); lex_getsym(); if(!parser_statement(NULL)) { string testset[]={"","while"}; parser_test(testset,2); if(lex_sym=="") { global_error("while","nothing"); return 0; } } if(lex_sym!="while") { global_error("while",lex_sym); return 0; } lex_getsym(); if(!parser_condition(&src1,&src2,oprname)) return 0; oprname=global_ralation[oprname]; if(src1&&src1->kind=="const") src1=parser_create_new_const(src1); if(src2&&src2->kind=="const") src2=parser_create_new_const(src2); global_new_quadruple(oprname,src1,src2,lable1); } else if(lex_sym=="write") { string testset[]={"",")"}; lex_getsym(); if(lex_sym!="(") { global_error("(",lex_sym); string testset2[]={"",")"}; parser_test(testset2,2); if(lex_sym=="") { global_error(")","nothing"); return 0; } } else lex_getsym(); if(lex_sym=="string") { symbItem *item=new symbItem(); item->name=lex_token; my_write_string.push(lex_token); item->value=my_writes_num++; item->kind="constpool"; item->type="string";//digit,char,string,lable item->link=NULL; global_const_pool.push(item); global_new_quadruple("writes",item,NULL,NULL); lex_getsym(); if(lex_sym==",") { lex_getsym(); if(!parser_expression()) { parser_test(testset,2); if(lex_sym=="") { global_error(")","nothing"); return 0; } } else { symbItem *src=operand_stack.top(); if(src->kind=="const") src=parser_create_new_const(src); global_new_quadruple("writee",src,NULL,NULL); operand_stack.pop(); } } } else//表达式 { if(!parser_expression()) { parser_test(testset,2); if(lex_sym=="") { global_error(")","nothing"); return 0; } } else { symbItem *src=operand_stack.top(); if(src->kind=="const") src=parser_create_new_const(src); global_new_quadruple("writee",src,NULL,NULL); operand_stack.pop(); } } if(lex_sym!=")") { global_error(")",lex_sym); return 0; } lex_getsym(); } else if(lex_sym=="read")//func,var,para? { lex_getsym(); int flag=0; if(lex_sym!="(") { global_error("(",lex_sym); return 0; } do{ lex_getsym(); if(lex_sym!="ident") { global_error("ident",lex_sym); flag=1; } else//"ident" { symbItem *ans=symbtable_check(lex_token); if(ans==NULL) { global_error(lex_token+" is not declared in this scope."); flag=1; } else { if(ans->kind=="const") { global_error("const \""+ans->name+"\" can not be changed"); flag=1; } else if(ans->kind=="procedure") { global_error("procedure \""+ans->name+"\" can not be changed"); flag=1; } else if(ans->kind=="function"&&!symbtable_if_can_change_func(ans->name)) { global_error("function \""+ans->name+"\" can not be changed in this scope."); flag=1; } else { global_new_quadruple("read",ans,NULL,NULL); } } } if(flag) { string testset[]={"",",",")"}; parser_test(testset,3); if(lex_sym=="") { global_error(")",lex_sym); return 0; } } else lex_getsym(); }while(lex_sym==","); if(lex_sym!=")") { global_error(")",lex_sym); return 0; } lex_getsym(); } else if(lex_sym=="for") { int downto=0; symbItem *tmp,*target,*lable1,*lable2; lex_getsym(); if(lex_sym!="ident") { global_error("ident",lex_sym); return 0; } tmp=symbtable_check(lex_token); int flag=0; if(tmp->kind=="const") { global_error("const \""+tmp->name+"\" can not be changed."); flag=1; } else if(tmp->kind=="procedure") { global_error("procedure \""+tmp->name+"\" can not be changed."); flag=1; } else { if(!parser_statement(NULL)) flag=1;//生成首次赋值语句。 } if(flag) { string testset[]={"","to","downto"}; parser_test(testset,3); if(lex_sym=="") { global_error("downto or to","nothing"); return 0; } } if(lex_sym!="downto"&&lex_sym!="to") { global_error("downto or to",lex_sym); return 0; } else downto=lex_sym=="downto"; lex_getsym(); if(!parser_expression()) { string testset[]={"","do"}; parser_test(testset,2); if(lex_sym=="") { global_error("do","nothing"); return 0; } } else { target=operand_stack.top(); operand_stack.pop(); if(target->kind=="const") target=parser_create_new_const(target); } if(lex_sym!="do") { global_error("do",lex_sym); // return 0; } lex_getsym(); lable1=parser_create_new_lable(); lable2=parser_create_new_lable(); global_new_quadruple("lab",lable1,NULL,NULL); string opr=downto?"jl":"jg"; global_new_quadruple(opr,tmp,target,lable2); if(!parser_statement(tmp)) return 0; opr=downto?"dec":"inc"; global_new_quadruple(opr,tmp,NULL,NULL); global_new_quadruple("jmp",lable1,NULL,NULL); global_new_quadruple("lab",lable2,NULL,NULL); } else { //空语句怎么处理,那就不处理好了? } #ifdef PARSER_DEBUG cout <<"语句"<< endl; #endif return 1; }
static int parser_formalparasection(int ¶_size) { int paraifvar=0; symbItem *start; string paratype; if(lex_sym=="var") { paraifvar=1; lex_getsym(); } if(lex_sym!="ident") { global_error("ident",lex_sym); return 0; } else { para_size++; if(!symbtable_enter(lex_token,"parameter","",0,paraifvar)) return 0; start=symbtable_now->last_item; lex_getsym(); while(lex_sym==",") { lex_getsym(); if(lex_sym!="ident") { global_error("ident",lex_sym); return 0; } else { para_size++; if(!symbtable_enter(lex_token,"parameter","",0,paraifvar)) return 0; lex_getsym(); } } if(lex_sym!=":") { global_error(":",lex_sym); return 0; } lex_getsym(); if(lex_sym!="integer"&&lex_sym!="char") { global_error("char or integer",lex_sym); return 0; } else { paratype=lex_sym; while(start!=NULL) { start->type=paratype; start=start->link; } lex_getsym(); } } #ifdef PARSER_DEBUG cout << "形式参数段" << endl; #endif return 1; }
static int parser_factor() { symbItem *operand; if(lex_sym=="ident") { operand=symbtable_check(lex_token); if(operand==NULL) { global_error("legal ident",lex_token); return 0; } if(operand->kind=="array") { parser_create_new_var(operand); symbItem *ans=symbtable_now->last_item,*src2; lex_getsym(); if(lex_sym!="[") { global_error("[",lex_sym); return 0; } lex_getsym(); if(!parser_expression()) { string testset[]={"","]"}; parser_test(testset,2); if(lex_sym=="") { global_error("]","nothing"); return 0; } } else{ src2=operand_stack.top(); operand_stack.pop(); if(src2->kind=="const") src2=parser_create_new_const(src2); } if(lex_sym!="]") { global_error("]",lex_sym); return 0; } if(ans->type=="char"&&operand->type=="integer") { global_error("integer can not be asssigned to a char"); } global_new_quadruple("larray",operand,src2,ans);//ans=operand[src2] operand_stack.push(ans); lex_getsym(); } else if(operand->kind=="function") { parser_create_new_var(operand->type); symbItem *ans=symbtable_now->last_item; lex_getsym(); if(lex_sym=="("&&!operand->size) { global_error("no parameter",lex_sym); return 0; } else if(operand->size) { if(!parser_realparameterlist(operand)) return 0; } global_new_quadruple("call",operand,NULL,NULL); global_new_quadruple("assign",operand,NULL,ans); operand_stack.push(ans); } else if(operand->kind=="procedure") { global_error("factor","procedure "+operand->name); return 0; } else { operand_stack.push(operand);//获得操作数 lex_getsym(); } } else if(lex_sym=="(") { lex_getsym(); if(!parser_expression()) { string testset[]={"",")"}; parser_test(testset,2); if(lex_sym=="") { global_error(")","nothing"); return 0; } } if(lex_sym!=")") { global_error(")",lex_sym); return 0; } lex_getsym(); } else if(lex_sym=="digit") { symbItem *item=new symbItem(); item->name=numtostring(lex_value); item->value=lex_value; item->kind="constpool"; item->type="integer";//digit,char,string,lable item->link=NULL; operand_stack.push(item); global_const_pool.push(item);//放到常量池里面 lex_getsym(); } else { global_error("legal factor",lex_sym); return 0; } #ifdef PARSER_DEBUG cout << "因子" << endl; #endif return 1; }
//Require: item is func or proc //暂时不跳读,因为,一行而已。。本身久错了 static int parser_realparameterlist(symbItem *func_proc) {//func后面一定要紧跟着参数信息,这是四元式中操作数的一部分,虽然你没用到他的值,但你用到的是他的其他信息; //need to find the location of func or proc stack<symbItem*> para_stack; symbItem *src; if(lex_sym!="(") { global_error("(",lex_sym); return 0; } do{ lex_getsym(); if(!parser_expression()) { string testset[]={"",",",")"}; parser_test(testset,3); if(lex_sym=="") { global_error(")","nothing"); return 0; } } else { para_stack.push(operand_stack.top()); operand_stack.pop(); } }while(lex_sym==","); if((unsigned)func_proc->size!=para_stack.size()) { global_error("wrong num of parametes in \""+func_proc->name+"\"call."); return 0; }//good,我是指针我怕谁 //require: enough para item in the global_table int j=func_proc->size; symbItem *k=func_proc->link; if(func_proc->name==symbtable_now->name)//调用自身此时符号表没调整。 k=symbtable_now->first_item; else if(j&&(k==NULL||k->kind!="parameter"))//这里子表没有撤回的情况有很多,不过一旦动用了这条分支,意味着死循环 { symbTable *tmp=symbtable_now; while(tmp->name!=func_proc->name) tmp=tmp->father; k=tmp->first_item; } int mark_i=0; stack<symbItem*> paras; symbItem *twx=k; for(int i=1;i<=j;i++) { paras.push(twx); twx=twx->link; } for(int i=1;i<=j;i++)//k是顺着来的而栈里的参数是反着来的。。 { src=para_stack.top(); para_stack.pop(); if(paras.top()->type=="char"&&src->type=="integer") { global_error("parameter type error:char","integer:"); mark_i=1; } if(paras.top()->para_ifvar&¶s.top()->type=="integer"&&src->type=="char") { global_error("real parameter type error,integer","char"); } paras.pop(); if(k->para_ifvar&&src->kind!="const")//可能撤表了也可能没撤 { if(src->kind=="var"&&src->name[0]=='_') { global_error("legal var parameter","expression"); mark_i=1; } else global_new_quadruple("rpara",src,func_proc,NULL); } else if(k->para_ifvar&&src->kind=="const") { global_error("legal var parameter","const"); mark_i=1; } else { if(src->kind=="const") src=parser_create_new_const(src); global_new_quadruple("fpara",src,func_proc,NULL); } if(k==NULL) cout << "are you kidding me!" <<endl; k=k->link;//Require k<>NULL; } if(lex_sym!=")") { global_error(")",lex_sym); return 0; } lex_getsym(); #ifdef PARSER_DEBUG cout << "实在参数表" << endl; #endif /* if(mark_i) return 0;*/ return 1; }
static int parser_proceduredeclaration() { int para_size=0; symbTable *start=symbtable_now; string procename; string testset[]={"",";"}; if(lex_sym!="ident") { global_error("ident",lex_sym); return 0; } else { if(!symbtable_enter(lex_token,"procedure","",0,0)) return 0; symbtable_new_level(lex_token); lex_getsym(); if(lex_sym!=";") { if(!parser_formalparalist(para_size)) { parser_test(testset,2); if(lex_sym=="") { global_error(";","nothing"); return 0; } } if(lex_sym!=";") { global_error(";",lex_sym); string testset[]={"","const","var","begin","function","procedure"}; parser_test(testset,6); if(lex_sym=="") { global_error("procedure\""+lex_token+"\" body expected."); return 0; } } else lex_getsym(); } else lex_getsym(); start->last_item->size=para_size; } if(!parser_procedure()) { string testset[]={"",";"}; parser_test(testset,2); if(lex_sym=="") { global_error(";","nothing"); return 0; } } if(lex_sym!=";") { global_error(";",lex_sym); return 0; } lex_getsym(); #ifdef PARSER_DEBUG cout << "过程声明" << endl; #endif return 1; }
static int parser_functiondeclaration() { int para_size=0; symbTable *start=symbtable_now; string testset[]={"",":"}; string functype; if(lex_sym!="ident") { global_error("ident",lex_sym); return 0; } else { if(!symbtable_enter(lex_token,"function","",0,0)) return 0; symbtable_new_level(lex_token); lex_getsym(); if(lex_sym!=":") { if(!parser_formalparalist(para_size)) { parser_test(testset,2); if(lex_sym=="") { global_error(":","nothing"); return 0; } } if(lex_sym!=":") { global_error(":","nothing"); return 0; } } lex_getsym(); if(lex_sym!="char"&&lex_sym!="integer") { global_error("char or integer",lex_sym); return 0; } functype=lex_sym; lex_getsym(); start->last_item->size=para_size;//那是上一层的需要反填的东西。 start->last_item->type=functype; if(lex_sym!=";") { global_error(";",lex_sym); string testset[]={"","begin","const","var","begin","function","procedure"}; parser_test(testset,6); if(lex_sym=="") { global_error("begin","nothing"); return 0; } } else lex_getsym(); } if(!parser_procedure()) { string testset[]={"",";"}; parser_test(testset,2); if(lex_sym!="") { global_error(";","nothing"); return 0; } } if(lex_sym!=";") { global_error(";",lex_sym); return 0; } else lex_getsym(); #ifdef PARSER_DEBUG cout << "函数声明" << endl; #endif return 1; }
static int parser_constdefinition()//常量定义 { if(lex_sym=="ident") { string constname=lex_token; lex_getsym(); if(lex_sym=="="||lex_sym==":=") { if(lex_sym==":=") { global_error("=",":=");//是=不是:= } lex_getsym(); if(lex_sym=="char") { if(!symbtable_enter(constname,"const","char",lex_value,0)) return 0; lex_getsym(); } else if(lex_sym=="+"||lex_sym=="-") { int mark=lex_sym=="-"?-1:1; lex_getsym(); if(lex_sym=="digit") { if(!symbtable_enter(constname,"const","integer",lex_value*mark,0)) return 0; lex_getsym(); } else { global_error("digit",lex_sym);//+-后面应该是数字 return 0; } } else if(lex_sym=="digit") { if(!symbtable_enter(constname,"const","integer",lex_value,0)) return 0; lex_getsym(); } else { global_error("const's value",lex_sym);//常量都没定义明白就不填表了。 return 0; } } else { global_error("=",lex_sym);//标识符后面是= return 0; } } else { global_error("ident",lex_sym);//常量定义开头是标识符 return 0; } #ifdef PARSER_DEBUG cout << "常量定义" << endl; #endif return 1; }
static int parser_vardefinition() { int size=0; symbItem *start; string consttype; if(lex_sym=="ident") { if(!symbtable_enter(lex_token,"var","",0,0)) return 0; start=symbtable_now->last_item; lex_getsym(); while(lex_sym==",") { lex_getsym(); if(lex_sym!="ident") { global_error("ident",lex_sym); return 0; } else { if(!symbtable_enter(lex_token,"var","",0,0)) return 0; lex_getsym(); } } if(lex_sym!=":") { global_error(":",lex_sym); return 0; } lex_getsym(); if(lex_sym=="integer"||lex_sym=="char") consttype=lex_sym; else { if(lex_sym=="array") { if_array=1; lex_getsym(); if(lex_sym!="[") { global_error("[",lex_sym); if_array=0; return 0; } else lex_getsym(); if(lex_sym!="digit") { if_array=0; global_error("digit",lex_sym); return 0; } size=lex_value; lex_getsym(); if(lex_sym!="]") { if_array=0; global_error("]",lex_sym); return 0; } else lex_getsym(); if(lex_sym!="of") { global_error("of",lex_sym); } else lex_getsym(); if(lex_sym=="integer"||lex_sym=="char")//这里你调试了很久 consttype=lex_sym; else { global_error("integer or char",lex_sym); if_array=0; return 0; } } else//!array,!integer,!char { global_error("type",lex_sym); return 0; } } while(start!=NULL) { start->type=consttype; start->size=size; if(if_array) { start->kind="array"; } start=start->link; } if_array=0; lex_getsym(); } else { global_error("ident",lex_sym);//变量定义开头是标识符 return 0; } #ifdef PARSER_DEBUG cout << "变量定义" << endl; #endif return 1; }