simple.java

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

JAVA
657
字号
            } 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 必须为整数或变量且已经声明过            //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("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) {                      //防止读过头了,当let语句为程序最后一句时,会出现                }            } 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);        }    }    //对表达式的处理    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();    }    //计算n1 opt n2的结果,并返回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);        }        //分配一个内存位置给中间结果        ++this.currentNumPtr;        this.codeMemory[++this.currentCodePtr] = 2100 + this.currentNumPtr;        result.location = this.currentNumPtr;        return result;    }    //将中缀式生成对应的后缀式    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;           //存放声明的变量及行号    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;         //源程序中当前的代码行    private int currentPtr = -1;          //指向读头下的token    private int currentCodePtr;           //生成的语句存放的位置    private int currentNumPtr;            //整数在内存中的位置    private int currentStringPtr;         //字符串在内存中的位置    /*     *是否已经编译过    */    private boolean compiled = false;    //程序是否包含"end",若不包含,则生成的目标代码会发生运行时错误    private boolean hasEndSymbol = false;    private Lexical lex;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?