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

📄 scanner.java

📁 JAVA在编译原理上的应用。
💻 JAVA
字号:
package lolo;import java.io.Serializable;import java.io.IOException;import java.util.Map;import java.util.HashMap;import java.util.Iterator;import lolo.Scan.State;/** A <tt>Scanner</tt> collects <tt>Scan</tt> objects to maintain a lexical scanner. * The characters are read from an <tt>Input</tt> object. * <p>A <tt>Scanner</tt> can be serialized to be reused. * * @author <a href="http://www.inf.uos.de/bernd" target="_blank">Bernd K&uuml;hl</a>           (<a href="mailto:bernd@informatik.uni-osnabrueck.de">bernd@informatik.uni-osnabrueck.de</a>) * @see lolo.Mux * @see lolo.Scan * @see lolo.Input * @see lolo.Scanner#scan(Input) */public class Scanner implements Serializable {    /** Array of all <tt>Scan</tt> objects.     *     * @see lolo.Scan     */    protected Scan[] scans = new Scan[1];    /** Indexes in <tt>scans</tt>. */    protected int next, max = scans.length;        /** Constructs an empty <tt>Scanner</tt>. */    public Scanner() {}    /** Constructs a <tt>Scanner</tt> managing one <tt>Scan</tt> instance.     *     * @see lolo.Scan     */    public Scanner(Scan scan) {        add(scan);    }    /** Constructs a <tt>Scanner</tt> managing many <tt>Scan</tt> instances.     *     * @see lolo.Scan     */    public Scanner(Scan [] scans) {        if (scans == null)            throw new IllegalArgumentException("scans is null");        for (int i = 0; i < scans.length; i++)             add(scans[i]);    }    /** Marks if this <tt>Scanner</tt> is packed.     *     * @see lolo.Scanner#pack()     */    protected boolean packed;        /** Adds a <tt>Scan</tt> instance to this <tt>Scanner</tt>.     *     * @param scan the added recognizer.     * @throws IllegalArgumentException if the argument is <tt>null</tt>.     * @see lolo.Scan     */    public boolean add(Scan scan) throws IllegalArgumentException {        if (scan == null)            throw new IllegalArgumentException("scan is null");        if (contains(scan)) return false;        if (max == next) {            Scan [] help = new Scan[max*=2];            System.arraycopy(scans, 0, help, 0, max/2);            scans = help;        }        scans[next++] = scan;        packed = false;        return true;    }    /** Adds all elements of a <tt>Scan</tt> array to this <tt>Scanner</tt>.     *     * @param scans the added recognizers.     * @throws IllegalArgumentException if the argument or the elements of the argument are <tt>null</tt>.     * @see lolo.Scan     */    public boolean add(Scan [] scans) throws IllegalArgumentException {        if (scans == null)            throw new IllegalArgumentException("scan is null");        boolean b = false;        for (int i = 0; i < scans.length; i++)             b |= add(scans[i]);        return b;    }    /** Removes a <tt>Scan</tt> instance to this <tt>Scanner</tt>.     *     * @see lolo.Scan     */	public boolean remove(Scan scan) {        for (int i = 0; i < next; i++)            if (scans[i].equals(scan)) {                if(i <= next-1)                    System.arraycopy(scans, i+1, scans, i, next-(i+1));                next--;                packed = false;                return true;            }        return false;	}    /** Returns if this <tt>Scanner</tt> contains the <tt>Scan</tt> instance. The check is done by using     * <tt>equals()</tt>.     *     * @return if this <tt>Scanner</tt> contains the <tt>Scan</tt> instance.     * @see lolo.Scan     */	public boolean contains(Scan scan) {        for (int i = 0; i < next; i++)            if (scans[i].equals(scan))                return true;        return false;	}    /** Returns if this <tt>Scanner</tt> is packed.     *     * @return if this <tt>Scanner</tt> is packed.     */    public boolean packed() {        return packed;    }        /** Array holding for every character-index a <tt>Scan</tt> or <tt>Mux</tt> object.     *     * @see lolo.Mux     * @see lolo.Scan     */    public transient Scan[] table;        /** Packs the <tt>table</tt> with <tt>Scan</tt> or <tt>Mux</tt> objects.     *     * @see lolo.Mux     * @see lolo.Scan     */    public void pack() {        if (packed) return;        	    if (debug)            System.err.println("start packing...");                table = new Scan[unicode ? Character.MAX_VALUE+1 : 128];        for (int ch = 0; ch <= (unicode ? Character.MAX_VALUE : 127); ch++) {            for (int i = 0; i < next; i++) {                Scan scan = scans[i];                scan.reset();                State state = scan.nextChar((char) ch);                if (state.more || state.found)                    enter(ch, scan);            }            if (debug && ch > 0 && (ch % 5000 == 00))                System.err.println("packing up to "+ch+" done...");        }	    if (debug)            System.err.println("replacing Mux objects...");        // replace equal Mux by one Mux and reset all recognizers        Map muxs = new HashMap();        int countMux = 0;        for (int ch = 0; ch <= (unicode ? Character.MAX_VALUE : 127); ch++) {            Scan scan = table[ch];            if (scan instanceof Mux) {                Mux mux = (Mux) scan;                if (muxs.containsKey(mux)) {                    table[ch] = (Mux) muxs.get(mux);                } else {                    muxs.put(mux, mux);  // better use a Set collection....                    countMux++;                }            }        }        	    if (debug)            System.err.println(countMux+" Mux objects...");        // reset all scans and all mux objects        Iterator iterator = muxs.keySet().iterator();        while (iterator.hasNext())            ((Scan) iterator.next()).reset();        for (int i = 0; i < next; i++)            scans[i].reset();        packed = true;        	    if (debug)            System.err.println("packing done...");    }        /** Enters <tt>scan</tt> at index <tt>index</tt> into the table.     * This may creates a <tt>Mux</tt> object.    *     * @see lolo.Mux     * @see lolo.Scan     * @param index index into the table for <tt>scan</tt>.     * @param scan the new <tt>Scan</tt> object for table index <tt>index</tt>.     */    protected void enter(int index, Scan scan) {        if (table[index] != null)            if (table[index] instanceof Mux)                ((Mux) table[index]).add(scan);            else                table[index] = new Mux(table[index], scan);        else            table[index] = scan;    }        /** debug mode? */    public boolean debug = false;        /** Finds and returns the next winning <tt>Scan</tt> object or <tt>null</tt> at EOF.     *     * @return the winning <tt>Scan</tt> object or <tt>null</tt> at EOF.     * @param the character input source.     * @throws IllegalCharacterException if no symbol was found.     * @throws IOException if an I/O error occured.     */    public Scan scan(Input input) throws IllegalCharacterException, IOException {        if (!packed) pack();        while (true) {            input.setStartSymbol();            int first = input.next();            int symbolLength = -1, length = 1;                        if(!unicode && 127 < first)                 throw new IllegalCharacterException((char) first, input.toString());                            int ch = first;            if (ch < 0)                return null;            Scan scan = table[ch];            if (scan == null)                throw new IllegalCharacterException((char) first, input.toString());            scan.reset();                        boolean found = false;            input.mark();             while (true) {                if(!unicode && 127 < ch)                     throw new IllegalCharacterException((char) ch, input.toString());                State state = scan.nextChar((char) ch);                if (state.found) {                    input.mark();                    found = true;                    symbolLength = length;                }                if (!state.more)                    break;                ch = input.next();                length++;                if (ch < 0) break;            }                        if (!found)                throw new IllegalCharacterException((char) first, input.toString());                            input.pushBackToMarked();            input.unmark();                        Scan winner = scan instanceof Mux ? ((Mux) scan).winner() : scan;            winner.action(input.buffer, input.startOfSymbol, symbolLength);            if (!winner.getIgnore())                return winner ;        }    }        /** Unicode (or ASCII) mode? */    protected boolean unicode;        /** Set Unicode (or ASCII) mode mode.     *     * @param the new mode.     */    public void setUnicode(boolean unicode) {        packed = this.unicode == unicode;        this.unicode = unicode;    }    /** Returns if the current mode is Unicode.      *     * @return if the current mode is Unicode.     */    public boolean getUnicode() {        return unicode;    }        /** Deserializes the object. */	private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {        stream.defaultReadObject();        int length = stream.readInt();        table = new Scan[length];        int pairs = stream.readInt();        int n = 0;        while (pairs > 0) {            Scan s = (Scan) stream.readObject();            String string = (String) stream.readObject();            pairs--;            for (int i = 0 ; i < string.length(); i++) {                table[(int) string.charAt(i)] = s;                n++;            }        }    }    /** Serializes the object. */	private void writeObject(java.io.ObjectOutputStream stream) throws IOException {        stream.defaultWriteObject();        Map map = new HashMap();        for (int i = 0; i < this.table.length; i++) {            Scan s = (Scan) this.table[i];            if (s != null)                if (map.containsKey(s))                    ((StringBuffer) map.get(s)).append((char) i);                else                    map.put(s, new StringBuffer().append((char) i));        }        stream.writeInt(table.length);        stream.writeInt(map.size());        Iterator keys = map.keySet().iterator();        while (keys.hasNext()) {            Scan s = (Scan) keys.next();            String string = ((StringBuffer) map.get(s)).toString();            stream.writeObject(s);            stream.writeObject(string);        }    }    	/** An <tt>IllegalCharacterException</tt> is thrown, when no <tt>Scan</tt> instance matches     * the current character.     *     * @author <a href="http://www.inf.uos.de/bernd" target="_blank">Bernd K&uuml;hl</a>               (<a href="mailto:bernd@informatik.uni-osnabrueck.de">bernd@informatik.uni-osnabrueck.de</a>)     */    public static class IllegalCharacterException extends Exception {        /** The illegal character. */        protected char ch;        /** Constructs an <tt>IllegalCharacterException</tt>.         *         * @param ch the illegal character.         * @param message the message.         */        public IllegalCharacterException(char ch, String message) {            super(message);            this.ch = ch;        }        /** Return the illegal character.         *         * @return the illegal character.         */        public char getChar() { return ch; }        /** Returns <tt>"IllegalCharacterException["+ch+","+getMessage()+"]"</tt>         *         * @return <tt>"IllegalCharacterException["+ch+","+getMessage()+"]"</tt>         */        public String toString() {            return "IllegalCharacterException["+ch+","+getMessage()+"]";        }    }}

⌨️ 快捷键说明

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