es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Antlr4: Mensaje de error confuso (concatena líneas correctas e incorrectas) para gramática de Java.

Estoy tratando de construir mi propio analizador basado en la gramática existente de Java.

Incluso si uso la gramática de Java7 del repositorio de origen, genero el analizador y utilizo TestRig de antlr-4.9.3-complete.jar dado el código:

public class Test {
   public static void main() {
      test
      int b = 1;
   }
}

Obtengo el siguiente error:

línea 4:8 no hay una alternativa viable en ‘test\n int’

Por alguna razón, concatena la línea incorrecta “test” con la línea correcta “int”.
También dice “línea 4:8” señalando la línea “int” cuando debería señalar “test” (línea 3).

(En un editor de Java regular, vería una correcta resaltado de error para la palabra “test” que sonaría como):

“Error de sintaxis, inserte “VariableDeclarators” para completar LocalVariableDeclaration”

¿Qué debo hacer para obtener un error similar con ANTLR para que solo se enfoque en la línea incorrecta “test”?
Probablemente sea solo mi falta de comprensión de cómo ANTLR interpreta los errores, entonces, ¿cómo haría que el listener informe correctamente al menos la línea de inicio?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución

    El problema aquí es que el analizador está tratando de analizar las palabras “test int” como una única instrucción. Esto se debe a que la gramática no permite que se analicen instrucciones incompletas como “test”.

    Para obtener un mensaje de error más preciso, puedes modificar la gramática para permitir instrucciones incompletas. Una forma de hacer esto es añadir una regla para StatementExpression que permita ExpressionStatement o instrucciones incompletas:

    statementExpression 
        : expressionStatement 
        | incompleteStatement
        ;
    
    incompleteStatement 
        : IDENTIFIER 
        | primary '.' IDENTIFIER 
        | primary '[' expression ']' '.' IDENTIFIER 
        ;
    

    Esto permitirá que el analizador reconozca “test” como una instrucción incompleta y dé un mensaje de error más preciso.

    En cuanto al problema de que el error señala la línea incorrecta, esto se debe a que ANTLR reporta los errores basándose en la posición en el flujo de entrada, en lugar del número de línea. Para obtener el número de línea, puedes utilizar el método Token.getLine() en tu error listener. Aquí tienes un ejemplo:

    public class MyErrorListener extends BaseErrorListener {
        @Override
        public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
                                int line, int charPositionInLine, String msg,
                                RecognitionException e) {
            System.err.println("línea " + line + ":" + charPositionInLine + " " + msg);
        }
    }
    

    Con este error listener, deberías poder ver el número de línea correcto en el mensaje de error.

    Ten en cuenta que modificar la gramática puede ser una tarea compleja, y debes ser cauteloso al realizar cambios en la gramática de Java. Siempre es buena idea probar tu gramática modificada con una variedad de entradas para asegurarte de que sigue analizando correctamente código Java válido.

Comments are closed.