En un analizador LALR (1), las reglas en la gramática se convierten en una tabla de análisis que dice efectivamente "Si tiene esta entrada hasta ahora, y el token de búsqueda anticipada es X, cambie al estado Y o reduzca por regla R ".¿Cómo trata el algoritmo yacc/bison LALR (1) las reglas "vacías"?
He construido con éxito un analizador LALR (1) en un lenguaje interpretado (ruby), no usando un generador, pero calculando una tabla de análisis sintáctico en tiempo de ejecución y evaluando la entrada usando esa tabla de análisis sintáctico. Esto funciona sorprendentemente bien y la generación de tablas es bastante trivial (lo cual me sorprendió un poco), apoyando reglas autorreferenciales y asociación izquierda/derecha.
Una cosa que estoy teniendo algunas dificultades para entender, sin embargo, es cómo yacc/bison procesa conceptualmente las definiciones de reglas vacías. Mi analizador no puede manejarlos, ya que al generar la tabla, observa cada símbolo en cada regla, de forma recursiva, y "vacío" no es algo que provenga del lector, ni será reducido por una regla. Entonces, ¿cómo pueden los analizadores LALR (1) procesar la regla vacía? ¿Lo tratan especialmente, o es un concepto "natural" con el que debería funcionar un algoritmo válido, sin siquiera tener que tener un conocimiento particular de tal concepto?
Digamos, una regla que puede coincidir con cualquier número de paréntesis, emparejado con nada en el medio:
expr: /* empty */
| '(' expr ')'
;
de entrada como la siguiente se correspondería con esta regla:
((((()))))
Esto significa que al leyendo '(' y viendo ')' en el token de búsqueda anticipada, las opciones del analizador:
- Cambie el ')' (no es posible)
- Reducir la entrada de acuerdo con alguna otra regla (no es posible)
- otra cosa ...
no encajan bien en el algoritmo básico de "cambio" o "reducir". El analizador efectivamente no necesita cambiar nada a la pila, reducir "nada" a expr
, luego cambiar el siguiente token ')'
, dando '(' expr ')'
, que por supuesto se reduce a expr
, y así sucesivamente.
Es el "cambio nada" que me confunde. ¿Cómo la tabla de análisis transmite tal concepto? Considere también que debería ser posible invocar alguna acción semántica que devuelva un valor a $$
al reducir el valor vacío, por lo que una vista bastante simplista de simplemente omitirlo de la tabla de análisis sintáctico y decir que '('
en la pila y ')'
en la búsqueda futura simplemente traducir a un cambio, no produciría genuinamente la secuencia '(' expr ')'
, sino que simplemente produciría la secuencia '(' ')'
.
Estoy seguro de que hay largas secciones en el [libro de dragón] (http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools) sobre cómo tratar con tales reglas. No creo que Stack Overflow sea el lugar adecuado para discutirlo, ¿acaso programadores? –
Gracias por la sugerencia sobre el libro ... mirando ese enlace ahora. Stackoverflow parece el lugar correcto para mí. Es una pregunta directa sobre el algoritmo, no una discusión subjetiva. Alguien podría buscar esto y, si alguien sabe la respuesta, obtener una solución rápida. – d11wtq
Creo que realmente me di cuenta de esto cuando un punto fundamental se me ocurrió, y es tan ciegamente obvio y directo. Responderá la pregunta, ya que Google no arroja nada y es una pregunta bastante natural;) – d11wtq