Antlr4 recursividad "primitivo"

votos
0

Siguiendo a lo largo de http://blog.ptsecurity.com/2016/06/theory-and-practice-of-source-code.html#java--and-java8-grammars , estoy tratando de reducir izquierda recursividad en mi bastante gramática compleja. Por lo que entiendo, la forma no primitivo de la recursividad puede conducir a problemas de rendimiento tanto en términos de memoria y tiempo de proceso.

Así que estoy tratando de refactorizar estas reglas en mi gramática a utilizar sólo recursividad primitivo. Por supuesto, esa entrada del blog es la única vez que he visto la frase recursión primitivo en lo que respecta a Antlr. Así que sólo estoy adivinando en su significado / propósito. Me parece que significa una regla que se refiere a sí mismo como un izda a lo sumo sólo una sola rama regla. ¿Correcto?

Por el momento tengo una regla de expresión como:

expression
    : expression DOUBLE_PIPE expression         # ConcatenationExpression
    | expression PLUS expression                # AdditionExpression
    | expression MINUS expression               # SubtractionExpression
    | expression ASTERISK expression            # MultiplicationExpression
    | expression SLASH expression               # DivisionExpression
    | expression PERCENT expression             # ModuloExpression
    ...
    ;

La ...incluye un buen número de sub-reglas que también se refieren de nuevo a expression. Pero estos son los únicos con la repetición directa.

Si he entendido bien, la refactorización que éstos sean recursividad primitivo sería algo como:

expression
    : binaryOpExpression                        # BinaryOpExpression
    ...
    ;

binaryOpExpression
    : expression DOUBLE_PIPE expression         # ConcatenationExpression
    | expression PLUS expression                # AdditionExpression
    | expression MINUS expression               # SubtractionExpression
    | expression ASTERISK expression            # MultiplicationExpression
    | expression SLASH expression               # DivisionExpression
    | expression PERCENT expression             # ModuloExpression
    ;

En primer lugar, es que la refactorización correcta?

En segundo lugar, habrá que realmente mejorar el rendimiento? Al final del día sigue siendo las mismas decisiones, así que no estoy realmente entender cómo esto ayuda el rendimiento (aparte de quizás producir menos objetos ATNConfig).

Gracias

Publicado el 09/10/2019 a las 19:01
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
0

No he oído "recursividad primitiva" antes en este contexto y el autor probablemente sólo significa nombrar una forma específica de funciones recursivas ANTLR4.

El hecho es que hay 3 formas pertinentes de funciones recursivas ANTLR4:

  • recursividad por la izquierda directa: la repetición de la primera referencia regla en regla (a la misma regla). Por ejemplo:a: ab | c;
  • Indirecta recursividad por la izquierda: recursividad por la izquierda no directamente de la misma norma. Por ejemplo:a: b | c; b: c | d; c: a | e;
  • Recursividad derecha: cualquier otra recursividad en una regla. Por ejemplo: a: ba | c;. Sin embargo, el nombre de "recursividad derecho" sólo es correcto en casos de expresión binaria, pero a menudo se utiliza para diferenciarse de recurrencias izquierda.

Habiendo dicho esto, queda claro que su reescritura es incorrecto, ya que crearía la repetición indirecta izquierda, que ANLTR4 no soporta. la repetición directa izquierda no suele ser un problema (desde un punto de vista de la memoria o el rendimiento) porque ANTLR4 los convierte en gráficos de reglas ATN no recursivos.

Lo que puede convertirse en un problema son recurrencias correctas, ya que son implementadas por la repetición de código (función recursiva se llama en el tiempo de ejecución), que puede agotar qickly la pila de la CPU. He visto casos con grandes expresiones que no se pudo analizar en un hilo separado, porque no podía establecer el tamaño de pila de subprocesos a un valor más grande (el tamaño principal pila de subprocesos por lo general se puede ajustar a través de la configuración de engarce).

La única solución para el último caso, que he encontrado útil, es reducir el número de reglas del analizador en la gramática que llaman entre sí. Por supuesto que es una cuestión de estructura, etc. legibilidad para poner ciertos elementos de expresión en diferentes normas (por ejemplo andExpression, orExpression, bitExpressionetc.), sino que puede conducir a la invocación pilas muy profundas, que pueden agotar la pila de la CPU y / o requerir mucho de tiempo para procesarlos.

Respondida el 10/10/2019 a las 10:28
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more