java - the - Error del analizador Antlr 4.5 durante el tiempo de ejecución
megatutorial antlr (1)
Estoy construyendo una gramática simple para programar laguange con fines de aprendizaje.
Me encuentro con un error extraño que no tiene sentido para mí.
line 1:0 missing {''void'', ''int'', ''bool'', ''string'', ''union''} at ''void''
Estoy usando prebuild lexer y parser 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 este código 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. Mirar las reglas de lexer sugiere que la regla de IDENTIFICADOR está consumiendo la cadena de entrada ''nula'', produciendo un token de tipo IDENTIFICADOR, no VACÍO.
En general, la regla lexer que coincide con la cadena de entrada más larga gana. Para dos (o más) reglas con la misma duración de la partida, gana la primera lista. Mueva todas sus reglas de palabras clave por encima de la regla IDENTIFICADOR.
Un útil formulario de prueba de unidad volcará los tokens lex''d y mostrará los tipos de tokens reales coincidentes. 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 en su subclase de token para satisfacer sus propias necesidades.