TableDrivenParserFactory.java

package org.sterling.source.parser;

import static org.sterling.source.syntax.NodeKind.*;

import org.sterling.source.scanner.Scanner;
import org.sterling.source.syntax.NodeKind;

public class TableDrivenParserFactory {

    private static final NodeKind[] ANY_ATOM = new NodeKind[] {
        GROUP_OPEN,
        DOUBLE,
        INTEGER,
        CHARACTER,
        STRING,
        BOOLEAN,
        NOTHING,
        KEYWORD_OBJECT,
        IDENTIFIER,
    };

    private static final NodeKind[] ANY_MEMBER_NAME = new NodeKind[] {
        KEYWORD_POSITIVE,
        KEYWORD_NEGATIVE,
        ADD,
        SUBTRACT,
        MULTIPLY,
        DIVIDE,
        MODULO,
        SHIFT_LEFT,
        SHIFT_RIGHT,
        SIGNED_SHIFT_RIGHT,
        COALESCE,
        INDEXER_OPERATOR,
        BITWISE_AND,
        BITWISE_OR,
        BITWISE_XOR,
        BITWISE_NOT,
        IDENTIFIER,
    };

    private static ParserTable getParserTable() {
        return Holder.parserTable;
    }

    @SuppressWarnings("PMD.ExcessiveMethodLength")
    private static ParserTable initParserTable() {
        return new ParserTableBuilder()
            .when(MODULE_DECLARATION).sees(ANYTHING).derive(MODULE_HEADER, IMPORT_HEADERS, DECLARATION_SEQUENCE, END_OF_INPUT)

            .when(MODULE_HEADER).sees(KEYWORD_MODULE).derive(KEYWORD_MODULE, MODULE_IDENTIFIER)
            .when(MODULE_HEADER).sees(ANYTHING_ELSE).output()
            .when(MODULE_IDENTIFIER).sees(IDENTIFIER).derive(IDENTIFIER, MODULE_IDENTIFIER_TAIL)
            .when(MODULE_IDENTIFIER_TAIL).sees(ACCESSOR).derive(ACCESSOR, IDENTIFIER, MODULE_IDENTIFIER_TAIL)
            .when(MODULE_IDENTIFIER_TAIL).sees(ANYTHING_ELSE).output()

            .when(IMPORT_HEADERS).sees(KEYWORD_IMPORT).or(KEYWORD_FROM).derive(IMPORT_HEADER)
            .when(IMPORT_HEADERS).sees(ANYTHING_ELSE).output()
            .when(IMPORT_HEADER).sees(KEYWORD_IMPORT).derive(IMPORT_STATEMENT, IMPORT_HEADER_SUFFIX)
            .when(IMPORT_HEADER).sees(KEYWORD_FROM).derive(FROM_STATEMENT, IMPORT_HEADER_SUFFIX)
            .when(IMPORT_HEADER).sees(ANYTHING_ELSE).output()
            .when(IMPORT_HEADER_SUFFIX).sees(TERMINATOR).derive(TERMINATOR, IMPORT_HEADER_TAIL)
            .when(IMPORT_HEADER_TAIL).sees(KEYWORD_IMPORT).or(KEYWORD_FROM).derive(IMPORT_HEADER)
            .when(IMPORT_HEADER_TAIL).sees(ANYTHING_ELSE).output()

            .when(IMPORT_STATEMENT).sees(KEYWORD_IMPORT).derive(KEYWORD_IMPORT, IMPORT_IDENTIFIER)
            .when(IMPORT_IDENTIFIER).sees(IDENTIFIER).derive(IDENTIFIER, IMPORT_IDENTIFIER_TAIL, IMPORT_IDENTIFIER_ALIAS)
            .when(IMPORT_IDENTIFIER_TAIL).sees(ACCESSOR).derive(ACCESSOR, IDENTIFIER, IMPORT_IDENTIFIER_TAIL)
            .when(IMPORT_IDENTIFIER_TAIL).sees(ANYTHING_ELSE).output()
            .when(IMPORT_IDENTIFIER_ALIAS).sees(KEYWORD_AS).derive(KEYWORD_AS, IDENTIFIER)
            .when(IMPORT_IDENTIFIER_ALIAS).sees(ANYTHING_ELSE).output()

            .when(FROM_STATEMENT).sees(KEYWORD_FROM).derive(KEYWORD_FROM, FROM_IDENTIFIER, KEYWORD_IMPORT, FROM_IDENTIFIERS)
            .when(FROM_IDENTIFIER).sees(IDENTIFIER).derive(IDENTIFIER, FROM_IDENTIFIER_TAIL)
            .when(FROM_IDENTIFIER_TAIL).sees(ACCESSOR).derive(ACCESSOR, IDENTIFIER, FROM_IDENTIFIER_TAIL)
            .when(FROM_IDENTIFIER_TAIL).sees(ANYTHING_ELSE).output()
            .when(FROM_IDENTIFIERS).sees(GROUP_OPEN).derive(GROUP_OPEN, FROM_IDENTIFIER_LIST, GROUP_CLOSE)
            .when(FROM_IDENTIFIERS).sees(IDENTIFIER).derive(FROM_IDENTIFIER_LIST)
            .when(FROM_IDENTIFIER_LIST).sees(IDENTIFIER).derive(IDENTIFIER, IMPORT_IDENTIFIER_ALIAS, FROM_IDENTIFIER_LIST_TAIL)
            .when(FROM_IDENTIFIER_LIST).sees(ANYTHING_ELSE).output()
            .when(FROM_IDENTIFIER_LIST_TAIL).sees(SEPARATOR).derive(SEPARATOR, FROM_IDENTIFIER_LIST)
            .when(FROM_IDENTIFIER_LIST_TAIL).sees(ANYTHING_ELSE).output()

            .when(DECLARATION_SEQUENCE).sees(IDENTIFIER).derive(DECLARATION, DECLARATION_SEQUENCE_TAIL)
            .when(DECLARATION_SEQUENCE).sees(ANYTHING_ELSE).output()
            .when(DECLARATION_SEQUENCE_TAIL).sees(TERMINATOR).derive(TERMINATOR, DECLARATION_SEQUENCE)
            .when(DECLARATION_SEQUENCE_TAIL).sees(ANYTHING_ELSE).output()
            .when(DECLARATION).sees(IDENTIFIER).derive(IDENTIFIER, ASSIGN, DECLARATION_LITERAL)

            .when(DECLARATION_LITERAL).sees(KEYWORD_OBJECT).derive(OBJECT_LITERAL)
            .when(DECLARATION_LITERAL).sees(GROUP_OPEN).tryDerive(FUNCTION_LITERAL, CONSTANT_EXPRESSION)
            .when(DECLARATION_LITERAL).sees(IDENTIFIER).tryDerive(LAMBDA_LITERAL, CONSTANT_EXPRESSION)
            .when(DECLARATION_LITERAL).sees(ANYTHING_ELSE).tryDerive(CONSTANT_EXPRESSION)

            .when(CONSTANT_EXPRESSION).sees(ANYTHING).derive(EXPRESSION)
            .when(LAMBDA_LITERAL).sees(IDENTIFIER).derive(LAMBDA_ARGUMENT, ARROW, EXPRESSION)

            .when(FUNCTION_LITERAL).sees(GROUP_OPEN).derive(GROUP_OPEN, FUNCTION_ARGUMENTS, GROUP_CLOSE, ARROW, EXPRESSION)
            .when(FUNCTION_ARGUMENTS).sees(IDENTIFIER).derive(LAMBDA_ARGUMENT, FUNCTION_ARGUMENTS_TAIL)
            .when(FUNCTION_ARGUMENTS_TAIL).sees(IDENTIFIER).derive(LAMBDA_ARGUMENT, FUNCTION_ARGUMENTS_TAIL)
            .when(FUNCTION_ARGUMENTS_TAIL).sees(GROUP_CLOSE).output()

            .when(OBJECT_LITERAL).sees(KEYWORD_OBJECT).derive(KEYWORD_OBJECT, OBJECT_HEADER, OBJECT_BODY)
            .when(OBJECT_HEADER).sees(GROUP_OPEN).derive(OBJECT_ARGUMENTS)
            .when(OBJECT_HEADER).sees(IDENTIFIER).derive(SINGLE_OBJECT_ARGUMENT)
            .when(OBJECT_HEADER).sees(BLOCK_OPEN).output()
            .when(OBJECT_ARGUMENTS).sees(GROUP_OPEN).derive(GROUP_OPEN, OBJECT_ARGUMENTS_LIST, GROUP_CLOSE)
            .when(OBJECT_ARGUMENTS_LIST).sees(IDENTIFIER).derive(OBJECT_ARGUMENT, OBJECT_ARGUMENTS_LIST)
            .when(OBJECT_ARGUMENTS_LIST).sees(GROUP_CLOSE).output()
            .when(SINGLE_OBJECT_ARGUMENT).sees(IDENTIFIER).derive(OBJECT_ARGUMENT)
            .when(OBJECT_ARGUMENT).sees(IDENTIFIER).derive(IDENTIFIER)
            .when(OBJECT_BODY).sees(BLOCK_OPEN).derive(BLOCK_OPEN, OBJECT_MEMBERS, BLOCK_CLOSE)
            .when(OBJECT_MEMBERS).sees(ANY_MEMBER_NAME).derive(OBJECT_MEMBER, OBJECT_MEMBERS_SUFFIX)
            .when(OBJECT_MEMBERS).sees(BLOCK_CLOSE).output()
            .when(OBJECT_MEMBERS_SUFFIX).sees(TERMINATOR).derive(TERMINATOR, OBJECT_MEMBERS_TAIL)
            .when(OBJECT_MEMBERS_SUFFIX).sees(ANYTHING_ELSE).output()
            .when(OBJECT_MEMBERS_TAIL).sees(ANY_MEMBER_NAME).derive(OBJECT_MEMBER, OBJECT_MEMBERS_SUFFIX)
            .when(OBJECT_MEMBERS_TAIL).sees(ANYTHING_ELSE).output()
            .when(OBJECT_MEMBER).sees(ANY_MEMBER_NAME).derive(OBJECT_MEMBER_NAME, ASSIGN, DECLARATION_LITERAL)

            .when(OBJECT_MEMBER_NAME).sees(KEYWORD_POSITIVE).derive(KEYWORD_POSITIVE)
            .when(OBJECT_MEMBER_NAME).sees(KEYWORD_NEGATIVE).derive(KEYWORD_NEGATIVE)
            .when(OBJECT_MEMBER_NAME).sees(IDENTIFIER).derive(IDENTIFIER)
            .when(OBJECT_MEMBER_NAME).sees(ADD).derive(ADD)
            .when(OBJECT_MEMBER_NAME).sees(SUBTRACT).derive(SUBTRACT)
            .when(OBJECT_MEMBER_NAME).sees(MULTIPLY).derive(MULTIPLY)
            .when(OBJECT_MEMBER_NAME).sees(DIVIDE).derive(DIVIDE)
            .when(OBJECT_MEMBER_NAME).sees(MODULO).derive(MODULO)
            .when(OBJECT_MEMBER_NAME).sees(SHIFT_LEFT).derive(SHIFT_LEFT)
            .when(OBJECT_MEMBER_NAME).sees(SHIFT_RIGHT).derive(SHIFT_RIGHT)
            .when(OBJECT_MEMBER_NAME).sees(SIGNED_SHIFT_RIGHT).derive(SIGNED_SHIFT_RIGHT)
            .when(OBJECT_MEMBER_NAME).sees(COALESCE).derive(COALESCE)
            .when(OBJECT_MEMBER_NAME).sees(INDEXER_OPERATOR).derive(INDEXER_OPERATOR)
            .when(OBJECT_MEMBER_NAME).sees(BITWISE_AND).derive(BITWISE_AND)
            .when(OBJECT_MEMBER_NAME).sees(BITWISE_OR).derive(BITWISE_OR)
            .when(OBJECT_MEMBER_NAME).sees(BITWISE_XOR).derive(BITWISE_XOR)
            .when(OBJECT_MEMBER_NAME).sees(BITWISE_NOT).derive(BITWISE_NOT)

            .when(LAMBDA_ARGUMENT).sees(IDENTIFIER).derive(IDENTIFIER)

            .when(EXPRESSION).sees(KEYWORD_IF).derive(TERNARY_EXPRESSION)
            .when(EXPRESSION).sees(ANYTHING_ELSE).derive(LOGICAL_OR_EXPRESSION)

            .when(TERNARY_EXPRESSION).sees(KEYWORD_IF).derive(
                KEYWORD_IF, LOGICAL_OR_EXPRESSION,
                TERNARY_TRUE, EXPRESSION,
                TERNARY_FALSE, TERNARY_EXPRESSION_TAIL
            )

            .when(TERNARY_EXPRESSION_TAIL).sees(KEYWORD_IF).derive(TERNARY_EXPRESSION)
            .when(TERNARY_EXPRESSION_TAIL).sees(ANYTHING_ELSE).derive(LOGICAL_OR_EXPRESSION)

            .when(LOGICAL_OR_EXPRESSION).sees(ANYTHING).derive(LOGICAL_AND_EXPRESSION, LOGICAL_OR_EXPRESSION_TAIL)
            .when(LOGICAL_OR_EXPRESSION_TAIL).sees(LOGICAL_OR).derive(LOGICAL_OR, LOGICAL_AND_EXPRESSION, LOGICAL_OR_EXPRESSION_TAIL)
            .when(LOGICAL_OR_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(LOGICAL_AND_EXPRESSION).sees(ANYTHING).derive(LOGICAL_NOT_EXPRESSION, LOGICAL_AND_EXPRESSION_TAIL)
            .when(LOGICAL_AND_EXPRESSION_TAIL).sees(LOGICAL_AND).derive(LOGICAL_AND, LOGICAL_NOT_EXPRESSION, LOGICAL_AND_EXPRESSION_TAIL)
            .when(LOGICAL_AND_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(LOGICAL_NOT_EXPRESSION).sees(LOGICAL_NOT).derive(LOGICAL_NOT, EQUALITY_EXPRESSION)
            .when(LOGICAL_NOT_EXPRESSION).sees(ANYTHING_ELSE).derive(EQUALITY_EXPRESSION)

            .when(EQUALITY_EXPRESSION).sees(ANYTHING).derive(SHIFT_EXPRESSION, EQUALITY_EXPRESSION_TAIL)
            .when(EQUALITY_EXPRESSION_TAIL).sees(NOT_EQUALS).derive(NOT_EQUALS, SHIFT_EXPRESSION, EQUALITY_EXPRESSION_TAIL)
            .when(EQUALITY_EXPRESSION_TAIL).sees(EQUALS).derive(EQUALS, SHIFT_EXPRESSION, EQUALITY_EXPRESSION_TAIL)
            .when(EQUALITY_EXPRESSION_TAIL).sees(LESS_THAN_EQUALS).derive(LESS_THAN_EQUALS, SHIFT_EXPRESSION, EQUALITY_EXPRESSION_TAIL)
            .when(EQUALITY_EXPRESSION_TAIL).sees(LESS_THAN).derive(LESS_THAN, SHIFT_EXPRESSION, EQUALITY_EXPRESSION_TAIL)
            .when(EQUALITY_EXPRESSION_TAIL).sees(GREATER_THAN_EQUALS).derive(GREATER_THAN_EQUALS, SHIFT_EXPRESSION, EQUALITY_EXPRESSION_TAIL)
            .when(EQUALITY_EXPRESSION_TAIL).sees(GREATER_THAN).derive(GREATER_THAN, SHIFT_EXPRESSION, EQUALITY_EXPRESSION_TAIL)
            .when(EQUALITY_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(SHIFT_EXPRESSION).sees(ANYTHING).derive(COALESCE_EXPRESSION, SHIFT_EXPRESSION_TAIL)
            .when(SHIFT_EXPRESSION_TAIL).sees(SHIFT_LEFT).derive(SHIFT_LEFT, COALESCE_EXPRESSION, SHIFT_EXPRESSION_TAIL)
            .when(SHIFT_EXPRESSION_TAIL).sees(SIGNED_SHIFT_RIGHT).derive(SIGNED_SHIFT_RIGHT, COALESCE_EXPRESSION, SHIFT_EXPRESSION_TAIL)
            .when(SHIFT_EXPRESSION_TAIL).sees(SHIFT_RIGHT).derive(SHIFT_RIGHT, COALESCE_EXPRESSION, SHIFT_EXPRESSION_TAIL)
            .when(SHIFT_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(COALESCE_EXPRESSION).sees(ANYTHING).derive(BITWISE_XOR_EXPRESSION, COALESCE_EXPRESSION_TAIL)
            .when(COALESCE_EXPRESSION_TAIL).sees(COALESCE).derive(COALESCE, BITWISE_XOR_EXPRESSION, COALESCE_EXPRESSION_TAIL)
            .when(COALESCE_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(BITWISE_XOR_EXPRESSION).sees(ANYTHING).derive(BITWISE_OR_EXPRESSION, BITWISE_XOR_EXPRESSION_TAIL)
            .when(BITWISE_XOR_EXPRESSION_TAIL).sees(BITWISE_XOR).derive(BITWISE_XOR, BITWISE_OR_EXPRESSION, BITWISE_XOR_EXPRESSION_TAIL)
            .when(BITWISE_XOR_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(BITWISE_OR_EXPRESSION).sees(ANYTHING).derive(BITWISE_AND_EXPRESSION, BITWISE_OR_EXPRESSION_TAIL)
            .when(BITWISE_OR_EXPRESSION_TAIL).sees(BITWISE_OR).derive(BITWISE_OR, BITWISE_AND_EXPRESSION, BITWISE_OR_EXPRESSION_TAIL)
            .when(BITWISE_OR_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(BITWISE_AND_EXPRESSION).sees(ANYTHING).derive(ADDITIVE_EXPRESSION, BITWISE_AND_EXPRESSION_TAIL)
            .when(BITWISE_AND_EXPRESSION_TAIL).sees(BITWISE_AND).derive(BITWISE_AND, ADDITIVE_EXPRESSION, BITWISE_AND_EXPRESSION_TAIL)
            .when(BITWISE_AND_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(ADDITIVE_EXPRESSION).sees(ANYTHING).derive(MULTIPLICATIVE_EXPRESSION, ADDITIVE_EXPRESSION_TAIL)
            .when(ADDITIVE_EXPRESSION_TAIL).sees(ADD).derive(ADD, MULTIPLICATIVE_EXPRESSION, ADDITIVE_EXPRESSION_TAIL)
            .when(ADDITIVE_EXPRESSION_TAIL).sees(SUBTRACT).derive(SUBTRACT, MULTIPLICATIVE_EXPRESSION, ADDITIVE_EXPRESSION_TAIL)
            .when(ADDITIVE_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(MULTIPLICATIVE_EXPRESSION).sees(ANYTHING).derive(UNARY_EXPRESSION, MULTIPLICATIVE_EXPRESSION_TAIL)
            .when(MULTIPLICATIVE_EXPRESSION_TAIL).sees(MULTIPLY).derive(MULTIPLY, UNARY_EXPRESSION, MULTIPLICATIVE_EXPRESSION_TAIL)
            .when(MULTIPLICATIVE_EXPRESSION_TAIL).sees(DIVIDE).derive(DIVIDE, UNARY_EXPRESSION, MULTIPLICATIVE_EXPRESSION_TAIL)
            .when(MULTIPLICATIVE_EXPRESSION_TAIL).sees(MODULO).derive(MODULO, UNARY_EXPRESSION, MULTIPLICATIVE_EXPRESSION_TAIL)
            .when(MULTIPLICATIVE_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(UNARY_EXPRESSION).sees(POSITIVE).derive(POSITIVE, UNARY_EXPRESSION)
            .when(UNARY_EXPRESSION).sees(NEGATIVE).derive(NEGATIVE, UNARY_EXPRESSION)
            .when(UNARY_EXPRESSION).sees(BITWISE_NOT).derive(BITWISE_NOT, UNARY_EXPRESSION)
            .when(UNARY_EXPRESSION).sees(ANYTHING_ELSE).derive(SELECTOR_EXPRESSION)

            .when(SELECTOR_EXPRESSION).sees(ANYTHING).derive(PRIMARY_EXPRESSION, SELECTOR_EXPRESSION_TAIL)
            .when(SELECTOR_EXPRESSION_TAIL).sees(INDEXER_OPEN).derive(INDEXER_EXPRESSION, SELECTOR_EXPRESSION_TAIL)
            .when(SELECTOR_EXPRESSION_TAIL).sees(ACCESSOR).derive(ACCESSOR_EXPRESSION, SELECTOR_EXPRESSION_TAIL)
            .when(SELECTOR_EXPRESSION_TAIL).sees(TERMINATOR).or(TERNARY_TRUE).or(TERNARY_FALSE).output()
            .when(SELECTOR_EXPRESSION_TAIL).sees(ANY_ATOM).or(APPLY).derive(ARGUMENTS_EXPRESSION, SELECTOR_EXPRESSION_TAIL)
            .when(SELECTOR_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()

            .when(INDEXER_EXPRESSION).sees(INDEXER_OPEN).derive(INDEXER_OPEN, INDEXER_ARGUMENTS, INDEXER_CLOSE)
            .when(INDEXER_ARGUMENTS).sees(ANYTHING).derive(INDEXER_ARGUMENT, INDEXER_ARGUMENTS_SUFFIX)
            .when(INDEXER_ARGUMENTS_SUFFIX).sees(SEPARATOR).derive(SEPARATOR, INDEXER_ARGUMENTS_TAIL)
            .when(INDEXER_ARGUMENTS_SUFFIX).sees(ANYTHING_ELSE).output()
            .when(INDEXER_ARGUMENTS_TAIL).sees(ANY_ATOM).derive(INDEXER_ARGUMENT, INDEXER_ARGUMENTS_SUFFIX)
            .when(INDEXER_ARGUMENTS_TAIL).sees(ANYTHING_ELSE).output()
            .when(INDEXER_ARGUMENT).sees(ANY_ATOM).derive(EXPRESSION)

            .when(ACCESSOR_EXPRESSION).sees(ACCESSOR).derive(ACCESSOR, IDENTIFIER)

            .when(ARGUMENTS_EXPRESSION).sees(ANY_ATOM).or(APPLY).derive(ARGUMENT, ARGUMENTS_EXPRESSION_TAIL)
            .when(ARGUMENTS_EXPRESSION_TAIL).sees(TERMINATOR).output()
            .when(ARGUMENTS_EXPRESSION_TAIL).sees(ANY_ATOM).or(APPLY).derive(ARGUMENT, ARGUMENTS_EXPRESSION_TAIL)
            .when(ARGUMENTS_EXPRESSION_TAIL).sees(ANYTHING_ELSE).output()
            .when(ARGUMENT).sees(ANY_ATOM).derive(PRIMARY_EXPRESSION)
            .when(ARGUMENT).sees(APPLY).derive(APPLY_EXPRESSION)

            .when(PRIMARY_EXPRESSION).sees(GROUP_OPEN).tryDerive(FUNCTION_LITERAL, PARENTHETICAL_EXPRESSION)
            .when(PRIMARY_EXPRESSION).sees(DOUBLE, INTEGER, CHARACTER, STRING, BOOLEAN, NOTHING).derive(LITERAL_EXPRESSION)
            .when(PRIMARY_EXPRESSION).sees(KEYWORD_OBJECT).derive(OBJECT_LITERAL)
            .when(PRIMARY_EXPRESSION).sees(KEYWORD_JAVA).derive(JAVA_EXPRESSION)
            .when(PRIMARY_EXPRESSION).sees(IDENTIFIER).tryDerive(LAMBDA_LITERAL, QUALIFIED_IDENTIFIER)
            .when(PRIMARY_EXPRESSION).sees(APPLY).derive(APPLY_EXPRESSION)

            .when(JAVA_EXPRESSION).sees(KEYWORD_JAVA).derive(KEYWORD_JAVA)
            .when(APPLY_EXPRESSION).sees(APPLY).derive(APPLY, EXPRESSION)

            .when(PARENTHETICAL_EXPRESSION).sees(GROUP_OPEN).derive(GROUP_OPEN, EXPRESSION, GROUP_CLOSE)

            .when(LITERAL_EXPRESSION).sees(DOUBLE).derive(DOUBLE_LITERAL)
            .when(LITERAL_EXPRESSION).sees(INTEGER).derive(INTEGER_LITERAL)
            .when(LITERAL_EXPRESSION).sees(CHARACTER).derive(CHARACTER_LITERAL)
            .when(LITERAL_EXPRESSION).sees(STRING).derive(STRING_LITERAL)
            .when(LITERAL_EXPRESSION).sees(BOOLEAN).derive(BOOLEAN_LITERAL)
            .when(LITERAL_EXPRESSION).sees(NOTHING).derive(NULL_LITERAL)

            .when(QUALIFIED_IDENTIFIER).sees(IDENTIFIER).derive(IDENTIFIER, QUALIFIED_IDENTIFIER_TAIL)
            .when(QUALIFIED_IDENTIFIER_TAIL).sees(ACCESSOR).derive(ACCESSOR, IDENTIFIER, QUALIFIED_IDENTIFIER_TAIL)
            .when(QUALIFIED_IDENTIFIER_TAIL).sees(ANYTHING_ELSE).output()

            .when(DOUBLE_LITERAL).sees(DOUBLE).derive(DOUBLE)
            .when(INTEGER_LITERAL).sees(INTEGER).derive(INTEGER)
            .when(CHARACTER_LITERAL).sees(CHARACTER).derive(CHARACTER)
            .when(STRING_LITERAL).sees(STRING).derive(STRING)
            .when(BOOLEAN_LITERAL).sees(BOOLEAN).derive(BOOLEAN)
            .when(NULL_LITERAL).sees(NOTHING).derive(NOTHING)

            .getTable();
    }

    public TableDrivenParser getParser(NodeKind kind, Scanner scanner) {
        return new TableDrivenParser(kind, getParserTable(), scanner);
    }

    private static final class Holder {

        public static final ParserTable parserTable = initParserTable();

        private Holder() {
            // intentionally empty
        }
    }
}