📄 parse.java
字号:
import java.io.*;import java.util.*;public class Parse implements LineRead { static final int levelMax = 3; static final int amax = 2047; PrintWriter outFile; Scan scanner; Symbol sym; int errcnt; /* 错误计数器 */ CodeSegment code; /* 存放虚拟机代码 */ ArrayList symTable; /* 名字表 */ HashSet declarationBegin, statementBegin, factorBegin, relops; int level; Parse() { HashSet hs; /* 设置声明开始符号集 */ hs = declarationBegin = new HashSet(); hs.add(new Integer(Symbol.constsym)); hs.add(new Integer(Symbol.varsym)); hs.add(new Integer(Symbol.procsym)); /* 设置语句开始符号集 */ hs = statementBegin = new HashSet(); hs.add(new Integer(Symbol.beginsym)); hs.add(new Integer(Symbol.callsym)); hs.add(new Integer(Symbol.ifsym)); hs.add(new Integer(Symbol.whilesym)); /* 设置因子开始符号集 */ hs = factorBegin = new HashSet(); hs.add(new Integer(Symbol.ident)); hs.add(new Integer(Symbol.number)); hs.add(new Integer(Symbol.lparen)); /* 设置关系运算符号集 */ hs = relops = new HashSet(); hs.add(new Integer(Symbol.eql)); hs.add(new Integer(Symbol.neq)); hs.add(new Integer(Symbol.lss)); hs.add(new Integer(Symbol.gtr)); hs.add(new Integer(Symbol.leq)); hs.add(new Integer(Symbol.geq)); } CodeSegment doScan(BufferedReader br, PrintWriter pw) { scanner = new Scan(br, this); outFile = pw; code = new CodeSegment(); symTable = new ArrayList(); errcnt = 0; try { getSym(); HashSet hs = new HashSet(declarationBegin); hs.addAll(statementBegin); hs.add(new Integer(Symbol.period)); PLobject plo = new PLobject("__main__", PLobject.PLprocedure); symTable.add(plo); level = 0; block(plo, hs); if (sym.symtype != Symbol.period) { error(9); } } catch (IOException ioe) { System.out.println("IO Error---program probably incomplete"); outFile.println("IO Error---program probably incomplete"); return null; } return errcnt == 0 ? code : null; } void block(PLobject thisBlock, HashSet followSet) throws IOException { int dataIndex; HashSet hs; int symSizeOnEntry = symTable.size(); thisBlock.adr = code.nextInstrAdr(); dataIndex = CodeSegment.frameSize; code.gen(CodeSegment.jmp, 0, 0); if (level > levelMax) { error(32); } do { /* 收到常量声明符号,开始处理常量声明 */ if (sym.symtype == Symbol.constsym) { getSym(); // the original do...while(sym.symtype == Symbol.ident) is problematic, thanks to calculous // do { constDeclaration(); while (sym.symtype == Symbol.comma) { getSym(); constDeclaration(); } if (sym.symtype == Symbol.semicolon) { getSym(); } else { error(5); /*漏掉了逗号或者分号*/ } // } while (sym.symtype == Symbol.ident); } /* 收到变量声明符号,开始处理变量声明 */ if (sym.symtype == Symbol.varsym) { getSym(); // the original do...while(sym == ident) is problematic, thanks to calculous // do { dataIndex = varDeclaration(dataIndex); while (sym.symtype == Symbol.comma) { getSym(); dataIndex = varDeclaration(dataIndex); } if (sym.symtype == Symbol.semicolon) { getSym(); } else { error(5); } // } while (sym.symtype == Symbol.ident); } /* 收到过程声明符号,开始处理过程声明 */ while (sym.symtype == Symbol.procsym) { PLobject proc; getSym(); if (sym.symtype == Symbol.ident) { proc = new PLobject(sym.id, PLobject.PLprocedure, level, 0); getSym(); } else { proc = new PLobject("", PLobject.PLprocedure, level, 0); error(4); /* procedure后应为标识符 */ } symTable.add(proc); if (sym.symtype == Symbol.semicolon) { getSym(); } else { error(5); } /* 递归调用 */ hs = new HashSet(followSet); hs.add(new Integer(Symbol.semicolon)); level++; block(proc, hs); level--; if (sym.symtype == Symbol.semicolon) { getSym(); hs = new HashSet(statementBegin); hs.add(new Integer(Symbol.ident)); hs.add(new Integer(Symbol.procsym)); test(hs, followSet, 6); } else { error(5); } } hs = new HashSet(statementBegin); hs.add(new Integer(Symbol.ident)); test(hs, declarationBegin, 7); } while (declarationBegin.contains(new Integer(sym.symtype))); int blockStartAdr = code.nextInstrAdr(); code.setAddrField(thisBlock.adr, blockStartAdr); thisBlock.adr = blockStartAdr; code.gen(CodeSegment.inct, 0, dataIndex); /* 语句后跟符号为分号或end */ hs = new HashSet(followSet); hs.add(new Integer(Symbol.semicolon)); hs.add(new Integer(Symbol.endsym)); statement(hs); code.gen(CodeSegment.opr, 0, CodeSegment.opReturn); test(followSet, new HashSet(), 8); code.list(outFile, blockStartAdr, code.nextInstrAdr()-1); for (int i=symTable.size(); i!=symSizeOnEntry; i--) { symTable.remove(i-1); } } void constDeclaration() throws IOException { if (sym.symtype == Symbol.ident) { String name = sym.id; getSym(); if (sym.symtype == Symbol.eql || sym.symtype == Symbol.becomes) { if (sym.symtype == Symbol.becomes) { error(1); /* 把=写成了:= */ } getSym(); if (sym.symtype == Symbol.number) { if (sym.num > amax) { error(31); sym.num = 0; } symTable.add(new PLobject(name, PLobject.constant, sym.num)); getSym(); } else { error(2); /* 常量说明=后应是数字 */ } } else { error(3); /* 常量说明标识后应是= */ } } else { error(4); /* const后应是标识 */ } } int varDeclaration(int dataIndex) throws IOException { if (sym.symtype == Symbol.ident) { symTable.add(new PLobject(sym.id, PLobject.variable, level, dataIndex)); getSym(); dataIndex++; } else { error(4); } return dataIndex; } void statement(HashSet followSet) throws IOException { PLobject plo; HashSet hs; if (sym.symtype == Symbol.ident) { plo = findSym(sym.id); if (plo == null) { error(11); } else { if (plo.kind != PLobject.variable) { error(12); plo = null; } } getSym(); if (sym.symtype == Symbol.becomes) { getSym(); } else { error(13); } expression(followSet); if (plo != null) { code.gen(CodeSegment.sto, level - plo.level, plo.adr); } } else if (sym.symtype == Symbol.readsym) { getSym(); if (sym.symtype != Symbol.lparen) { error(34); } else { do { getSym(); if (sym.symtype == Symbol.ident) { plo = findSym(sym.id); } else { plo = null; } if (plo == null) { error(35); } else { code.gen(CodeSegment.opr, 0, CodeSegment.opRead); code.gen(CodeSegment.sto, level-plo.level, plo.adr); } getSym(); } while (sym.symtype == Symbol.comma); if (sym.symtype != Symbol.rparen) { error(33); while (!followSet.contains(new Integer(sym.symtype))) { getSym(); } } else { getSym(); } } } else if (sym.symtype == Symbol.writesym) { getSym(); if (sym.symtype == Symbol.lparen) { do { getSym();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -