/// <summary> /// 常数声明模块 /// </summary> private void constDeclare() { SymbolTable table = compiler.ST; ErrorHandle err = compiler.EH; if (sym == symbol.ident) { getsym(); if (sym == symbol.equality || sym == symbol.becomes) { if (sym == symbol.becomes) { err.adderr(1); } getsym(); if (sym == symbol.number) { table.Enter(ObjectK.constant); getsym(); } else { err.adderr(2); } } else { err.adderr(3); } } else { err.adderr(4); } }
/// <summary> /// 构造函数 /// </summary> public PL0Compiler(string path) { try { source = new FileStream(path, FileMode.Open); SA = new SymbolAnalysis(this); ST = new SymbolTable(this); EH = new ErrorHandle(this); GSA = new GrammarAndSemanticAna(this); PCG = new PCodeGenetate(); } catch (IOException e) { Console.WriteLine(e.Message); source = null; SA = null; ST = null; EH = null; GSA = null; PCG = null; } finally { } }
/// <summary> /// 变量声明模块 /// </summary> private void varDeclare() { SymbolTable table = compiler.ST; ErrorHandle err = compiler.EH; if (sym == symbol.ident) { table.Enter(ObjectK.variable); dx[level]++; getsym(); } else { err.adderr(4); } }
/// <summary> /// 程序模块 /// </summary> /// <param name="progSym"></param> private void program(SymbolSet progSym) { ErrorHandle err = compiler.EH; block(progSym); if (sym == symbol.period) { while (sym != symbol.endfile) { getsym(); if ((int)sym >= 0) { err.adderr(36); } } } else { err.adderr(9); } compiler.source.Close(); }
/// <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="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="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="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--; }
/// <summary> /// 获取单词 /// </summary> /// <returns></returns> public symbol getSymbol() { ErrorHandle error = compiler.EH; int maxVarLen = (int)constnum.MAX_VAR_LEN; symbol sym; int k, p, num; LSymLine = lineNum; while (ch == (int)' ' || ch == (int)'\r' || ch == (int)'\n' || ch == (int)'\t') { if (ch == (int)'\n') { lineNum++; } ch = sourceCode.Read(); } //读取标识符 if ((ch >= (int)'a' && ch <= (int)'z') || (ch >= (int)'A' && ch <= (int)'Z')) { k = 0; List <char> name = new List <char>(); do { if (k < maxVarLen) { name.Add((char)ch); } k++; ch = sourceCode.Read(); } while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')); tname = new string(name.ToArray()); p = isReserved(tname); if (p >= 0) { symbol_reserved sr = (symbol_reserved)(reservedSym[p]); sym = sr.sym; } else { sym = symbol.ident; } } //读取数字 else if ((ch >= (int)'0' && ch <= (int)'9')) { k = 0; num = 0; sym = symbol.number; do { num = num * 10 + (ch - (int)'0'); k++; ch = sourceCode.Read(); } while ((ch >= (int)'0' && ch <= (int)'9')); if (k > (int)constnum.MAX_INT_LEN) { error.adderr(30); } if (num > (int)constnum.MAX_INT) { error.adderr(31); num = 0; } tnumber = num; } //读取其他 else if (ch == (int)':') { ch = sourceCode.Read(); if (ch == (int)'=') { sym = symbol.becomes; ch = sourceCode.Read(); } else { sym = symbol.nul; } } else if (ch == (int)'>') { ch = sourceCode.Read(); if (ch == (int)'=') { sym = symbol.MoreThanE; ch = sourceCode.Read(); } else { sym = symbol.MoreThan; } } else if (ch == (int)'<') { ch = sourceCode.Read(); if (ch == (int)'=') { sym = symbol.LessThanE; ch = sourceCode.Read(); } else if (ch == (int)'>') { sym = symbol.inequality; ch = sourceCode.Read(); } else { sym = symbol.LessThan; } } else { switch (ch) { case (int)'+': sym = symbol.plus; break; case '-': sym = symbol.minus; break; case (int)'*': sym = symbol.times; break; case (int)'/': sym = symbol.division; break; case (int)'(': sym = symbol.LParenthesis; break; case (int)')': sym = symbol.RParenthesis; break; case (int)';': sym = symbol.semicolon; break; case (int)',': sym = symbol.comma; break; case (int)'.': sym = symbol.period; break; //case (int)'#': sym = symbol.inequality; // break; case (int)'=': sym = symbol.equality; break; case -1: sym = symbol.endfile; break; default: sym = symbol.nul; break; } ch = sourceCode.Read(); } return(sym); }