?? simple.java
字號:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */package srtpv02;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.Writer;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.LinkedList;import java.util.List;import java.util.Set;import java.util.Stack;/** * * @author Administrator */public class Simple { public String compile(String fileName) { lex = new Lexical(fileName); currentFile = fileName; this.hasEndSymbol = false; try { lex.run(); tokens = lex.getTokens(); this.iniMemory(); this.analyse(); this.reScan(); } catch (Exception e) { return e.getMessage(); } try { this.outCode(); this.outData(); this.outSData(); } catch (Exception e) { return "寫入到目標文件時發生錯誤"; } if(!this.hasEndSymbol){ return "The program does not have end symbol, this will cause runntime error."; } return "Congratulations! Complie succeed..."; } public void run() { if (!compiled) { return; } } private int getNextLineNum(String want, String ignore) { int needIgnore = 0; for (int next = this.currentPtr + 1; next < this.tokens.size(); ++next) { Node node = this.tokens.get(next); if (node.symbol.equals(ignore)) { ++needIgnore; } else if (node.symbol.equals(want)) { if (needIgnore == 0) { Node ppLineNum = this.tokens.get(++next); if(ppLineNum.type == Type.LINE) return Integer.parseInt(ppLineNum.symbol); else return -1; } else { --needIgnore; } } } return -1; } private int getPreLineNum(String want, String ignore) { int needIgnore = 0; for (int pre = this.currentPtr - 1; pre >= 0 ; --pre) { Node node = this.tokens.get(pre); if (node.symbol.equals(ignore)) { ++needIgnore; } else if (node.symbol.equals(want)) { if (needIgnore == 0) { Node ppLineNum = this.tokens.get(--pre); if(ppLineNum.type == Type.LINE) return Integer.parseInt(ppLineNum.symbol); else return -1; } else { --needIgnore; } } } return -1; } private void outData() throws Exception { File data = new File(this.currentFile + ".mem"); Writer writer = new FileWriter(data); for(int num : this.dataMemory) { writer.write("" + num + "\n"); } data.createNewFile(); writer.flush(); writer.close(); } private void outSData() throws Exception { File data = new File(this.currentFile + ".smem"); Writer writer = new FileWriter(data); for (String string : this.stringMemory) { writer.write(string + "\n"); } data.createNewFile(); writer.flush(); writer.close(); } private void outCode() throws Exception { File data = new File(this.currentFile + ".code"); Writer writer = new FileWriter(data); for (int num : this.codeMemory) { writer.write("" + num + "\n"); } data.createNewFile(); writer.flush(); writer.close(); } private void analyse() throws Exception { symbolTable = new ArrayList<Node>(); currentLine = -1; this.currentStringPtr = -1; this.currentNumPtr = -1; this.currentCodePtr = -1; for (currentPtr = 0; currentPtr < tokens.size(); ++currentPtr) { Node current = tokens.get(currentPtr); switch (current.type) { case LINE: dealLine(current); break; case KEYWORD: dealKeyWord(current); break; /*case VARIABLE: dealVariable(current); break; case STRING: dealString(current); break; case NUM: dealNum(current); break;*/ default: throw new Exception(current.symbol + " in line " + currentLine + " is wrong!"); } } } private void dealKeyWord(Node currentNode) throws Exception { if (currentNode.symbol.equals("rem")) { while (true) { if (tokens.get(++currentPtr).type.equals(Type.LINE)) { break; } } --currentPtr; return; } else if (currentNode.symbol.equals("input")) { Node temp = tokens.get(++currentPtr); int location = this.symbolTable.indexOf(temp); if (location != -1) { temp = this.symbolTable.get(location); if(temp.where == 0) { this.codeMemory[++this.currentCodePtr] = 1000 + temp.location; return; } else { this.codeMemory[++this.currentCodePtr] = 1200 + temp.location; return; } } else { throw new Exception(temp.symbol + " has been used without been defined in line" + this.currentLine); } } else if (currentNode.symbol.equals("print")) { Node temp = tokens.get(++currentPtr); if (temp.type.equals(Type.VARIABLE)) { int location = this.symbolTable.indexOf(temp); if (location != -1) { temp = this.symbolTable.get(location); if (temp.where == 0) { this.codeMemory[++this.currentCodePtr] = 1100 + temp.location; return; } else { this.codeMemory[++this.currentCodePtr] = 1300 + temp.location; return; } } else { throw new Exception(temp.symbol + " has not been defined in line" + this.currentLine); } } else if(temp.type.equals(Type.NUM)){ this.dataMemory[++this.currentNumPtr] = Integer.parseInt(temp.symbol); this.codeMemory[++this.currentCodePtr] = 1100 + this.currentNumPtr; } else if(temp.type.equals(Type.STRING)) { this.stringMemory[++this.currentStringPtr] = temp.symbol; this.codeMemory[++this.currentCodePtr] = 1300 + this.currentStringPtr; } else { } } else if (currentNode.symbol.equals("string")) { Node temp = tokens.get(++currentPtr); if(this.symbolTable.contains(temp)) { throw new Exception(temp.symbol + " has already been defined."); } temp.where = 1; //this.stringMemory[++this.currentStringPtr] = temp.symbol; //記錄存放在內存中的位置,并將此變量放入符號表 temp.location = ++this.currentStringPtr; this.symbolTable.add(temp); //如果下一個符號是 = ,則說明是聲明的同時進行了初始化,將此值放入內存 Node valueTemp = tokens.get(currentPtr + 1); if(valueTemp.symbol.equals("=")) { currentPtr += 2; valueTemp = tokens.get(currentPtr); if(!valueTemp.type.equals(Type.STRING)) throw new Exception(valueTemp.symbol + " is not valid value for " + temp.symbol); this.stringMemory[this.currentStringPtr] = valueTemp.symbol; } return; } else if (currentNode.symbol.equals("int")) { Node temp = tokens.get(++currentPtr); if (symbolTable.contains(temp)) { throw new Exception(temp.symbol + " has already been defined"); } temp.where = 0; //this.dataMemory[++this.currentNumPtr] = Integer.parseInt(temp.symbol); temp.location = ++this.currentNumPtr; this.symbolTable.add(temp); Node valueTemp = tokens.get(currentPtr + 1); if(valueTemp.symbol.equals("=")) { currentPtr += 2; valueTemp = tokens.get(currentPtr); if (!valueTemp.type.equals(Type.NUM)) { throw new Exception(valueTemp.symbol + " is not valid value for " + temp.symbol); } this.dataMemory[this.currentNumPtr] = Integer.parseInt(valueTemp.symbol); } } else if (currentNode.symbol.equals("gosub")) { Node temp = tokens.get(++currentPtr); if(!temp.type.equals(Type.NUM)) { throw new Exception("The gosub must followed with a num in line " + this.currentLine); } temp.type = Type.LINE; int locationInTable = symbolTable.indexOf(temp); if(locationInTable != -1) { temp = tokens.get(locationInTable); this.codeMemory[++this.currentCodePtr] = 5200 + temp.location; return; } else { this.codeMemory[++this.currentCodePtr] = 5200; this.needReScan[this.currentCodePtr][0] = Integer.parseInt(temp.symbol); this.needReScan[this.currentCodePtr][1] = this.currentLine; return; } } else if (currentNode.symbol.equals("return")) { this.codeMemory[++this.currentCodePtr] = 5300; } else if (currentNode.symbol.equals("end")) { this.codeMemory[ ++ this.currentCodePtr] = 8000; this.hasEndSymbol = true; } else if (currentNode.symbol.equals("goto")) { Node temp = tokens.get(++currentPtr); if(!temp.type.equals(Type.NUM)) { throw new Exception("The goto must followed with a num in line " + this.currentLine); } temp.type = Type.LINE; int locationInTable = symbolTable.indexOf(temp); if(locationInTable != -1) { temp = tokens.get(locationInTable); this.codeMemory[++this.currentCodePtr] = 4000 + temp.location; return; } else { this.codeMemory[++this.currentCodePtr] = 4000; this.needReScan[this.currentCodePtr][0] = Integer.parseInt(temp.symbol); this.needReScan[this.currentCodePtr][1] = this.currentLine; return; } } else if (currentNode.symbol.equals("if")) { Node n1 = tokens.get(++currentPtr); Node opt = tokens.get(++currentPtr); Node n2 = tokens.get(++currentPtr); //if n1 opt n2 .... endif //n1 必須為整數或變量且已經聲明過 //opt 為 <,>,==,<=,>= 中的一個 //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("Valid 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("endif","if"); 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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -