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

📄 scanner.java

📁 是有关解释器的.用JAVA编写.可以解释一般的JAVA程序.
💻 JAVA
字号:
/** * The scanner transforms the input file into a stream of tokens. The
 * "lookahead" may be used to exam the token following the current token. This
 * is sometimes required when the current token does not reveal the following
 * construct (e.g. variable definitions and method definition both start with an
 * identifier). The scanner has to be advanced to the next token explicitly by
 * calling advance().
 * 
 * @see Token */

public class Scanner {
	private LexemReader lexemReader;
	private Token currentToken;
	private Token lookAheadToken;

    /**
     * Creates an instance of the scanner and tokenizes the input file.
     * 
     * @param fileName
     *            name of the input file
     * @throws ScannerException
     *             If an I/O exception occured
     */
    Scanner(String fileName) throws ScannerException {
        lexemReader = new LexemReader(fileName);

        advance(); // read first token into currentToken
    }

    /**
     * Returns the current token without advancing to the next.
     * 
     * @see Token
     */
    Token token() {
        return currentToken;
    }

    /**
     * Returns the following token (again without advancing).
     * 
     * @see Token
     * @throws ScannerException
     *             I/O error or illegal character.
     */
    Token followingToken() throws ScannerException {
        // if lookahead has been done before, don't read another token
        if (lookAheadToken == null)
            lookAheadToken = scanToken();

        return lookAheadToken;
    }

    /**
     * Advances the scanner to the next token.
     * 
     * @throws ScannerException
     *             I/O error or illegal character.
     */
    void advance() throws ScannerException {
        if (lookAheadToken != null) {
            currentToken = lookAheadToken;
            lookAheadToken = null; // erase lookahead cache; causing real read
                                   // next time and re-enable lookahead-read
        } else
            currentToken = scanToken();
    }

    private Token scanToken() throws ScannerException {
        int ch = lexemReader.nextNonWhiteCharacter();

        // return EOF token if no more characters are availabe
        if (ch == -1)
            return new SimpleToken(lexemReader.line(), lexemReader.pos(), '~');

        // continue with a character rather than an integer value
        char c = (char) ch;

        switch (c) {
        case '.':
        case ',':
        case ';':
            return new SimpleToken(lexemReader.line(), lexemReader.pos(), c);

        case '(':
        case ')':
        case '{':
        case '}':
            return new BracketToken(lexemReader.line(), lexemReader.pos(), c);

        case '/':
            if (lexemReader.followingCharacter() == '/')
                return consumeComment();
            else
                return new OperatorToken(lexemReader.line(), lexemReader.pos(),
                        c);

        case '+':
        case '-':
        case '*':
        case '!':
        case '>':
        case '<':
            return new OperatorToken(lexemReader.line(), lexemReader.pos(), c);

        case '&':
        case '|':
            if (lexemReader.followingCharacter() == c)//is it one of "&&",
                                                      // "||"?
            {
                lexemReader.nextCharacter();
                return new OperatorToken(lexemReader.line(), lexemReader.pos(),
                        c);
            } else
                throw new ScannerException(lexemReader.line(), lexemReader
                        .pos(), "Unknown Operator");

        case '=':
            if (lexemReader.followingCharacter() == c)//is it "=="?
            {
                lexemReader.nextCharacter();
                return new OperatorToken(lexemReader.line(), lexemReader.pos(),
                        c);
            } else
                return new SimpleToken(lexemReader.line(), lexemReader.pos(), c); // found
                                                                                  // assignment

        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return composeNumberLiteral(c, lexemReader.line(), lexemReader
                    .pos());

        default:
            return composeWord(c, lexemReader.line(), lexemReader.pos());
        }
    }

    private Token consumeComment() throws ScannerException {
        while (lexemReader.nextCharacter() != '\n')
            ;

        return scanToken();
    }

    private Token composeNumberLiteral(char c, int line, int pos)
            throws ScannerException {
        int val = c - '0';

        while (isDigit(lexemReader.followingCharacter())) {
            c = (char) lexemReader.nextCharacter();
            val *= 10;
            val += c - '0';
        }

        return new NumberLiteralToken(line, pos, val);
    }

    private boolean isDigit(char c) {
        return c >= '0' && c <= '9';
    }

    private Token composeWord(char c, int line, int pos)
            throws ScannerException {
        StringBuffer charSequence = new StringBuffer(99);

        charSequence.append(c);

        while (isAlphaNumeric(lexemReader.followingCharacter())) {
            c = (char) lexemReader.nextCharacter();
            charSequence.append(c);
        }

        String word = charSequence.toString();

        if (isBooleanLiteral(word))
            return new BooleanLiteralToken(line, pos, word.equals("true"));

        if (isKeyword(word))
            return new KeywordToken(line, pos, word);

        return new IdentifierToken(line, pos, word);
    }

    private boolean isAlphaNumeric(char c) {
        return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'
                || isDigit(c);
    }

    private boolean isKeyword(String s) {
        String[] keywords = { "while", "if", "else", "return", "new",
                "void", "boolean", "int", "direction", "Robot" };

        return contains(keywords, s);
    }

    private boolean isBooleanLiteral(String s) {
        String[] booleanLiterals = { "true", "false" };

        return contains(booleanLiterals, s);
    }

    private boolean contains(String[] a, String s) {
        for (int i = 0; i < a.length; i++)
            if (s.equals(a[i]))
                return true;

        return false;
    }
}

⌨️ 快捷键说明

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