⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codeexpression.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            tokenizer = new StreamTokenizer(reader);            tokenizer.parseNumbers();            tokenizer.ordinaryChar('(');            tokenizer.ordinaryChar(')');            tokenizer.ordinaryChar('*');            tokenizer.ordinaryChar('/');            tokenizer.ordinaryChar('+');            tokenizer.ordinaryChar('-');            tokenizer.ordinaryChar('<');            tokenizer.ordinaryChar('=');            tokenizer.ordinaryChar('>');            tokenizer.ordinaryChar('!');            tokenizer.ordinaryChar('?');            tokenizer.ordinaryChar(':');            tokenizer.ordinaryChar('@');            tokenizer.quoteChar('"');            tokenizer.wordChars('_', '_');        }        private Expr parse() throws EvalSpice.ParseException {            try {                nextToken();                Expr expr = evalEq();                assert op == null;                switch (tokenizer.ttype) {                    case StreamTokenizer.TT_EOF:                        return expr;                    case StreamTokenizer.TT_EOL:                        throw new EvalSpice.ParseException("Multiline expression");                    case StreamTokenizer.TT_NUMBER:                    case StreamTokenizer.TT_WORD:                    case '(':                        throw new EvalSpice.ParseException("Two operands with no operator");                    default:                        throw new EvalSpice.ParseException("Unexpected character " + (char)tokenizer.ttype);                }            } catch (IOException e) {                throw new EvalSpice.ParseException(e.getMessage());            } catch (EvalSpice.ParseException e) {                try {                    long left = reader.skip(Long.MAX_VALUE);                    int pos = expr.length() - (int)left;                    throw new EvalSpice.ParseException(expr.substring(0, pos) + "<" + e.getMessage() + ">" + expr.substring(pos));                } catch (IOException e2) {}            }            throw new AssertionError();        }        private Expr evalEq() throws IOException, EvalSpice.ParseException {            return evalEq(Expr.MAX_PRECEDENCE);        }        /**         * Evaluate an expression         * @return the evaluated expression         * @throws IOException         * @throws ParseException         */        private Expr evalEq(int outerPrecedence) throws IOException, EvalSpice.ParseException {            boolean unaryMinus = false;            if (op == EvalSpice.Op.MINUS) {                unaryMinus = true;                nextToken();            }            Expr e;            if (tokenizer.ttype == '(') {                nextToken();                e = evalEq();                expect(')');            } else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) {                e = parseNumber();            } else if (tokenizer.ttype == StreamTokenizer.TT_WORD) {                e = parseWord();            } else if (tokenizer.ttype == '@') {                if (nextToken() != StreamTokenizer.TT_WORD)                    throw new EvalSpice.ParseException("Bad name after @");                e = new VarExpr(Variable.newKey("ATTR_" + tokenizer.sval));                nextToken();            } else if (op != null) {                throw new EvalSpice.ParseException("Operator "+op+" with no left hand operand");            } else {                throw new EvalSpice.ParseException("Expected identifier");            }            if (unaryMinus)                e = new UnaryOpExpr(e);            for (;;) {                if (op == null || outerPrecedence < op.precedence)                    return e;                if (op == EvalSpice.Op.COND) {                    nextToken();                    Expr thenE = evalEq(Expr.MAX_PRECEDENCE - 1);                    expect(':');                    Expr elseE = evalEq();                    return new IfThenElseExpr(e, thenE, elseE);                }                EvalSpice.Op myOp = op;                assert outerPrecedence >= myOp.precedence;                nextToken();                Expr e2 = evalEq(myOp.precedence - 1);                e = new BinaryOpExpr(e, myOp, e2);            }        }        /**         * Parse a number. A number may have the format:         * <P>         * number[g|meg|k|m|u|n|p|f]         * <p>         * number(e)[-]number         * @return         * @throws IOException         * @throws ParseException         */        private ConstExpr parseNumber() throws IOException, EvalSpice.ParseException {            assert tokenizer.ttype == StreamTokenizer.TT_NUMBER;            double val = tokenizer.nval;            // peek ahead to check if exponential, or multiplier            tokenizer.ordinaryChar('e');            tokenizer.ordinaryChar('E');            int tt = tokenizer.nextToken();            if (tt == 'e' || tt == 'E') {                tt = tokenizer.nextToken();                boolean minus = false;                if (tt == '-') {                    minus = true;                    tt = tokenizer.nextToken();                }                if (tt == StreamTokenizer.TT_NUMBER) {                    double exp = tokenizer.nval;                    if (minus) exp = -1.0 * exp;                    val = val * Math.pow(10, exp);                } else {                    throw new EvalSpice.ParseException("Invalid token");                }            }            else if (tt == StreamTokenizer.TT_WORD) {                if (tokenizer.sval.equalsIgnoreCase("g")) {                    val = val * 1e9;                } else if (tokenizer.sval.equalsIgnoreCase("meg")) {                    val = val * 1e6;                } else if (tokenizer.sval.equalsIgnoreCase("k")) {                    val = val * 1e3;                } else if (tokenizer.sval.equalsIgnoreCase("m")) {                    val = val * 1e-3;                } else if (tokenizer.sval.equalsIgnoreCase("u")) {                    val = val * 1e-6;                } else if (tokenizer.sval.equalsIgnoreCase("n")) {                    val = val * 1e-9;                } else if (tokenizer.sval.equalsIgnoreCase("p")) {                    val = val * 1e-12;                } else if (tokenizer.sval.equalsIgnoreCase("f")) {                    val = val * 1e-15;                } else                    throw new EvalSpice.ParseException("Invalid token");            }            else {                tokenizer.pushBack();            }            tokenizer.wordChars('e', 'e');            tokenizer.wordChars('E', 'E');            nextToken();            return new ConstExpr(new Double(val));        }        private Expr parseWord() throws IOException, EvalSpice.ParseException {            assert tokenizer.ttype == StreamTokenizer.TT_WORD;            String id = tokenizer.sval;            for (UnaryFunExpr.Fun fun : UnaryFunExpr.Fun.class.getEnumConstants()) {                if (!id.equalsIgnoreCase(fun.toString()) && !id.equals("Math." + fun.toString())) continue;                nextToken();                expect('(');                Expr arg = evalEq();                expect(')');                return new UnaryFunExpr(fun, arg);            }            for (BinaryFunExpr.Fun fun : BinaryFunExpr.Fun.class.getEnumConstants()) {                if (!id.equalsIgnoreCase(fun.toString()) && !id.equals("Math." + fun.toString())) continue;                nextToken();                expect('(');                Expr arg1 = evalEq();                expect(',');                Expr arg2 = evalEq();                expect(')');                return new BinaryFunExpr(fun, arg1, arg2);            }            if (/*isJava &&*/ id.equals("P")) {                nextToken();                expect('(');                if (tokenizer.ttype != '"')                    throw new EvalSpice.ParseException("Bad name after @");                Variable.Key varKey = Variable.newKey(tokenizer.sval);                nextToken();                expect(')');                return new VarExpr(varKey);            }            if (isJava && id.equals("LE.getdrive")) {                nextToken();                expect('(');                expect(')');                return new GetDriveExpr();            }            if (isJava && id.equals("LE.subdrive")) {                nextToken();                expect('(');                if (tokenizer.ttype != '"')                    throw new EvalSpice.ParseException("Bad name after subdrive");                String instName = tokenizer.sval;                nextToken();                expect(',');                if (tokenizer.ttype != '"')                    throw new EvalSpice.ParseException("Bad name after subdrive");                String varName = tokenizer.sval;                nextToken();                expect(')');                return new SubDriveExpr(instName, varName);            }            Variable.Key attrKey = Variable.newKey("ATTR_" + tokenizer.sval);            nextToken();            return new VarExpr(attrKey);        }        private void expect(int token) throws IOException, EvalSpice.ParseException {            if (tokenizer.ttype != token)                throw new EvalSpice.ParseException("Expected token "+(char)token);            nextToken();        }        private int nextToken() throws IOException, EvalSpice.ParseException {            switch (tokenizer.nextToken()) {                case '*':                    op = EvalSpice.Op.MULT;                    break;                case '/':                    op = EvalSpice.Op.DIV;                    break;                case '+':                    op = EvalSpice.Op.PLUS;                    break;                case '-':                    op = EvalSpice.Op.MINUS;                    break;                case '<':                    op = EvalSpice.Op.LT;                    if (tokenizer.nextToken() == '=')                        op = EvalSpice.Op.LTOE;                    else                        tokenizer.pushBack();                    break;                case '>':                    op = EvalSpice.Op.GT;                    if (tokenizer.nextToken() == '=')                        op = EvalSpice.Op.GTOE;                    else                        tokenizer.pushBack();                    break;                case '=':                    op = EvalSpice.Op.EQ;                    if (tokenizer.nextToken() != '=')                        throw new EvalSpice.ParseException("Expected token ==");                    break;                case '!':                    op = EvalSpice.Op.NE;                     if (tokenizer.nextToken() != '=')                        throw new EvalSpice.ParseException("Expected token !=");                    break;                case '?':                    op = EvalSpice.Op.COND;                    break;                case StreamTokenizer.TT_EOL:                    throw new EvalSpice.ParseException("Multiline expression");                case ':':                case '(':                case ')':                case ',':                case '@':                case '"':                case StreamTokenizer.TT_NUMBER:                case StreamTokenizer.TT_WORD:                case StreamTokenizer.TT_EOF:                    op = null;                    break;                default:                    throw new EvalSpice.ParseException("Illegal character " + (char)tokenizer.ttype);            }            return tokenizer.ttype;        }    }}

⌨️ 快捷键说明

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