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

📄 evalspice.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: EvalSpice.java * * Copyright (c) 2005 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.database.variable;import com.sun.electric.database.text.TextUtils;import java.io.IOException;import java.io.StreamTokenizer;import java.io.StringReader;/** * Class to evaluate Spice expressions. * User: gainsley * Date: Aug 17, 2006 */public class EvalSpice {    private String expr;    private StreamTokenizer tokenizer;    int openParens;    public EvalSpice(String expr) {        this.expr = expr;        openParens = 0;    }    public Object evaluate() {        if (expr == null) return null;        StringReader reader = new StringReader(expr);        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.wordChars('_', '_');        try {            return evalEq().eval();        } catch (IOException e) {            System.out.println(e.getMessage());        } catch (ParseException e) {            String parsed = "";            try {                long left = reader.skip(Long.MAX_VALUE);                parsed = expr.substring(0, expr.length()-(int)left);            } catch (IOException e2) {}            if (!parsed.equals(""))                parsed = ": "+parsed+" <--";            System.out.println("Spice Parse Error: "+e.getMessage()+parsed +" "+tokenizer.toString());            System.out.println("   Original string: "+expr);        }        return expr;    }    /**     * Evaluate an expression     * @return the evaluated expression     * @throws IOException     * @throws ParseException     */    private SimpleEq evalEq() throws IOException, ParseException {        SimpleEq eq = new SimpleEq();        while (true) {            int tt = tokenizer.nextToken();            if (tt == StreamTokenizer.TT_EOF || tt == StreamTokenizer.TT_EOL) {                if (openParens > 0) throw new ParseException("Unmatched open parens");                return eq;            }            // delimiters come first            else if (tt == ')') {       // end eq                openParens--;                if (openParens < 0) throw new ParseException("Unmatched close parens");                Object value = eq.eval();                if (value instanceof String) {                    return new SimpleEq("("+value.toString()+")", null, null);                }                return new SimpleEq(value, null, null);            }            else if (tt == '(') {       // begin new eq                openParens++;                if (!eq.addIdentifierOk()) throw new ParseException("Too many identifiers");                Object id = evalEq();                eq.addIdentifier(id);            }            else if (tt == ',') {       // end eq                return eq;            }            else if (tt == StreamTokenizer.TT_NUMBER) {                tokenizer.pushBack();                eq.addIdentifier(parseNumber());            }            else if (tt == StreamTokenizer.TT_WORD) {                if (tokenizer.sval.equalsIgnoreCase("sin")) {                    expect('(');                    openParens++;                    Object arg = evalEq().eval();                    if (arg instanceof Double) {                        arg = new Double(Math.sin(((Double)arg).doubleValue()));                    } else {                        arg = "sin"+format(arg);                    }                    eq.addIdentifier(arg);                }                else if (tokenizer.sval.equalsIgnoreCase("min")) {                    expect('(');                    openParens++;                    Object m1 = evalEq().eval();                    Object m2 = evalEq().eval();                    if ((m1 instanceof Double) && (m2 instanceof Double)) {                        double a = ((Double)m1).doubleValue();                        double b = ((Double)m2).doubleValue();                        m1 = new Double(Math.min(a,b));                    } else {                        String m2str = format(m2);                        // remove extraneous ()'s                        if (m2str.startsWith("(") && m2str.endsWith(")"))                            m2str = m2str.substring(1, m2str.length()-1);                        m1 = "min("+format(m1)+","+m2str+")";                    }                    eq.addIdentifier(m1);                }                else if (tokenizer.sval.equalsIgnoreCase("max")) {                    expect('(');                    openParens++;                    Object m1 = evalEq().eval();                    Object m2 = evalEq().eval();                    if ((m1 instanceof Double) && (m2 instanceof Double)) {                        double a = ((Double)m1).doubleValue();                        double b = ((Double)m2).doubleValue();                        m1 = new Double(Math.max(a,b));                    } else {                        String m2str = format(m2);                        // remove extraneous ()'s                        if (m2str.startsWith("(") && m2str.endsWith(")"))                            m2str = m2str.substring(1, m2str.length()-1);                        m1 = "max("+format(m1)+","+m2str+")";                    }                    eq.addIdentifier(m1);                }                else if (tokenizer.sval.equalsIgnoreCase("abs")) {                    expect('(');                    openParens++;                    Object arg = evalEq().eval();                    if (arg instanceof Double) {                        arg = new Double(Math.abs(((Double)arg).doubleValue()));                    } else {                        arg = "abs"+format(arg);                    }                    eq.addIdentifier(arg);                }                else if (tokenizer.sval.equalsIgnoreCase("sqrt")) {                    expect('(');                    openParens++;                    Object arg = evalEq().eval();                    if (arg instanceof Double) {                        arg = new Double(Math.sqrt(((Double)arg).doubleValue()));                    } else {                        arg = "sqrt"+format(arg);                    }                    eq.addIdentifier(arg);                }                else if (tokenizer.sval.equalsIgnoreCase("int")) {                    expect('(');                    openParens++;                    Object arg = evalEq().eval();                    if (arg instanceof Double) {                        arg = new Double((int)(((Double)arg).doubleValue()));                    } else {                        arg = "int"+format(arg);                    }                    eq.addIdentifier(arg);                }                else {                    // identifier                    eq.addIdentifier(tokenizer.sval);                }            }            else if (tt == '*') {                eq.addOp(Op.MULT);            }            else if (tt == '/') {                eq.addOp(Op.DIV);            }            else if (tt == '+') {                eq.addOp(Op.PLUS);            }            else if (tt == '-') {                eq.addOp(Op.MINUS);            }            else if (tt == '<') {                tt = tokenizer.nextToken();                if (tt == '=') {                    eq.addOp(Op.LTOE);                } else {                    tokenizer.pushBack();                    eq.addOp(Op.LT);                }            }            else if (tt == '>') {                tt = tokenizer.nextToken();                if (tt == '=') {                    eq.addOp(Op.GTOE);                } else {                    tokenizer.pushBack();                    eq.addOp(Op.GT);                }            }            else if (tt == '=') {                expect('=');                eq.addOp(Op.EQ);            }            else if (tt == '!') {                expect('=');                eq.addOp(Op.NE);            }            else if (tt == '?') {                eq.addOp(Op.COND);/*                Object arg1 = evalEq().eval();                if (tokenizer.ttype != ':') throw new ParseException("Expected ':' after conditional");                Object arg2 = evalEq().eval();                SimpleEq condval = new SimpleEq(arg1, Op.CONDCHOICE, arg2);                eq.addIdentifier(condval);*/            }            else if (tt == ':') {       // end conditional true arg                eq.addOp(Op.CONDCHOICE);            }        }    }    /**     * 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 Object parseNumber() throws IOException, ParseException {        int tt = tokenizer.nextToken();        if (tt == StreamTokenizer.TT_NUMBER) {            double val = tokenizer.nval;            // peek ahead to check if exponential, or multiplier            tokenizer.ordinaryChar('e');            tokenizer.ordinaryChar('E');            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 ParseException("Invalid token");                }            }            else if (tt == StreamTokenizer.TT_WORD) {                if (tokenizer.sval.equalsIgnoreCase("g")) {                    val = val * 1e9;                } else if (tokenizer.sval.equalsIgnoreCase("meg")) {

⌨️ 快捷键说明

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