simple.java

来自「一个用JAVA做的」· Java 代码 · 共 657 行 · 第 1/2 页

JAVA
657
字号
/* * 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 + =
减小字号Ctrl + -
显示快捷键?