All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.monte.media.io.StreamPosTokenizer Maven / Gradle / Ivy

The newest version!

package org.monte.media.io;

import java.io.*;
import java.util.Vector;




public class StreamPosTokenizer
         {
    private Reader reader = null;


    private int readpos = 0;


    private int startpos = -1, endpos = -1;
    private Vector unread = new Vector();

    private char buf[] = new char[20];


    private int peekc = NEED_CHAR;

    private static final int NEED_CHAR = Integer.MAX_VALUE;
    private static final int SKIP_LF = Integer.MAX_VALUE - 1;

    private boolean pushedBack;
    private boolean forceLower;

    private int lineno = 1;

    private boolean eolIsSignificantP = false;
    private boolean slashSlashCommentsP = false;
    private boolean slashStarCommentsP = false;


    private char[] slashSlash = new char[] {'/','/'};
    private char[] slashStar = new char[] {'/','*'};
    private char[] starSlash = new char[] {'*','/'};

    private byte ctype[] = new byte[256];
    private static final byte CT_WHITESPACE = 1;
    private static final byte CT_DIGIT = 2;
    private static final byte CT_ALPHA = 4;
    private static final byte CT_QUOTE = 8;
    private static final byte CT_COMMENT = 16;

    private boolean isParseHexNumbers = false;
    private boolean isParseExponents = false;


    public int ttype = TT_NOTHING;


    public static final int TT_EOF = -1;


    public static final int TT_EOL = '\n';


    public static final int TT_NUMBER = -2;


    public static final int TT_WORD = -3;


    private static final int TT_NOTHING = -4;


    public String sval;


    public double nval;


    public StreamPosTokenizer() {
        wordChars('a', 'z');
        wordChars('A', 'Z');
        wordChars(128 + 32, 255);
        whitespaceChars(0, ' ');
        commentChar('/');
        quoteChar('"');
        quoteChar('\'');
        parseNumbers();
    }



    public StreamPosTokenizer(Reader r) {
        this();
        if (r == null) {
            throw new NullPointerException();
        }
        reader = r;
    }


    public void setReader(Reader r) {
        this.reader = r;
        readpos = 0;
        unread.clear();
        peekc = NEED_CHAR;
        pushedBack = false;
        forceLower = false;
        lineno = 0;
        startpos = endpos = -1;
        ttype = TT_NOTHING;
    }


    public void resetSyntax() {
        for (int i = ctype.length; --i >= 0;)
            ctype[i] = 0;
    }


    public void wordChars(int low, int hi) {
        if (low < 0)
            low = 0;
        if (hi >= ctype.length)
            hi = ctype.length - 1;
        while (low <= hi)
            ctype[low++] |= CT_ALPHA;
    }


    public void whitespaceChars(int low, int hi) {
        if (low < 0)
            low = 0;
        if (hi >= ctype.length)
            hi = ctype.length - 1;
        while (low <= hi)
            ctype[low++] = CT_WHITESPACE;
    }


    public void ordinaryChars(int low, int hi) {
        if (low < 0)
            low = 0;
        if (hi >= ctype.length)
            hi = ctype.length - 1;
        while (low <= hi)
            ctype[low++] = 0;
    }


    public void ordinaryChar(int ch) {
        if (ch >= 0 && ch < ctype.length)
            ctype[ch] = 0;
    }


    public void commentChar(int ch) {
        if (ch >= 0 && ch < ctype.length)
            ctype[ch] = CT_COMMENT;
    }


    public void quoteChar(int ch) {
        if (ch >= 0 && ch < ctype.length)
            ctype[ch] = CT_QUOTE;
    }


    public void parseNumbers() {
        for (int i = '0'; i <= '9'; i++)
            ctype[i] |= CT_DIGIT;
        ctype['.'] |= CT_DIGIT;
        ctype['-'] |= CT_DIGIT;

    }

    public void parsePlusAsNumber() {
        ctype['+'] |= CT_DIGIT;
    }


    public void parseHexNumbers() {
        parseNumbers();
        isParseHexNumbers = true;
    }

    public void parseExponents() {
        parseNumbers();
        isParseExponents = true;
    }


    public void eolIsSignificant(boolean flag) {
        eolIsSignificantP = flag;
    }


    public void slashStarComments(boolean flag) {
        slashStarCommentsP = flag;
    }


    public void slashSlashComments(boolean flag) {
        slashSlashCommentsP = flag;
    }


    public void lowerCaseMode(boolean fl) {
        forceLower = fl;
    }


    private int read() throws IOException {

        int data;
        if (unread.size() > 0) {
            data = ((Integer) unread.lastElement()).intValue();
            unread.removeElementAt(unread.size() - 1);
        } else {
            data = reader.read();
        }
        if (data != -1) { readpos++; }
        return data;
    }

    private void unread(int c) {
        unread.addElement(c);
        readpos--;
    }


    @SuppressWarnings("empty-statement")
    public int nextToken() throws IOException {
        if (pushedBack) {
            pushedBack = false;
            return ttype;
        }
        byte ct[] = ctype;
        sval = null;

        int c = peekc;
        if (c < 0)
            c = NEED_CHAR;
        if (c == SKIP_LF) {
            c = read();
            if (c < 0) {

                startpos = endpos = readpos - 1;
                return ttype = TT_EOF;
            }
            if (c == '\n')
                c = NEED_CHAR;
        }
        if (c == NEED_CHAR) {
            c = read();
            if (c < 0) {

                startpos = endpos = readpos - 1;
                return ttype = TT_EOF;
            }
        }
        ttype = c;


        peekc = NEED_CHAR;

        int ctype = c < 256 ? ct[c] : CT_ALPHA;
        while ((ctype & CT_WHITESPACE) != 0) {
            if (c == '\r') {
                lineno++;
                if (eolIsSignificantP) {
                    peekc = SKIP_LF;

                    startpos = endpos = readpos - 1;
                    return ttype = TT_EOL;
                }
                c = read();
                if (c == '\n')
                    c = read();
            } else {
                if (c == '\n') {
                    lineno++;
                    if (eolIsSignificantP) {

                        startpos = endpos = readpos - 1;
                        return ttype = TT_EOL;
                    }
                }
                c = read();
            }
            if (c < 0) {

                startpos = endpos = readpos;
                return ttype = TT_EOF;
            }
            ctype = c < 256 ? ct[c] : CT_ALPHA;
        }


        startpos = readpos - 1;


        hex: if (((ctype & CT_DIGIT) != 0) &&
                c == '0' && isParseHexNumbers) {
            c = read();
            if (c == 'x') {
                int digits = 0;
                long hval = 0;
                while (digits < 16) {
                    c = read();
                    if (c >= '0' && c <= '9') {
                        hval = (hval << 4) | (c - '0');
                    } else if (c >= 'A' && c <= 'F') {
                        hval = (hval << 4) | (c - 'A' + 10);
                    } else if (c >= 'a' && c <= 'f') {
                        hval = (hval << 4) | (c - 'a' + 10);
                    } else {
                        unread(c);
                        if (digits == 0) {
                            sval = "0x";
                            endpos = readpos - 1;
                            return ttype = TT_WORD;
                        } else {
                            nval = (double) hval;
                            endpos = readpos - 1;
                            return ttype = TT_NUMBER;
                        }
                    }
                    digits++;
                }
                nval = (double) hval;
                endpos = readpos - 1;
                return ttype = TT_NUMBER;
            } else {
                unread(c);
                c = '0';
            }
        }

        digit: if ((ctype & CT_DIGIT) != 0) {
            int digits = 0;
            boolean neg = false;
            if (c == '-') {
                c = read();
                if (c != '.' && (c < '0' || c > '9')) {
                    peekc = c;

                    if (('-' & CT_ALPHA) != 0) {
                        unread(c);
                        c = '-';
                        break digit;
                    } else {
                        endpos = readpos - 1;
                        return ttype = '-';
                    }
                }
                neg = true;
            } else if (c == '+') {
                c = read();
                if (c != '.' && (c < '0' || c > '9')) {
                    peekc = c;

                    if (('+' & CT_ALPHA) != 0) {
                        unread(c);
                        c = '+';
                        break digit;
                    } else {
                        endpos = readpos - 1;
                        return ttype = '-';
                    }
                }
                neg = false;
            }

            double v = 0;
            int decexp = 0;
            int seendot = 0;
            while (true) {
                if (c == '.' && seendot == 0)
                    seendot = 1;
                else if ('0' <= c && c <= '9') {
                    digits++;
                    v = v * 10 + (c - '0');
                    decexp += seendot;
                } else
                    break;
                c = read();
            }
            peekc = c;
            if (decexp != 0) {
                double denom = 10;
                decexp--;
                while (decexp > 0) {
                    denom *= 10;
                    decexp--;
                }

                v = v / denom;
            }
            nval = neg ? -v : v;

            endpos = (c == -1) ? readpos - 1 : readpos - 2;
            if (digits == 0) {
                if (('.' & CT_ALPHA) != 0) {
                    unread(c);
                    if (neg) {
                        unread('.');
                        c = '-';
                    } else {
                        read();
                        c = '.';
                    }
                    break digit;
                } else {
                    return ttype = '.';
                }
            } else {
                if (isParseExponents) {
                    if (c == 'E' || c == 'e') {
                        c = read();

                        digits = 0;
                        neg = false;
                        if (c == '-') {
                            c = read();
                            if (c < '0' || c > '9') {
                                unread(c);
                                unread('E');
                                return ttype = TT_NUMBER;
                            }
                            neg = true;
                        }
                        v = 0;
                        decexp = 0;
                        while (true) {
                            if ('0' <= c && c <= '9') {
                                digits++;
                                v = v * 10 + (c - '0');
                            } else {
                                break;
                            }
                            c = read();
                        }
                        peekc = c;
                        nval *= Math.pow(10, (neg) ? -v : v);
                    }
                }
                return ttype = TT_NUMBER;
            }
        }

        if ((ctype & CT_ALPHA) != 0) {
            int i = 0;
            do {
                if (i >= buf.length) {
                    char nb[] = new char[buf.length * 2];
                    System.arraycopy(buf, 0, nb, 0, buf.length);
                    buf = nb;
                }
                buf[i++] = (char) c;
                c = read();
                ctype = c < 0 ? CT_WHITESPACE : c < 256 ? ct[c] : CT_ALPHA;
            } while ((ctype & (CT_ALPHA | CT_DIGIT)) != 0);
            peekc = c;
            sval = String.copyValueOf(buf, 0, i);
            if (forceLower)
                sval = sval.toLowerCase();

            endpos = (c == -1) ? readpos - 1 : readpos - 2;
            return ttype = TT_WORD;
        }

        if ((ctype & CT_QUOTE) != 0) {
            ttype = c;
            int i = 0;

            int d = read();
            while (d >= 0 && d != ttype && d != '\n' && d != '\r') {
                if (d == '\\') {
                    c = read();
                    int first = c;
                    if (c >= '0' && c <= '7') {
                        c = c - '0';
                        int c2 = read();
                        if ('0' <= c2 && c2 <= '7') {
                            c = (c << 3) + (c2 - '0');
                            c2 = read();
                            if ('0' <= c2 && c2 <= '7' && first <= '3') {
                                c = (c << 3) + (c2 - '0');
                                d = read();
                            } else
                                d = c2;
                        } else
                            d = c2;
                    } else {
                        switch (c) {
                            case 'a':
                                c = 0x7;
                                break;
                            case 'b':
                                c = '\b';
                                break;
                            case 'f':
                                c = 0xC;
                                break;
                            case 'n':
                                c = '\n';
                                break;
                            case 'r':
                                c = '\r';
                                break;
                            case 't':
                                c = '\t';
                                break;
                            case 'v':
                                c = 0xB;
                                break;
                        }
                        d = read();
                    }
                } else {
                    c = d;
                    d = read();
                }
                if (i >= buf.length) {
                    char nb[] = new char[buf.length * 2];
                    System.arraycopy(buf, 0, nb, 0, buf.length);
                    buf = nb;
                }
                buf[i++] = (char)c;
            }


            peekc = (d == ttype) ? NEED_CHAR : d;

            sval = String.copyValueOf(buf, 0, i);

            endpos = readpos - 2;
            return ttype;
        }



        if (slashSlashCommentsP && c == slashSlash[0]
                || slashStarCommentsP && c == slashStar[0]) {
            if (c == slashStar[0] && slashStar.length == 1) {


                while ((c = read()) != starSlash[0]) {
                    if (c == '\r') {
                        lineno++;
                        c = read();
                        if (c == '\n') {
                            c = read();
                        }
                    } else {
                        if (c == '\n') {
                            lineno++;
                            c = read();
                        }
                    }
                    if (c < 0) {
                        endpos = readpos;
                        return ttype = TT_EOF;
                    }
                }
                return nextToken();
            } else if (c == slashSlash[0] && slashSlash.length == 1) {


                while ((c = read()) != '\n' && c != '\r' && c >= 0);
                peekc = c;
                return nextToken();
            } else {


                c = read();
                if (c == slashStar[1] && slashStarCommentsP) {
                    int prevc = 0;
                    while ((c = read()) != starSlash[1] || prevc != starSlash[0]) {
                        if (c == '\r') {
                            lineno++;
                            c = read();
                            if (c == '\n') {
                                c = read();
                            }
                        } else {
                            if (c == '\n') {
                                lineno++;
                                c = read();
                            }
                        }
                        if (c < 0) {
                            endpos = readpos;
                            return ttype = TT_EOF;
                        }
                        prevc = c;
                    }
                    return nextToken();
                } else if (c == slashSlash[1] && slashSlashCommentsP) {
                    while ((c = read()) != '\n' && c != '\r' && c >= 0);
                    peekc = c;
                    return nextToken();
                } else {

                    if ((ct[slashSlash[0]] & CT_COMMENT) != 0) {
                        while ((c = read()) != '\n' && c != '\r' && c >= 0);
                        peekc = c;
                        return nextToken();
                    } else {
                        peekc = c;

                        endpos = readpos - 2;
                        return ttype = slashSlash[0];
                    }
                }
            }
        }

        if ((ctype & CT_COMMENT) != 0) {
            while ((c = read()) != '\n' && c != '\r' && c >= 0);
            peekc = c;

            return nextToken();
        }


        endpos = readpos - 1;
        return ttype = c;
    }

    public int nextChar() throws IOException {
        if (pushedBack) {
            throw new IllegalStateException("can't read char when a token has been pushed back");
        }
        if (peekc == NEED_CHAR) {
            return read();
        } else {
            int ch = peekc;
            peekc = NEED_CHAR;
            return ch;
        }
    }

    public void pushCharBack(int ch) throws IOException {
        if (pushedBack) {
            throw new IllegalStateException("can't push back char when a token has been pushed back");
        }
        if (peekc == NEED_CHAR) {
            unread(ch);
        } else {
            unread(peekc);
            peekc = NEED_CHAR;
            unread(ch);
        }
    }

    public void setSlashStarTokens(String slashStar, String starSlash) {
        if (slashStar.length() != starSlash.length()) {
            throw new IllegalArgumentException("SlashStar and StarSlash tokens must be of same length: '"+slashStar+"' '"+starSlash+"'");
        }
        if (slashStar.length() < 1 || slashStar.length() > 2) {
            throw new IllegalArgumentException("SlashStar and StarSlash tokens must be of length 1 or 2: '"+slashStar+"' '"+starSlash+"'");
        }
        this.slashStar = slashStar.toCharArray();
        this.starSlash = starSlash.toCharArray();
        commentChar(this.slashStar[0]);
    }

    public void setSlashSlashToken(String slashSlash) {
        if (slashSlash.length() < 1 || slashSlash.length() > 2) {
            throw new IllegalArgumentException("SlashSlash token must be of length 1 or 2: '"+slashSlash+"'");
        }
        this.slashSlash = slashSlash.toCharArray();
        commentChar(this.slashSlash[0]);
    }


    public void pushBack() {
        if (ttype != TT_NOTHING)
            pushedBack = true;
    }


    public int lineno() {
        return lineno;
    }


    public int getStartPosition() {
        return startpos;
    }

    public void setStartPosition(int p) {
        startpos = p;
    }

    public int getEndPosition() {
        return endpos;
    }


    public void consumeGreedy(String greedyToken) {
        if (greedyToken.length() < sval.length()) {
            pushBack();
            setStartPosition(getStartPosition() + greedyToken.length());
            sval = sval.substring(greedyToken.length());
        }
    }

    @Override
    public String toString() {
        String ret;
        switch (ttype) {
            case TT_EOF:
                ret = "EOF";
                break;
            case TT_EOL:
                ret = "EOL";
                break;
            case TT_WORD:
                ret = sval;
                break;
            case TT_NUMBER:
                ret = "n=" + nval;
                break;
            case TT_NOTHING:
                ret = "NOTHING";
                break;
            default:{
                char s[] = new char[3];
                s[0] = s[2] = '\'';
                s[1] = (char) ttype;
                ret = new String(s);
                break;
            }
        }
        return "Token[" + ret + "], line " + lineno;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy