Error del analizador Antlr 4.5 durante el tiempo de ejecución

Estoy construyendo gramática simple para progtwigr laguange con fines de aprendizaje.

Me encuentro con un extraño error que no tiene sentido para mí.

line 1:0 missing {'void', 'int', 'bool', 'string', 'union'} at 'void' 

Estoy usando prebuild lexer y analizador de esta gramática:

 grammar ProgrammingLanguage; function_definition : type_specifier IDENTIFIER '(' parameter_list_opt ')' compound_statement ; type_specifier : VOID | INT | BOOL | STRING | UNION ; compound_statement : '{' declaration_list statement_list '}' ; statement_list : statement | statement statement_list | ; statement : compound_statement | selection_statement | while_statement | jump_statement | expression_statement | comment_statement ; comment_statement : COMMENT_START COMMENT ; selection_statement : IF '(' expression ')' compound_statement | IF '(' expression ')' compound_statement ELSE compound_statement | SWITCH '(' expression ')' compound_statement ; expression_statement : ';' | expression ';' ; jump_statement : BREAK ';' | CONTINUE ';' ; while_statement : WHILE '(' expression ')' compound_statement ; primary_expression : IDENTIFIER | CONSTANT | '(' expression ')' | IDENTIFIER '(' primary_expression_list ')' ; primary_expression_list : primary_expression | primary_expression primary_expression_list | ; expression : logical_or_expression | additive_expression ; logical_or_expression : logical_and_expression | logical_or_expression '||' logical_and_expression ; logical_and_expression : compare_expression | logical_and_expression '&&' compare_expression ; compare_expression : primary_expression compare_op primary_expression | primary_expression ; compare_op : '' | '==' | '!=' | '=' ; additive_expression : multiplicative_expression | additive_expression '+' multiplicative_expression | additive_expression '-' multiplicative_expression ; multiplicative_expression : primary_expression | multiplicative_expression '*' primary_expression | multiplicative_expression '/' primary_expression | multiplicative_expression '%' primary_expression ; assignment_expression : IDENTIFIER '=' expression ; id_list : IDENTIFIER | IDENTIFIER ',' id_list ; declaration : type_specifier id_list ';' ; parameter_list_opt : parameter_list | ; parameter_list : type_specifier IDENTIFIER | type_specifier IDENTIFIER ',' parameter_list ; declaration_list : declaration | declaration declaration_list | ; /**------------------------------------------------------------------ * LEXER RULES *------------------------------------------------------------------ */ WHILE : 'while' ; BREAK : 'break' ; CONTINUE : 'continue' ; SWITCH : 'switch' ; IF : 'if' ; ELSE : 'else' ; COMMENT_START : '//' ; IDENTIFIER : ('a'..'z'|'A'..'Z')('0'..'9'|'a'..'z'|'A'..'Z')*; CONSTANT : FALSE|TRUE|STRING_VALUE|INT_VALUE; STRING_VALUE : '"'COMMENT'"'; COMMENT : ('0'..'9'|'a'..'z'|'A'..'Z')*; INT_VALUE : ('0'..'9')+; FALSE : 'false'; TRUE : 'true'; VOID : 'void'; INT : 'int'; BOOL : 'bool'; STRING : 'string'; UNION : 'union'; WS : (' '|'\t'|'\n'|'\r')+ -> skip; 

Y estoy analizando con este código de Java:

 import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeWalker; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { ProgrammingLanguageLexer lexer = new ProgrammingLanguageLexer(new ANTLRFileStream("input.txt")); ProgrammingLanguageParser parser = new ProgrammingLanguageParser(new CommonTokenStream(lexer)); ParseTree tree = parser.function_definition(); ParseTreeWalker.DEFAULT.walk(new ProgrammingLanguageBaseListener(), tree); } } 

Y finalmente, cadena, que estoy tratando de analizar:

 void power () {} 

El mensaje de error significa que el tipo de token esperado que contiene el valor ‘void’ no coincide con el tipo de token real producido al consumir la cadena ‘void’ de la entrada. Al observar sus reglas lexer, se sugiere que la cadena de entrada ‘void’ está siendo consumida por la regla IDENTIFIER, produciendo un token de tipo IDENTIFICADOR, no VACÍO.

En general, la regla de lexer que coincide con la cadena de entrada más larga gana. Para dos (o más) reglas con la misma longitud de coincidencia, la primera lista gana. Mueva todas sus reglas de palabras clave por encima de la regla del IDENTIFICADOR.

Un formulario de prueba de unidad útil volcará los tokens lex’d y mostrará los tipos de token reales emparejados. Algo como:

 CommonTokenStream tokens = ... tokens.fill(); StringBuilder sb = new StringBuilder(); for (Token token : tokens.getTokens()) { sb.append(((YourCustomTokenType) token).toString()); } System.out.print(sb.toString()); 

El método Token.toString () suele ser lo suficientemente bueno. Anule su subclase de tokens para que se ajuste a sus necesidades.