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

📄 spicenetlistreader.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: SpiceNetlistReader.java * * Copyright (c) 2006 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.tool.io.input.spicenetlist;import java.io.*;import java.util.*;/** * Parse a spice netlist. Ignores comments, and * coalesces split lines into single lines. * User: gainsley * Date: Aug 3, 2006 */public class SpiceNetlistReader {    private File file;    BufferedReader reader;    private StringBuffer lines;    private int lineno;    private HashMap<String,String> options = new LinkedHashMap<String,String>();    private HashMap<String,String> globalParams = new LinkedHashMap<String,String>();    private List<SpiceInstance> topLevelInstances = new ArrayList<SpiceInstance>();    private HashMap<String,SpiceSubckt> subckts = new LinkedHashMap<String,SpiceSubckt>();    private List<String> globalNets = new ArrayList<String>();    private SpiceSubckt currentSubckt;    public SpiceNetlistReader() {        reader = null;        lines = null;    }    public HashMap<String,String> getOptions() { return options; }    public HashMap<String,String> getGlobalParams() { return globalParams; }    public List<SpiceInstance> getTopLevelInstances() { return topLevelInstances; }    public Collection<SpiceSubckt> getSubckts() { return subckts.values(); }    public List<String> getGlobalNets() { return globalNets; }    public SpiceSubckt getSubckt(String name) {        return subckts.get(name.toLowerCase());    }//    private static final boolean DEBUG = true;    // ============================== Parsing ==================================//    enum TType { PAR, PARVAL, WORD }    public void readFile(String fileName, boolean verbose) throws FileNotFoundException {        file = new File(fileName);        reader = new BufferedReader(new FileReader(fileName));        lines = new StringBuffer();        currentSubckt = null;        String line;        lineno = 0;        try {            while ((line = readLine()) != null) {                line = line.trim();                String [] tokens = getTokens(line);                if (tokens.length == 0) continue;                String keyword = tokens[0].toLowerCase();                if (keyword.equals(".include")) {                    if (tokens.length < 2) {                        prErr("No file specified for .include");                        continue;                    }                    String ifile = tokens[1];                    if (!ifile.startsWith("/") && !ifile.startsWith("\\")) {                        // relative path, add to current path                        File newFile = new File(file.getParent(), ifile);                        ifile = newFile.getPath();                    }                    File saveFile = file;                    BufferedReader saveReader = reader;                    StringBuffer saveLines = lines;                    int saveLine = lineno;                    try {                        if (verbose)                            System.out.println("Reading include file "+ifile);                        readFile(ifile, verbose);                    } catch (FileNotFoundException e) {                        file = saveFile;                        lineno = saveLine;                        prErr("Include file does not exist: "+ifile);                    }                    file = saveFile;                    reader = saveReader;                    lines = saveLines;                    lineno = saveLine;                }                else if (keyword.startsWith(".opt")) {                    parseOptions(options, 1, tokens);                }                else if (keyword.equals(".param")) {                    parseParams(globalParams, 1, tokens);                }                else if (keyword.equals(".subckt")) {                    currentSubckt = parseSubckt(tokens);                    if (currentSubckt != null && subckts.containsKey(currentSubckt.getName().toLowerCase())) {                        prErr("Subckt "+currentSubckt.getName()+                                " already defined");                        continue;                    }                    subckts.put(currentSubckt.getName().toLowerCase(), currentSubckt);                }                else if (keyword.equals(".global")) {                    for (int i=1; i<tokens.length; i++) {                        if (!globalNets.contains(tokens[i]))                            globalNets.add(tokens[i]);                    }                }                else if (keyword.startsWith(".ends")) {                    currentSubckt = null;                }                else if (keyword.startsWith(".end")) {                    // end of file                }                else if (keyword.startsWith("x")) {                    SpiceInstance inst = parseSubcktInstance(tokens);                    addInstance(inst);                }                else if (keyword.startsWith("r")) {                    SpiceInstance inst = parseResistor(tokens);                    addInstance(inst);                }                else if (keyword.startsWith("c")) {                    SpiceInstance inst = parseCapacitor(tokens);                    addInstance(inst);                }                else if (keyword.startsWith("m")) {                    SpiceInstance inst = parseMosfet(tokens);                    addInstance(inst);                }                else if (keyword.equals(".protect") || keyword.equals(".unprotect")) {                    // ignore                }                else {                    prWarn("Parser does not recognize: "+line);                }            }            reader.close();        } catch (IOException e) {            System.out.println("Error reading file "+file.getPath()+": "+e.getMessage());        }    }    private void prErr(String msg) {        System.out.println("Error ("+getLocation()+"): "+msg);    }    private void prWarn(String msg) {        System.out.println("Warning ("+getLocation()+"): "+msg);    }    private String getLocation() {        return file.getName()+":"+lineno;    }    /**     * Get the tokens in a line.  Tokens are separated by whitespace,     * unless that whitespace is surrounded by single quotes, or parentheses.     * When quotes are used, those quotes are removed from the string literal.     * The construct <code>name=value</code> is returned as three tokens,     * the second being the char '='.     * @param line the line to parse     * @return an array of tokens     */    private String [] getTokens(String line) {        List<String> tokens = new ArrayList<String>();        int start = 0;        boolean inquotes = false;        int inparens = 0;        int i;        for (i=0; i<line.length(); i++) {            char c = line.charAt(i);            if (inquotes) {                if (c == '\'') {                    if (inparens > 0) continue;                    // end string literal                    tokens.add(line.substring(start, i));                    start = i+1;                    inquotes = false;                }            }            else if (c == '\'') {                if (inparens > 0) continue;                inquotes = true;                if (start != i) {                    prErr("Improper use of open quote '");                    break;                }                start = i+1;            }            // else !inquotes:            else if (Character.isWhitespace(c) && inparens == 0) {                // end of token (unless just more whitespace)                if (start < i)                    tokens.add(line.substring(start, i));                start = i+1;            }            else if (c == '(') {                inparens++;            }            else if (c == ')') {                if (inparens == 0) {                    prErr("Too many ')'s");                    break;                }                inparens--;            }            else if (c == '=') {                if (start < i)                    tokens.add(line.substring(start, i));                tokens.add("=");                start = i+1;            }            else if (c == '*') {                break; // rest of line is comment            }        }        if (start < i) {            tokens.add(line.substring(start, i));        }        if (inparens != 0)            prErr("Unmatched parentheses");        // join {par, =, val} to {par=val}        List<String> joined = new ArrayList<String>();        for (int j=0; j<tokens.size(); j++) {            if (tokens.get(j).equals("=")) {                if (j == 0) {                    prErr("No right hand side to assignment");                } else if (j == tokens.size()-1) {                    prErr("No left hand side to assignment");                } else {                    int last = joined.size() - 1;                    joined.set(last, joined.get(last)+"="+tokens.get(++j));                }            } else {                joined.add(tokens.get(j));            }        }        String ret [] = new String[joined.size()];        for (int k=0; k<joined.size(); k++)            ret[k] = joined.get(k);        return ret;    }    private void parseOptions(HashMap<String,String> map, int start, String [] tokens) {        for (int i=start; i<tokens.length; i++) {            int e = tokens[i].indexOf('=');            String pname = tokens[i];            String value = "true";            if (e > 0) {                pname = tokens[i].substring(0, e);                value = tokens[i].substring(e+1);            }            if (pname == null || value == null) {                prErr("Bad option value: "+tokens[i]);                continue;            }            map.put(pname.toLowerCase(), value);        }    }    private void parseParams(HashMap<String,String> map, int start, String [] tokens) {        for (int i=start; i<tokens.length; i++) {            parseParam(map, tokens[i], null);        }    }    private void parseParam(HashMap<String,String> map, String parval, String defaultParName) {        int e = parval.indexOf('=');

⌨️ 快捷键说明

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