/// <summary> /// 错误探测 /// </summary> /// <param name="sBeg">开始符号集</param> /// <param name="sEnd">后继符号集</param> /// <param name="errorNum">错误编号</param> public void ErrorTest(SymbolSet sBeg, SymbolSet sEnd, int errorNum) { if (!sBeg.isInSet(sym) && sym != symbol.endfile) { compiler.EH.adderr(errorNum); sBeg.AddRange(sEnd.SymSet); while (!sBeg.isInSet(sym) && sym != symbol.endfile) { getsym(); } } }
/// <summary> /// 因子模块 /// </summary> /// <param name="factSym">开始与后继符号集</param> private void factor(SymbolSet factSym) { int i; ErrorHandle err = compiler.EH; SymbolTable table = compiler.ST; PCodeGenetate pCode = compiler.PCG; SymbolSet sfb = new SymbolSet(); sfb.AddRange(factorbegs.SymSet); ErrorTest(sfb, factSym, 24); while (factorbegs.isInSet(sym)) { switch (sym) { case symbol.ident: i = table.getPosition(compiler.SA.tname); if (i == 0) { err.adderr(11); } else { SymTabItem STI = table.SymTable[i]; switch (STI.kind) { case ObjectK.constant: pCode.Gen(oprCode.lit, 0, STI.value); break; case ObjectK.variable: int fa = level - STI.level; int la = STI.address; pCode.Gen(oprCode.lod, fa, la); break; case ObjectK.procedure: err.adderr(21); break; } } getsym(); break; case symbol.number: pCode.Gen(oprCode.lit, 0, compiler.SA.tnumber); getsym(); break; case symbol.LParenthesis: getsym(); factSym.Add(symbol.RParenthesis); expression(factSym); if (sym == symbol.RParenthesis) { getsym(); } else { err.adderr(22); } break; } ErrorTest(factSym, factorbegs, 23); } }
/// <summary> /// 语句模块 /// </summary> /// <param name="stateSym">开始与后继符号集</param> private void statement(SymbolSet stateSym) { SymbolTable table = compiler.ST; ErrorHandle err = compiler.EH; PCodeGenetate pCode = compiler.PCG; SymbolSet s = new SymbolSet(), s1 = new SymbolSet(); int i, cx1, cx2; switch (sym) { case symbol.ident: i = table.getPosition(compiler.SA.tname); if (i == 0) { err.adderr(11); } else if (table.SymTable[i].kind != ObjectK.variable) { err.adderr(12); i = 0; } getsym(); if (sym == symbol.becomes) { getsym(); } else { err.adderr(13); } expression(stateSym); if (i > 0) { int fa = level - table.SymTable[i].level; int la = table.SymTable[i].address; pCode.Gen(oprCode.sto, fa, la); } break; case symbol.readSym: getsym(); if (sym != symbol.LParenthesis) { err.adderr(33); } else { do { getsym(); if (sym == symbol.ident) { i = table.getPosition(compiler.SA.tname); } else { i = 0; } if (i == 0 || table.SymTable[i].kind != ObjectK.variable) { err.adderr(32); getsym(); } else if (i == 0 && (sym == symbol.RParenthesis || sym == symbol.semicolon)) { err.adderr(35); } else { pCode.Gen(oprCode.opr, 0, 16); int fa, la; fa = level - table.SymTable[i].level; la = table.SymTable[i].address; pCode.Gen(oprCode.sto, fa, la); getsym(); } }while(sym == symbol.comma); } if (sym != symbol.RParenthesis) { err.adderr(34); while (!stateSym.isInSet(sym)) { getsym(); } } else { getsym(); } break; case symbol.writeSym: s.Clear(); s.AddRange(stateSym.SymSet); s.Add(symbol.RParenthesis); s.Add(symbol.comma); getsym(); if (sym == symbol.LParenthesis) { do { getsym(); expression(s); pCode.Gen(oprCode.opr, 0, 14); } while (sym == symbol.comma); if (sym != symbol.RParenthesis) { err.adderr(34); } else { getsym(); } } pCode.Gen(oprCode.opr, 0, 15); break; case symbol.callSym: getsym(); if (sym != symbol.ident) { err.adderr(14); } else { i = table.getPosition(compiler.SA.tname); if (i == 0) { err.adderr(11); } else if (table.SymTable[i].kind == ObjectK.procedure) { int fa = level - table.SymTable[i].level; int la = table.SymTable[i].address; pCode.Gen(oprCode.cal, fa, la); } else { err.adderr(15); } getsym(); } break; case symbol.whileSym: cx1 = pCode.cx; getsym(); s.Clear(); s.AddRange(stateSym.SymSet); s.Add(symbol.doSym); condition(s); cx2 = pCode.cx; pCode.Gen(oprCode.jpc, 0, 0); if (sym == symbol.doSym) { getsym(); } else { err.adderr(18); } statement(stateSym); pCode.Gen(oprCode.jmp, 0, cx1); pCode.code[cx2].la = pCode.cx; break; case symbol.repeatSym: getsym(); s.Clear(); s.AddRange(stateSym.SymSet); s.Add(symbol.untilSym); cx1 = pCode.cx; statement(s); s1.Clear(); s1.AddRange(statementbegs.SymSet); s1.Add(symbol.semicolon); while (s1.isInSet(sym)) { if (sym == symbol.semicolon) { getsym(); } else { err.adderr(10); } statement(s); } if (sym == symbol.untilSym) { getsym(); condition(stateSym); pCode.Gen(oprCode.jpc, 0, cx1); } else { err.adderr(25); } break; case symbol.ifSym: s.Clear(); s.AddRange(stateSym.SymSet); s.Add(symbol.thenSym); s.Add(symbol.doSym); getsym(); condition(s); if (sym == symbol.thenSym) { getsym(); } else { err.adderr(16); } cx1 = pCode.cx; pCode.Gen(oprCode.jpc, 0, 0); s.Clear(); s.AddRange(stateSym.SymSet); s.Add(symbol.elseSym); statement(s); if (sym == symbol.elseSym) { getsym(); cx2 = pCode.cx; pCode.Gen(oprCode.jmp, 0, 0); statement(stateSym); pCode.code[cx1].la = cx2 + 1; pCode.code[cx2].la = pCode.cx; } else { pCode.code[cx1].la = pCode.cx; } break; case symbol.beginSym: s.Clear(); s.AddRange(stateSym.SymSet); s1.Clear(); s1.AddRange(statementbegs.SymSet); s1.Add(symbol.semicolon); getsym(); statement(s); while (s1.isInSet(sym)) { if (sym == symbol.semicolon) { getsym(); } else { err.adderr(10); } statement(s); } if (sym == symbol.endSym) { getsym(); } else { err.adderr(17); } break; } ErrorTest(stateSym, new SymbolSet(), 19); }
/// <summary> /// 条件模块 /// </summary> /// <param name="condiSym">开始与后继符号集</param> private void condition(SymbolSet condiSym) { ErrorHandle err = compiler.EH; PCodeGenetate pCode = compiler.PCG; symbol relsym; SymbolSet s = new SymbolSet(), s1 = new SymbolSet(); s.Add(symbol.equality); s.Add(symbol.inequality); s.Add(symbol.LessThan); s.Add(symbol.LessThanE); s.Add(symbol.MoreThan); s.Add(symbol.MoreThanE); if (sym == symbol.oddSym) { getsym(); expression(condiSym); pCode.Gen(oprCode.opr, 0, 6); } else { s1.AddRange(s.SymSet); s1.AddRange(condiSym.SymSet); expression(s1); if (!s.isInSet(sym)) { err.adderr(20); } else { relsym = sym; getsym(); expression(condiSym); switch (relsym) { case symbol.equality: pCode.Gen(oprCode.opr, 0, 8); break; case symbol.inequality: pCode.Gen(oprCode.opr, 0, 9); break; case symbol.LessThan: pCode.Gen(oprCode.opr, 0, 10); break; case symbol.LessThanE: pCode.Gen(oprCode.opr, 0, 13); break; case symbol.MoreThan: pCode.Gen(oprCode.opr, 0, 11); break; case symbol.MoreThanE: pCode.Gen(oprCode.opr, 0, 12); break; } } } }
/// <summary> /// 分程序模块 /// </summary> /// <param name="bSym"></param> private void block(SymbolSet bSym) { level++; int txThis, cxThis; SymbolSet s = new SymbolSet(); ErrorHandle err = compiler.EH; SymbolTable table = compiler.ST; PCodeGenetate pCode = compiler.PCG; dx[level] = 3; txThis = table.tableIndex(); table.SymTable[txThis].address = pCode.cx; pCode.Gen(oprCode.jmp, 0, 0); if (level > (int)constnum.MAX_LEVEL) { err.adderr(26); } do { if (sym == symbol.constSym) { getsym(); do { constDeclare(); while (sym == symbol.comma) { getsym(); constDeclare(); } if (sym == symbol.semicolon) { getsym(); } else { err.adderr(5); } }while(sym == symbol.ident); } if (sym == symbol.varSym) { getsym(); do { varDeclare(); while (sym == symbol.comma) { getsym(); varDeclare(); } if (sym == symbol.semicolon) { getsym(); } else { err.adderr(5); } }while(sym == symbol.ident); } while (sym == symbol.procedureSym) //这个过程的标识符加到当前的符号表里,加完后,lev++,再新建一个符号表1,这个符号表1入栈()这些都在最开始做 { //过程内的声明变量、常量、过程、放在新建的符号表1里 getsym(); if (sym == symbol.ident) { table.Enter(ObjectK.procedure); getsym(); } else { err.adderr(4); } if (sym == symbol.semicolon) { getsym(); } else { err.adderr(5); } s.AddRange(bSym.SymSet); s.Add(symbol.semicolon); block(s); if (sym == symbol.semicolon) { //这里是过程的结尾,栈顶符号表退栈(lev--) getsym();//别删 s.Clear(); s.AddRange(statementbegs.SymSet); s.Add(symbol.ident); s.Add(symbol.procedureSym); ErrorTest(s, bSym, 6); } else { err.adderr(5); } } s.Clear(); s.AddRange(statementbegs.SymSet); s.Add(symbol.ident); ErrorTest(s, declarebegs, 7); } while (declarebegs.isInSet(sym)); int ad = table.SymTable[txThis].address; (pCode.code[ad]).la = pCode.cx; table.SymTable[txThis].address = pCode.cx; table.SymTable[txThis].size = dx[level]; cxThis = pCode.cx; pCode.Gen(oprCode.Int, 0, dx[level]); s.Clear(); s.AddRange(bSym.SymSet); s.Add(symbol.semicolon); s.Add(symbol.endSym); statement(s); pCode.Gen(oprCode.opr, 0, 0); ErrorTest(s, new SymbolSet(), 8); table.Exit(); level--; }