Tengo un problema para entender el cambio/reducir el conflicto para una gramática que sé que no tiene ambigüedad. El caso es del tipo if else else, pero no es el problema de 'colgar el otro' ya que tengo cláusulas END obligatorias que delimitan bloques de código.Shift reduce conflicto
Aquí es la gramática de GPPG (es un compilador de bisonte como compilador ... y que no era un eco):
%output=program.cs
%start program
%token FOR
%token END
%token THINGS
%token WHILE
%token SET
%token IF
%token ELSEIF
%token ELSE
%%
program : statements
;
statements : /*empty */
| statements stmt
;
stmt : flow
| THINGS
;
flow : '#' IF '(' ')' statements else
;
else : '#' END
| '#' ELSE statements '#' END
| elseifs
;
elseifs : elseifs '#' ELSEIF statements else
| '#' ELSEIF statements else
;
Aquí está la salida de conflictos:
// Parser Conflict Information for grammar file "program.y"
Shift/Reduce conflict on symbol "'#'", parser will shift
Reduce 10: else -> elseifs
Shift "'#'": State-22 -> State-23
Items for From-state State 22
10 else: elseifs .
-lookahead: '#', THINGS, EOF
11 elseifs: elseifs . '#' ELSEIF statements else
Items for Next-state State 23
11 elseifs: elseifs '#' . ELSEIF statements else
// End conflict information for parser
ya Cambié todo, y sé cómo resolverlo, pero esa solución implica renunciar a la recursividad a la izquierda en 'elseif' para una recursión correcta.
He revisado toda la documentación que he encontrado en Internet sobre este tema (publico algunos enlaces al final) y todavía no he encontrado una solución elegante. Sé sobre ANTLR y no quiero considerarlo ahora. Por favor, limite su solución a los analizadores de Yacc/Bison.
Agradecería las soluciones elegantes, logré hacerlo eleminando las reglas/* empty */y la duplicación de todo lo que necesitaba una lista vacía pero en la gramática más grande en la que trabajo Simplemente termina como 'sparghetti grammar syndrome' .
Éstos son algunos enlaces:
http://nitsan.org/~maratb/cs164/bison.html
http://compilers.iecc.com/comparch/article/98-01-079
Sí. Yo también esperaba que funcionara, tienes razón al decir que es el más fácil de entender. pero lo ejecuté en el analizador sintáctico y desafortunadamente di 4 conflictos de cambio/reducción. Ejecútelo a través de gppg y compruébelo usted mismo. No entiendo (tengo que recuperar mi manual de compiladores de 'dragon') – Caerbanog
La respuesta funciona si saco el '#'. Parece que el simbol arruina el token de anticipación, probablemente porque el analizador es LALR (1) – Caerbanog