//<常量定义> ::= <标识符>=<无符号整数> public void decconst() { Error er = compiler.error; symbol_table st = compiler.st; if (sym == symlist.iden) { getsym(); if (sym == symlist.equality || sym == symlist.becomes) { if (sym == symlist.becomes) { er.adderror(1); } getsym(); if (sym == symlist.number) { st.add(symlist.constsym); //加入符号表 getsym(); } else//常数声明标识符后不是数字 { er.adderror(2); } } else//不是等号 { er.adderror(3); } } else //不是标识符 { er.adderror(4); } }
public Compiler(string path) { source = path; la = new lexical_analysis(this); sa = new syntax_Analysis(this); st = new symbol_table(this); error = new Error(this); pc = new Pcode(); }
//<变量说明部分>::= var<标识符>{,<标识符>}; public void decvar() { Error er = compiler.error; symbol_table st = compiler.st; if (sym == symlist.iden) { st.add(symlist.varsym); //加入符号表 dx[level]++; //分配地址 getsym(); } else//不是标识符 { er.adderror(4); } }
//<因子> ::= <标识符>|<无符号整数>|'('<表达式>')' public void factor(List <symlist> followlst) { Pcode pc = compiler.pc; List <symlist> nextlst = new List <symlist>(); symbol_table st = compiler.st; lexical_analysis la = compiler.la; Error er = compiler.error; int index; nextlst.AddRange(factorSymSet); check(nextlst, followlst, 24); while (factorSymSet.Contains(sym)) { if (sym == symlist.iden) { index = st.position(la.word); if (index == -1) { er.adderror(11); } else { record re = st.stable[index]; string kind = re.kind; if (kind == "constant") { pc.gen("LIT", 0, re.val); } else if (kind == "variable") { int l = level - re.level; int a = re.adr; pc.gen("LOD", l, a); } else { er.adderror(21); } } getsym(); } else if (sym == symlist.number) { pc.gen("LIT", 0, la.num); getsym(); } else if (sym == symlist.LParenthesis) { getsym(); followlst.Add(symlist.RParenthesis); expression(followlst); if (sym == symlist.RParenthesis) { getsym(); } else { er.adderror(22); } //error } check(followlst, factorSymSet, 23); } }
//<语句> ::= <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<重复语句>|<空> public void statement(List <symlist> followlst) { Error er = compiler.error; symbol_table st = compiler.st; lexical_analysis la = compiler.la; Pcode pc = compiler.pc; List <symlist> nextlst = new List <symlist>(); List <symlist> n2 = new List <symlist>(); int index, cx1, cx2; switch (sym) { //<赋值语句> ::= <标识符>:=<表达式> case symlist.iden: index = st.position(la.word); if (index == -1) //未声明 { er.adderror(11); } else if (st.stable[index].kind != "variable") { er.adderror(12); index = -1; } getsym(); if (sym == symlist.becomes) { getsym(); } else //不是:= { er.adderror(13); } expression(followlst); if (index != -1) //生成pcode { int l = level - st.stable[index].level; int a = st.stable[index].adr; pc.gen("STO", l, a); } break; //<过程调用语句>::=call<标识符> case symlist.callsym: getsym(); if (sym == symlist.iden) { index = st.position(la.word); if (index == -1) { er.adderror(11); } else if (st.stable[index].kind != "procedure") { index = -1; er.adderror(15); } else //生成pcode { int l = level - st.stable[index].level; int a = st.stable[index].adr; pc.gen("CAL", l, a); } getsym(); } else { er.adderror(14); } break; //<复合语句> ::= begin<语句>{;<语句>}end case symlist.beginsym: getsym(); nextlst.Clear(); nextlst.AddRange(followlst); n2.Clear(); n2.AddRange(stateSymSet); n2.Add(symlist.semicolon); statement(nextlst); while (n2.Contains(sym)) { if (sym == symlist.semicolon) { getsym(); } else { er.adderror(10); } statement(nextlst); } if (sym == symlist.endsym) { getsym(); } else //少了end { er.adderror(17); } break; //<条件语句> ::= if<条件>then<语句>[else<语句>] case symlist.ifsym: getsym(); nextlst.Clear(); nextlst.AddRange(followlst); nextlst.Add(symlist.thensym); nextlst.Add(symlist.dosym); ifstatement(nextlst); if (sym == symlist.thensym) { getsym(); } else { er.adderror(16); } cx1 = pc.cx; pc.gen("JPC", 0, 0); nextlst.Clear(); nextlst.AddRange(followlst); nextlst.Add(symlist.elsesym); statement(nextlst); if (sym == symlist.elsesym) { getsym(); cx2 = pc.cx; pc.gen("JMP", 0, 0); statement(followlst); pc.pcdeolst[cx1].a = cx2 + 1; pc.pcdeolst[cx2].a = pc.cx; } else { pc.pcdeolst[cx1].a = pc.cx; } break; // <当型循环语句 > ::= while< 条件 >do< 语句 > case symlist.whilesym: cx1 = pc.cx; getsym(); nextlst.Clear(); nextlst.AddRange(followlst); nextlst.Add(symlist.dosym); ifstatement(nextlst); cx2 = pc.cx; pc.gen("JPC", 0, 0); if (sym == symlist.dosym) { getsym(); } else { er.adderror(18); //error } statement(followlst); pc.gen("JMP", 0, cx1); pc.pcdeolst[cx2].a = pc.cx; break; //<读语句> ::= read'('<标识符>{,<标识符>}')' case symlist.readsym: getsym(); if (sym == symlist.LParenthesis) { do { getsym(); if (sym == symlist.iden) { index = st.position(la.word); } else { index = -1; er.adderror(32); //error } if (index > 0 && st.stable[index].kind != "variable") { getsym(); er.adderror(32); } else if (sym == symlist.RParenthesis || sym == symlist.semicolon) { er.adderror(35); getsym(); } else { int l = level - st.stable[index].level; int a = st.stable[index].adr; pc.gen("RED", l, a); getsym(); } } while (sym == symlist.comma); } else { er.adderror(33); } //error if (sym == symlist.RParenthesis) { getsym(); } else { er.adderror(34); while (!followlst.Contains(sym)) { getsym(); } } break; //<写语句> ::= write'('<标识符>{,<标识符>}')' case symlist.writesym: getsym(); nextlst.Clear(); nextlst.AddRange(followlst); nextlst.Add(symlist.RParenthesis); nextlst.Add(symlist.comma); if (sym == symlist.LParenthesis) { do { getsym(); expression(nextlst); pc.gen("WRT", 0, 0); } while (sym == symlist.comma); if (sym == symlist.RParenthesis) { getsym(); } else { er.adderror(34); } //error } else { er.adderror(33); } //error break; //<重复语句> ::= repeat<语句>{;<语句>}until<条件> case symlist.repeatsym: getsym(); nextlst.Clear(); nextlst.AddRange(followlst); nextlst.Add(symlist.untilsym); cx1 = pc.cx; statement(nextlst); n2.Clear(); n2.AddRange(stateSymSet); n2.Add(symlist.semicolon); while (n2.Contains(sym)) { if (sym == symlist.semicolon) { getsym(); } else { er.adderror(10); } //error} statement(nextlst); } if (sym == symlist.untilsym) { getsym(); ifstatement(followlst); pc.gen("JPC", 0, cx1); } else { er.adderror(25); } //error break; } check(followlst, new List <symlist>(), 19); }
//<分程序>::=[<常量说明部分>][变量说明部分>][<过程说明部分>]<语句> public void subprogram(List <symlist> followlst) { //int point = compiler.st.point; //int pi = compiler.st.dx[point]; List <symlist> nextlst = new List <symlist>(); symbol_table st = compiler.st; Pcode pcode = compiler.pc; Error er = compiler.error; int ti, ch; level++; dx[level] = 3; ti = st.dx[st.point]; st.stable[ti].adr = pcode.cx; pcode.gen("JMP", 0, 0); //判断是否分程序的层次超过最大层数3 if (level > 3) { er.adderror(26); } do { //<常量说明部分> ::= const<常量定义>{,<常量定义>}; if (sym == symlist.constsym) { do { getsym(); decconst(); } while (sym == symlist.comma); if (sym == symlist.semicolon) { getsym(); } else//少了一个分号 { er.adderror(5); } } //<变量说明部分>::= var<标识符>{,<标识符>}; if (sym == symlist.varsym) { do { getsym(); decvar(); } while (sym == symlist.comma); if (sym == symlist.semicolon) { getsym(); } else//少了一个分号 { er.adderror(5); } } //<过程说明部分> ::= <过程首部><分程序>;{<过程说明部分>} //<过程首部> ::= procedure<标识符>; while (sym == symlist.proceduresym) { getsym(); if (sym == symlist.iden) { st.add(symlist.proceduresym);//加入符号表 getsym(); } else//不是标识符 { er.adderror(4); } if (sym == symlist.semicolon) { getsym(); } else { er.adderror(5); } nextlst.AddRange(followlst); nextlst.Add(symlist.semicolon); subprogram(nextlst); if (sym == symlist.semicolon) { getsym(); nextlst.Clear(); nextlst.AddRange(followlst); nextlst.Add(symlist.iden); nextlst.Add(symlist.proceduresym); check(nextlst, followlst, 6); } else { er.adderror(5); } } nextlst.Clear(); nextlst.AddRange(stateSymSet); nextlst.Add(symlist.iden); check(nextlst, declareSymSet, 7); } while (declareSymSet.Contains(sym)); pcode.pcdeolst[st.stable[ti].adr].a = pcode.cx; st.stable[ti].adr = pcode.cx; st.stable[ti].size = dx[level]; ch = pcode.cx; pcode.gen("INT", 0, dx[level]); nextlst.Clear(); nextlst.AddRange(followlst); nextlst.Add(symlist.semicolon); nextlst.Add(symlist.endsym); statement(nextlst); pcode.gen("OPR", 0, 0); check(nextlst, new List <symlist>(), 8); level--; int point = compiler.st.point; if (level < point) { if (point > 0) { int delnum = compiler.st.dx[point] - compiler.st.dx[point - 1]; for (int i = 0; i < delnum; i++) { compiler.st.stable.RemoveAt(compiler.st.stable.Count - 1); } compiler.st.point--; } } //compiler.st.point = point; //compiler.st.dx[compiler.st.point] = pi; }