?? simple.java
字號(hào):
} else { this.codeMemory[++this.currentCodePtr] = 4200; } this.needReScan[this.currentCodePtr][0] = nextLineNum; this.needReScan[this.currentCodePtr][1] = this.currentLine; } else if (currentNode.symbol.equals("endif")) { } else if (currentNode.symbol.equals("while")) { Node n1 = tokens.get(++currentPtr); Node opt = tokens.get(++currentPtr); Node n2 = tokens.get(++currentPtr); //if n1 opt n2 .... endif //n1 必須為整數(shù)或變量且已經(jīng)聲明過(guò) //opt 為 <,>,==,<=,>= 中的一個(gè) //n2 同n1 if(!(((n1.type.equals(Type.VARIABLE) && n1.where == 0 && this.symbolTable.contains(n1))|| n1.type == Type.NUM) && (opt.symbol.equals("==") || opt.symbol.equals(">")|| opt.symbol.equals("<") || opt.symbol.equals("<=") || opt.symbol.equals(">=")) && ((n2.type == Type.VARIABLE && n2.where == 0 && this.symbolTable.contains(n2)) || n2.type == Type.NUM))) { throw new Exception("Invalid condition in line " + this.currentLine); } if (n1.type == Type.VARIABLE) { n1 = this.symbolTable.get(this.symbolTable.indexOf(n1)); this.codeMemory[++this.currentCodePtr] = 2000 + n1.location; } else { this.dataMemory[++this.currentNumPtr] = Integer.parseInt(n1.symbol); this.codeMemory[++this.currentCodePtr] = 2000 + currentNumPtr; } if (n2.type == Type.VARIABLE) { n2 = this.symbolTable.get(this.symbolTable.indexOf(n2)); this.codeMemory[++this.currentCodePtr] = 3100 + n2.location; } else { this.dataMemory[++this.currentNumPtr] = Integer.parseInt(n2.symbol); this.codeMemory[++this.currentCodePtr] = 3100 + currentNumPtr; } int nextLineNum = getNextLineNum("endw","while"); if(opt.symbol.equals("==")) { this.codeMemory[++this.currentCodePtr] = 4600; } else if(opt.symbol.equals(">")) { this.codeMemory[++this.currentCodePtr] = 4500; } else if(opt.symbol.equals(">=")) { this.codeMemory[++this.currentCodePtr] = 4100; } else if(opt.symbol.equals("<")) { this.codeMemory[++this.currentCodePtr] = 4400; } else if(opt.symbol.equals("<=")) { this.codeMemory[++this.currentCodePtr] = 4300; } else { this.codeMemory[++this.currentCodePtr] = 4200; } this.needReScan[this.currentCodePtr][0] = nextLineNum; this.needReScan[this.currentCodePtr][1] = this.currentLine; } else if (currentNode.symbol.equals("endw")) { int lineToGo = this.getPreLineNum("while", "endw"); Node temp = new Node(); temp.symbol = String.valueOf(lineToGo); temp.type = Type.LINE; temp = this.symbolTable.get(this.symbolTable.indexOf(temp)); this.codeMemory[++this.currentCodePtr] = 4000 + temp.location; } else if (currentNode.symbol.equals("for")) { Node[] temp = new Node[7]; for(int i=0;i<7;++i) temp[i] = this.tokens.get(++this.currentPtr); if(!(((temp[2].type.equals(Type.VARIABLE) && temp[2].where == 0 && this.symbolTable.contains(temp[2]))|| temp[2].type == Type.NUM) && temp[0].type == Type.VARIABLE && temp[1].symbol.equals("=") && temp[3].symbol.equals("to") && ((temp[4].type == Type.VARIABLE && temp[4].where == 0 && this.symbolTable.contains(temp[4])) || temp[4].type == Type.NUM))) { throw new Exception("Invalid expression in line " + this.currentLine); } int fLocation = this.symbolTable.indexOf(temp[0]); if(fLocation == -1) { throw new Exception(temp[0].symbol + " has been used without been decleared in line " + this.currentLine); } Node f = this.symbolTable.get(fLocation); Node n1 = temp[2]; Node n2 = temp[4]; if (n1.type == Type.VARIABLE) { n1 = this.symbolTable.get(this.symbolTable.indexOf(n1)); this.codeMemory[++this.currentCodePtr] = 2000 + n1.location; this.codeMemory[++this.currentCodePtr] = 2100 + f.location; } else { this.dataMemory[++this.currentNumPtr] = Integer.parseInt(n1.symbol); this.codeMemory[++this.currentCodePtr] = 2000 + currentNumPtr; this.codeMemory[++this.currentCodePtr] = 2100 + f.location; } if (n2.type == Type.VARIABLE) { try { n2 = this.symbolTable.get(this.symbolTable.indexOf(n2)); } catch (Exception e) { throw new Exception(n2.symbol + " has been used without been decleared in line " + this.currentLine); } } else { this.dataMemory[++this.currentNumPtr] = Integer.parseInt(n2.symbol); n2.location = this.currentNumPtr; } Node n3; if(temp[5].symbol.equals("step")) { if(temp[6].type == Type.NUM) { this.dataMemory[++this.currentNumPtr] = Integer.parseInt(temp[6].symbol); temp[6].location = this.currentNumPtr; n3 = temp[6]; } else if (temp[6].type == Type.VARIABLE) { try { temp[6] = this.symbolTable.get(this.symbolTable.indexOf(temp[6])); n3 = temp[6]; } catch (Exception e) { throw new Exception(temp[6].symbol + " has been used without been decleared in line " + this.currentLine); } } else { throw new Exception("Invalid step num " + temp[6].symbol + "in line " + this.currentLine); } } else { this.currentPtr -= 2; n3 = new Node(); this.dataMemory[++this.currentNumPtr] = 1; n3.location = this.currentNumPtr; } this.codeMemory[++this.currentCodePtr] = 2000 + n2.location; this.codeMemory[++this.currentCodePtr] = 3100 + f.location; int nextLineNum = this.getNextLineNum("next", "for"); this.codeMemory[++this.currentCodePtr] = 4100; this.needReScan[this.currentCodePtr][0] = nextLineNum; this.needReScan[this.currentCodePtr][1] = this.currentLine; this.codeMemory[++this.currentCodePtr] = 2000 + f.location; this.codeMemory[++this.currentCodePtr] = 3000 + n3.location; this.codeMemory[++this.currentCodePtr] = 2100 + f.location; } else if (currentNode.symbol.equals("next")) { int location = this.getPreLineNum("for", "next"); Node temp = new Node(); temp.symbol = String.valueOf(location); temp.type = Type.LINE; temp = this.symbolTable.get(this.symbolTable.indexOf(temp)); this.codeMemory[++this.currentCodePtr] = 4000 + temp.location + 2; } else if(currentNode.symbol.equals("let")) { Node y = tokens.get(++currentPtr); Node equ = tokens.get(++currentPtr); try { y = this.symbolTable.get(this.symbolTable.indexOf(y)); }catch (Exception e) { throw new Exception(y.symbol + " has been used without beed decleared. in line " + this.currentLine); } if(!equ.symbol.equals("=")) { throw new Exception("'=' is expected here,but we get " + equ.symbol + " in line " + this.currentLine); } List<Node> infix = new LinkedList<Node>(); Node temp = null; do { try { temp = tokens.get(++currentPtr); infix.add(temp); }catch (Exception e) { //防止讀過(guò)頭了,當(dāng)let語(yǔ)句為程序最后一句時(shí),會(huì)出現(xiàn) } } while(temp.type != Type.LINE); infix.remove(infix.size() - 1); --currentPtr; Node result = this.dealExpression(infix); this.codeMemory[++this.currentCodePtr] = 2000 + result.location; this.codeMemory[++this.currentCodePtr] = 2100 + y.location; } else { throw new Exception("Unexpect symbol " + currentNode.symbol + " appeared in line " + this.currentLine); } } //對(duì)表達(dá)式的處理 private Node dealExpression (List<Node> infix) throws Exception{ List<Node> postfix = this.convertToPostfix(infix); Stack<Node> stack = new Stack<Node>(); for(int i=0;i<postfix.size();++i) { Node current = postfix.get(i); if(current.type == Type.NUM) { this.dataMemory[++this.currentNumPtr] = Integer.parseInt(current.symbol); current.location = this.currentNumPtr; stack.push(current); } else if(current.type == Type.VARIABLE) { try { current = this.symbolTable.get(this.symbolTable.indexOf(current)); stack.push(current); } catch (Exception e) { throw new Exception(current.symbol + " in Expression undecleared in line " + this.currentFile); } } else if(isOperator(current)) { Node n2 = stack.pop(); Node n1 = stack.pop(); Node result = calculator(n1,n2,current); stack.push(result); } else { throw new Exception("Invalid expression in line " + this.currentLine); } } return stack.pop(); } //計(jì)算n1 opt n2的結(jié)果,并返回Node值 private Node calculator(Node n1,Node n2,Node opt) throws Exception { Node result = new Node(); this.codeMemory[++this.currentCodePtr] = 2000 + n1.location; if(opt.symbol.equals("+")) { this.codeMemory[++this.currentCodePtr] = 3000 + n2.location; } else if(opt.symbol.equals("-")) { this.codeMemory[++this.currentCodePtr] = 3100 + n2.location; } else if(opt.symbol.equals("*")) { this.codeMemory[++this.currentCodePtr] = 3300 + n2.location; } else if(opt.symbol.equals("/")) { this.codeMemory[++this.currentCodePtr] = 3200 + n2.location; } else if(opt.symbol.equals("^")) { this.codeMemory[++this.currentCodePtr] = 3500 + n2.location; } else if(opt.symbol.equals("%")) { this.codeMemory[++this.currentCodePtr] = 3400 + n2.location; } else { throw new Exception ("Unsupported operator " + opt.symbol + "int line " + this.currentLine); } //分配一個(gè)內(nèi)存位置給中間結(jié)果 ++this.currentNumPtr; this.codeMemory[++this.currentCodePtr] = 2100 + this.currentNumPtr; result.location = this.currentNumPtr; return result; } //將中綴式生成對(duì)應(yīng)的后綴式 private List<Node> convertToPostfix (List<Node> infix) throws Exception { Stack<Node> stack = new Stack<Node>(); List<Node> postfix = new LinkedList<Node>(); Node temp = new Node(); temp.symbol = "("; temp.type = Type.KEYWORD; stack.push(temp); temp = new Node(); temp.symbol = ")"; temp.type = Type.KEYWORD; infix.add(temp); int ptr = 0; try { while (!stack.empty()) { Node current = infix.get(ptr); if(current.type == Type.NUM || current.type == Type.VARIABLE) { postfix.add(current); } else if(current.symbol.equals("(")) { stack.push(current); } else if(isOperator(current)) { if(isOperator(stack.peek()) && isLarger(stack.peek(),current)) { postfix.add(stack.pop()); } stack.push(current); } else if(current.symbol.equals(")")) { Node top = stack.pop(); while(!top.symbol.equals("(")) { postfix.add(top); top = stack.pop(); } } ++ptr; } } catch (Exception e) { throw new Exception("Invalid expression in line " + this.currentLine); } return postfix; } private boolean isOperator(Node node) { return node.symbol.equals("+") || node.symbol.equals("-") || node.symbol.equals("*") || node.symbol.equals("/") || node.symbol.equals("%") || node.symbol.equals("^"); } private boolean isLarger(Node opt1,Node opt2) { return this.getPRI(opt1) > this.getPRI(opt2); } private int getPRI(Node opt) { if(opt.symbol.equals("+") || opt.symbol.equals("-")) { return 1; } else if(opt.symbol.equals("^")) { return 4; } else if(opt.symbol.equals("*") || opt.symbol.equals("/") || opt.symbol.equals("%")) { return 2; } else { throw new RuntimeException(); } } private void reScan() throws Exception { for(int line = 0; line < 100; ++line) { if(this.needReScan[line][0] != -1) { Node temp = new Node(); temp.type = Type.LINE; temp.symbol = String.valueOf(this.needReScan[line][0]); int location = this.symbolTable.indexOf(temp); if(location == -1) throw new Exception("The line num " + this.needReScan[line][0] + " int line " + this.needReScan[line][1] + " is not exist."); temp = this.symbolTable.get(location); this.codeMemory[line] += temp.location; } } } private void dealLine(Node currentNode) throws Exception { this.currentLine = Integer.parseInt(currentNode.symbol); currentNode.location = this.currentCodePtr + 1; this.symbolTable.add(currentNode); } private void iniMemory() { for (int i = 0; i < 100; ++i) { dataMemory[i] = 0; codeMemory[i] = 0; needReScan[i][0] = -1; stringMemory[i / 2] = null; } } private int[][] needReScan = new int[100][2]; private List<Node> tokens; private List<Node> symbolTable; //存放聲明的變量及行號(hào) private int[] dataMemory = new int[100]; private int[] codeMemory = new int[100]; private String[] stringMemory = new String[50]; private String currentFile; private int currentLine = -1; //源程序中當(dāng)前的代碼行 private int currentPtr = -1; //指向讀頭下的token private int currentCodePtr; //生成的語(yǔ)句存放的位置 private int currentNumPtr; //整數(shù)在內(nèi)存中的位置 private int currentStringPtr; //字符串在內(nèi)存中的位置 /* *是否已經(jīng)編譯過(guò) */ private boolean compiled = false; //程序是否包含"end",若不包含,則生成的目標(biāo)代碼會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤 private boolean hasEndSymbol = false; private Lexical lex;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -