Manejo de errores en ANTLR4.
El comportamiento predeterminado cuando el analizador no sabe qué hacer es imprimir mensajes al terminal como:
línea 1:23 falta DECIMAL en '}'
Este es un buen mensaje, pero en el lugar equivocado. Prefiero recibir esto como una excepción.
He intentado usar elBailErrorStrategy
, pero esto arroja unParseCancellationException
sin mensaje (causado por unInputMismatchException
, también sin mensaje).
¿Hay alguna forma en que pueda hacer que informe errores a través de excepciones al tiempo que conservo la información útil en el mensaje?
Esto es lo que realmente busco: normalmente uso acciones en las reglas para construir un objeto:
dataspec returns [DataExtractor extractor]
@init {
DataExtractorBuilder builder = new DataExtractorBuilder(layout);
}
@after {
$extractor = builder.create();
}
: first=expr { builder.addAll($first.values); } (COMMA next=expr { builder.addAll($next.values); })* EOF
;
expr returns [List<ValueExtractor> values]
: a=atom { $values = Arrays.asList($a.val); }
| fields=fieldrange { $values = values($fields.fields); }
| '%' { $values = null; }
| ASTERISK { $values = values(layout); }
;
Luego, cuando invoco el analizador, hago algo como esto:
public static DataExtractor create(String dataspec) {
CharStream stream = new ANTLRInputStream(dataspec);
DataSpecificationLexer lexer = new DataSpecificationLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DataSpecificationParser parser = new DataSpecificationParser(tokens);
return parser.dataspec().extractor;
}
Todo lo que realmente quiero es
Para eldataspec()
llamar para lanzar una excepción (idealmente una marcada) cuando la entrada no se puede analizarpara que esa excepción tenga un mensaje útil y proporcione acceso al número de línea y la posición donde se encontró el problemaLuego dejaré que esa excepción haga saltar la pila de llamadas al lugar que mejor se adapte para presentar un mensaje útil al usuario, de la misma manera que manejaría una conexión de red interrumpida, leyendo un archivo dañado, etc.
Vi que las acciones ahora se consideran "avanzadas" en ANTLR4, así que tal vez estoy haciendo cosas de una manera extraña, pero no he investigado cuál sería la forma "no avanzada" de hacer esto de esta manera Ha estado trabajando bien para nuestras necesidades.