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

📄 evalspice.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                    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 ParseException("Invalid token");            }            else {                tokenizer.pushBack();            }            tokenizer.wordChars('e', 'e');            tokenizer.wordChars('E', 'E');            return new Double(val);        }        throw new ParseException("Expected number");    }    private void expect(int token) throws IOException, ParseException {        int tt = tokenizer.nextToken();        if (tt != token) throw new ParseException("Expected token "+token);    }    // ==================== Parsable Objects ========================    public static class ParseException extends Exception {        public ParseException(String msg) { super(msg); }    }    public static class Op {        public final String name;        public final int precedence;        private Op(String name, int precedence) {            this.name = name;            this.precedence = precedence;        }        public String toString() { return name; }        // operators with lower value precedence bind tighter than higher value precedence        public static final Op MULT =  new Op("*", 2);        public static final Op DIV =   new Op("/", 2);        public static final Op PLUS =  new Op("+", 3);        public static final Op MINUS = new Op("-", 3);        public static final Op LT =    new Op("<", 5);        public static final Op LTOE =  new Op("<=", 5);        public static final Op GT =    new Op(">", 5);        public static final Op GTOE =  new Op(">=", 5);        public static final Op EQ =    new Op("==", 6);        public static final Op NE =    new Op("!=", 6);        public static final Op LAND =  new Op("&&", 10);        public static final Op LOR =   new Op("||", 11);        public static final Op CONDCHOICE =  new Op(":", 12);        public static final Op COND =  new Op("?", 13);    }    private static final Double ONE = new Double(1);    private static final Double ZERO = new Double(0);    /**     * A simple equation consists of two Identifiers (operands)     * that are Doubles, Strings, or other SimpleEq,     * and an operator *,/,+,-.     * <P>     * For a simple equation to be valid, it must define     * both operands and an operator. However, if the     * operator is '-', then the left hand operand may     * be null, to indicate a unary minus.  Additionally,     * if only the left hand operator is defined, then it     * is simply one operand.     */    public static class SimpleEq {        protected Object lhop;        // left hand operand        private Op op;              // operator        protected Object rhop;        // right hand operand        boolean neglh = false;        boolean negrh = false;        public SimpleEq() {            this.lhop = null;            this.op = null;            this.rhop = null;        }        public SimpleEq(Object lhop, Op op, Object rhop) {            this.lhop = lhop;            this.op = op;            this.rhop = rhop;        }        public boolean addIdentifierOk() {            if (lhop == null)                return true;            else if (rhop == null && op != null)                return true;            else if (rhop instanceof SimpleEq)                return ((SimpleEq)rhop).addIdentifierOk();            return false;        }        public void addIdentifier(Object id) throws ParseException {            if (lhop == null)                lhop = id;            else if (rhop == null && op != null)                rhop = id;            else if (rhop instanceof SimpleEq)                ((SimpleEq)rhop).addIdentifier(id);            else                throw new ParseException("Two operands with no operator");        }        public void addOp(Op operator) throws ParseException {            if (lhop == null && operator == Op.MINUS && !neglh)                neglh = true;               // unary minus on left hand operand            else if (lhop == null)                throw new ParseException("Operator "+operator+" with no left hand operand");            // lhop defined from here on            else if (op == null && rhop == null)                this.op = operator;            else if (op != null && rhop == null && operator == Op.MINUS && !negrh)                negrh = true;               // unary minus on right hand operand            else if (op != null && rhop != null) {                if (rhop instanceof SimpleEq) {                    ((SimpleEq)rhop).addOp(operator);                }                else {                    // operators with lower value precedence bind tighter than higher value precedence                    if (operator.precedence < op.precedence) {                        // bind right                        rhop = new SimpleEq(rhop, operator, null);                        // retain proper negation associations                        ((SimpleEq)rhop).neglh = negrh;                        negrh = false;                    } else {                        // bind left                        lhop = new SimpleEq(lhop, op, rhop);                        this.op = operator;                        this.rhop = null;                        // retain proper negation associations                        ((SimpleEq)lhop).neglh = neglh;                        ((SimpleEq)lhop).negrh = negrh;                        this.neglh = false;                        this.negrh = false;                    }                }            }            else                throw new ParseException(("Two operators in a row"));        }        /**         * Return either a Double, if the equation can be         * resolved numerically, or a String representing         * the equation after any numerical resolution can be done.         * @return a Double or a String         */        public Object eval() throws ParseException {            if (lhop instanceof SimpleEq)                lhop = ((SimpleEq)lhop).eval();            if (rhop instanceof SimpleEq)                rhop = ((SimpleEq)rhop).eval();            if (op == Op.CONDCHOICE) {                return this;            }            if (op == Op.COND && (rhop instanceof SimpleEq)) {                SimpleEq condval = (SimpleEq)rhop;                if ((lhop instanceof Double) && (condval.lhop instanceof Double) && (condval.rhop instanceof Double)) {                    double cond = ((Double)lhop).doubleValue();                    if (neglh) cond = -1.0 * cond;                    double valt = ((Double)condval.lhop).doubleValue();                    if (condval.neglh) valt = -1.0 * valt;                    double valf = ((Double)condval.rhop).doubleValue();                    if (condval.negrh) valf = -1.0 * valf;                    if (cond == 0) return valf;                    return valt;                }                String neglhstr = condval.neglh ? "-" : "";                String negrhstr = condval.negrh ? "-" : "";                rhop = neglhstr + format(condval.lhop) + " : " + negrhstr + format(condval.rhop);            }            else if ((lhop instanceof Double) && (rhop instanceof Double)) {                double lh = ((Double)lhop).doubleValue();                double rh = ((Double)rhop).doubleValue();                if (neglh) lh = -1.0 * lh;                if (negrh) rh = -1.0 * rh;                if      (op == Op.MULT)  return new Double(lh * rh);                else if (op == Op.DIV)   return new Double(lh / rh);                else if (op == Op.PLUS)  return new Double(lh + rh);                else if (op == Op.MINUS) return new Double(lh - rh);                else if (op == Op.LT)    return lh < rh ? ONE : ZERO;                else if (op == Op.LTOE)  return lh <= rh ? ONE : ZERO;                else if (op == Op.GT)    return lh > rh ? ONE : ZERO;                else if (op == Op.GTOE)  return lh >= rh ? ONE : ZERO;                else if (op == Op.EQ)    return lh == rh ? ONE : ZERO;                else if (op == Op.NE)    return lh != rh ? ONE : ZERO;                else if (op == Op.LAND)  return (lh != 0 && rh != 0) ? ONE : ZERO;                else if (op == Op.LOR)  return (lh != 0 || rh != 0) ? ONE : ZERO;            }            else if (op == null && rhop == null) {                if (neglh) {                    if (lhop instanceof Double) {                        return -1.0 * ((Double)lhop).doubleValue();                    }                    return "-"+lhop.toString();                }                return lhop;            }            // can't resolve numerically            String neglhstr = neglh ? "-" : "";            String negrhstr = negrh ? "-" : "";            String lhstr = (lhop == null ? "?" : format(lhop));            String rhstr = (rhop == null ? "?" : format(rhop));            return neglhstr + lhstr + " " + op + " " + negrhstr + rhstr;        }    }    private static String format(Object obj) {        // must be format double postfix, otherwise get 0 for numbers less than 0.001        if (obj instanceof Double) return TextUtils.formatDoublePostFix(((Double)obj).doubleValue());        return obj.toString();    }    // ================================ Main Test ================================    public static void main(String args[]) {        testEval("1 + 2", 3);        testEval("1 + 2 * 3", 7);        testEval("1 * 2 + 3", 5);        testEval("(1 + 2) * 3", 9);        testEval("(1 + 2) * x", "3 * x");        testEval("300 / -1.5e2", -2);        testEval("1.5e-2", 0.015);        testEval("20 * 1.5e-2", 0.3);        testEval("20 * 1.5m", 0.03);        testEval("(1 + a) * 3 + b", "(1 + a) * 3 + b");        testEval("1 + 2 * 3 + - 4", 3);        testEval("-1", -1);        testEval("-1 + 2 * 3 + - 4", 1);        testEval("-(1 + 2) * 3 + -4", -13);        testEval("-(1 + 2) * 3 + -4 * -2 - -4 * -3", -13);        testEval("-sin(3)", -Math.sin(3));        testEval("-sin(x)", "-sin(x)");        testEval("1-min(1,-2)", 3);        testEval("1-min(1,x)", null);        testEval("1-min((a+b)*c,x)", null);        testEval("1-min((a+b)*c,(a+b))", null);        testEval("-a + 2 * 3 * -b + - 4", null);        testEval("1 ? -2 : 4", -2);        testEval("0 ? -2 : 4", 4);        testEval("8 == 1 ? -2 : 4", 4);        testEval("8 > 1 ? -2 : 4", -2);        testEval("1 - 7 <= 1 ? -2 : 4", -2);        testEval("layer == 1 ? two + 1 : eight * 4 / 2", "layer == 1 ? two + 1 : eight * 4 / 2");        testEval("0 * 1 ? 3 / 2 : -4 + 10", 6);        testEval("(3==0?0.00441:3<8?0.011:0.016)*1e-15", 1.1e-17);        testEval("(layer==0?0.00441:layer<8?0.011:0.016)*1e-15", null);        System.out.println("\nThese should flag as errors:\n---------------------------\n");        testEval("1 2 +", null);        testEval("1 + * 2", null);        testEval("1 + 2 * - -3", null);        testEval("300 / -1.5ee2 + 5", null);        testEval("1-min((a+b)*c,(a+b)", null);        testEval("1/0", null);        testEval("M1 - M3 : 10001", null);    }    private static void testEval(String eq, String expected) {        EvalSpice sp = new EvalSpice(eq);        String evald = sp.evaluate().toString();        if (expected == null) {            System.out.println(eq+" = "+evald);        } else {            System.out.println(eq+" = "+evald+" -- ("+expected+")");            assert(expected.equals(evald));        }    }    private static void testEval(String eq, double expected) {        EvalSpice sp = new EvalSpice(eq);        Object evald = sp.evaluate();        System.out.println(eq+" = "+evald+" -- ("+expected+")");        assert(evald instanceof Double);        double val = ((Double)evald).doubleValue();        assert(val == expected);    }}

⌨️ 快捷键说明

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