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.

No puedo parecer resolver la ambigüedad en la gramática Antlr.

Estoy creando la gramática más simple posible que básicamente reconoce expresiones aritméticas. La gramática debe seguir correctamente las reglas de precedencia de los operadores aritméticos (PEMDAS), y para eso, coloqué expr ('*'|'/') term antes de expr ('+'|'-') term para garantizar esta precedencia.
Este es el archivo arithmetic.g4 que tengo:

“`grammar arithmetic;

/<em>Productions */
expr: expr ('</em>'|'/') term
| expr ('+'|'-') term
| term
;
term: '('expr')'
| ID
| NUM
;

/*Tokens */
ID: [a-z]+;
NUM: [0-9]+;

WS: [\t\r\n]+->skip;
“`
Sin embargo, la salida de la gramática no es lo que debería ser. Por ejemplo, para la expresión aritmética 4 * (3 + 10), obtengo el siguiente árbol de análisis (que no es absolutamente correcto):

Cualquier sugerencia sobre cómo puedo cambiar la gramática para obtener lo que estoy buscando. Soy nuevo en antlr y no estoy seguro de qué error estoy cometiendo. (BTW, mi sistema operativo es Windows)

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Hay un par de problemas con la gramática que están causando un árbol de análisis sintáctico incorrecto:

    1. Recursión a la izquierda: expr tiene una producción recursiva a la izquierda que causará un bucle infinito al analizar sintácticamente.
    2. Precedencia: el orden de las reglas de producción no sigue correctamente las reglas de precedencia.

    Para solucionar estos problemas, necesitamos reescribir la gramática de la siguiente manera:

    gramática aritmética;
    
    /*Producciones */
    
    expr: term ('*' term | '/' term)*;
    term: factor ('+' factor | '-' factor)*;
    factor: '('[expr]')' | ID | NUM;
    
    /*Tokens */
    ID: [a-z]+;
    NUM: [0-9]+;
    
    WS:  [\t\r\n]+ -> skip;
    

    Aquí, hemos eliminado la recursión a la izquierda y, en su lugar, hemos utilizado los operadores * y + para expresar los operadores de cada nivel.

    También hemos corregido las reglas de precedencia.

    Con esta gramática modificada, obtenemos el árbol de análisis sintáctico esperado para el ejemplo 4*(3+10):

    enter image description here

Comments are closed.