abstractsyntaxnode.java

来自「是有关解释器的.用JAVA编写.可以解释一般的JAVA程序.」· Java 代码 · 共 570 行 · 第 1/2 页

JAVA
570
字号
/**
 * This class defines the interface for nodes of the abstract syntax tree.
 * Important methods are already defined here and declared abstract. Optional
 * methods are defined as well but contain an empty implementation. Additional
 * (static) methods may help you in parsing constructs and some of the methods
 * might be useful in subclasses. <br>
 * ExecutableNode and EvaluatableNode are subclasses of this class. Use them as
 * superclasses if your node is executable or evaluatable, respectively.
 * Otherwise, inherit from this class. <br>
 * Subclasses should contain a static method for parsing, this methods needs an
 * Environment object as a parameter to access the information available there.
 * Look at the sample class ProgramNode for an example.
 * 
 * @see ExecutableNode
 * @see EvaluatableNode
 * @see Environment
 * @see ProgramNode
 */
public abstract class AbstractSyntaxNode {
    /**
     * Checks for well-formedness. Implementation of this method is optional. If
     * you want to check well-formedness during the execution instead, don't
     * overwrite the default implementation.
     * 
     * @param env
     *            the <code>Environment</code> (has to contain type
     *            information and identifier of varaibles and methods which are
     *            visible to this node.
     * @throws InterpreterException
     * @return false, if a type error happenend, true if not.
     */
    boolean typeCheck(Environment env) throws InterpreterException {
        return true;
    }

    /**
     * Creates a string which "pretty prints" this node.
     * 
     * @param indent
     *            amount of spaces to indent the code of this node.
     * @return a "pretty printed" version of the code of this node
     */
    abstract String format(int indent);

    final public String toString() {
        return format(0);
    }

    /** number of spaces for one indention level. */
    final static protected int indentAmount = 2;

    /**
     * Returns an html formatted pretty printed version of this node.
     * 
     * @param indent
     *            amount of spaces for indention of this code.
     * @return an html fragment showing a pretty printed version of the code.
     */
    String toHtml(int indent) {
        return "";
    }

    // -----------------------------------------------------------------------
    // The following utility methods are useful for implementing subclasses
    // -----------------------------------------------------------------------

    /**
     * Returns the given number of spaces as string.
     * 
     * @param n
     *            amount of spaces to be generated
     * @return A string containing n spaces.
     */
    static String space(int n) {
        String result = new String();
        for (; n > 0; n--)
            result += " ";
        return result;
    }

    // -----------------------------------------------------------------------
    // Methods to consume special tokens
    // -----------------------------------------------------------------------

    /**
     * If the next token is a <b>simple token </b> and matches the given char,
     * it is consumed and the scanner moves on to the next token.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @param c
     *            the char which has to match the token
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @see SimpleToken
     */
    static void matchSimple(Scanner s, char c) throws ParserException,
            ScannerException {
        Token t = s.token();

        if (t.isSimple())
            if (((SimpleToken) t).content() == c) {
                s.advance();
                return;
            }

        parserError(t, "Character '" + c + "' expected");
    }

    /**
     * If the next token is a <b>bracket </b> and matches the given char, it is
     * consumed and the scanner moves on to the next token.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @param c
     *            the char which has to match the token
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @see BracketToken
     */
    static void matchBracket(Scanner s, char c) throws ParserException,
            ScannerException {
        Token t = s.token();

        if (t.isBracket())
            if (((BracketToken) t).content() == c) {
                s.advance();
                return;
            }

        parserError(t, "Bracket '" + c + "' expected");
    }

    /**
     * If the next token is an <b>operator </b> and matches the given char, it
     * is consumed and the scanner moves on to the next token.
     * 
     * According to <code>OperatorToken</code> the operators "&&", "||", "=="
     * are represented by '&', '|', '='.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @param c
     *            the char which has to match the token
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @see OperatorToken
     */
    static void matchOperator(Scanner s, char c) throws ParserException,
            ScannerException {
        Token t = s.token();

        if (t.isOperator())
            if (((OperatorToken) t).content() == c) {
                s.advance();
                return;
            }

        parserError(t, "Operator '" + c + "' expected");
    }

    /**
     * If the next token is a <b>keyword </b> and matches the given char, it is
     * consumed and the scanner moves on to the next token.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @param w
     *            the String which has to match the token
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @see KeywordToken
     */
    static void matchKeyword(Scanner s, String w) throws ParserException,
            ScannerException {
        Token t = s.token();

        if (t.isKeyword())
            if (((KeywordToken) t).content().equals(w)) {
                s.advance();
                return;
            }

        parserError(t, "Keyword '" + w + "' expected");
    }

    /**
     * If the next token is an <b>identifier </b> and matches the given char, it
     * is consumed and the scanner moves on to the next token.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @param w
     *            the String which has to match the token
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @see KeywordToken
     * @see IdentifierToken
     */
    static void matchIdentifier(Scanner s, String w) throws ParserException,
            ScannerException {
        Token t = s.token();

        if (t.isIdentifier())
            if (((IdentifierToken) t).content().equals(w)) {
                s.advance();
                return;
            }

        parserError(t, "Identifier '" + w + "' expected");
    }

    /**
     * If the next token is a <b>keyword </b> the scanner moves on to the next
     * token and the matched token is returned.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @return the matched token
     * @see KeywordToken
     */
    static String matchKeyword(Scanner s) throws ParserException,
            ScannerException {
        Token t = s.token();

        if (!t.isKeyword())
            parserError(t, "Keyword expected");

        s.advance();

        return ((KeywordToken) t).content();
    }

    /**
     * If the next token is an <b>identifier </b> the scanner moves on to the
     * next token and the matched token is returned.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @return the matched token
     * @see IdentifierToken
     */
    static String matchIdentifier(Scanner s) throws ParserException,
            ScannerException {
        Token t = s.token();

        if (!t.isIdentifier())
            parserError(t, "Identifier expected");

        s.advance();

        return ((IdentifierToken) t).content();
    }

    /**
     * If the next token is a <b>boolean literal </b> the scanner moves on to
     * the next token and the matched token is returned.
     * 
     * @param s
     *            reference to the scanner returning the tokens.
     * @throws ScannerException
     *             If an input error occured
     * @throws ParserException
     *             If the token doesn't match.
     * @return the matched token
     * @see BooleanLiteralToken

⌨️ 快捷键说明

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