¿Estoy obligado a usar% glr-parser?
Pregunta
He estado manteniendo alejados los cambios / reducir errores. Ahora finalmente creo que conocí a mi pareja.
Int[] a
a[0] = 1
El problema es int [] se define como
Type OptSquareBrackets
mientras que un [0] se define como
Var | Var '[' expr ']'
Var y Type se definen como VAR, que es cualquier variable válida [a-zA-Z] [a-zA-Z0-9_]
. Además de agregar un token ficticio (como ** Decl ** Escriba OptSquareBrackets
en su lugar), ¿hay alguna manera de escribir esto para no tener un conflicto? De esta regla obtengo 1 turno / reducción y 1 advertencia de reducción / reducción.
Solución
¿Podría definir un nuevo token?
VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[
Y, por lo tanto, definir declaración
Type | VarLBracket ']';
y defina el objetivo de asignación como
Var | VarLBracket expr ']';
Otros consejos
Cree una regla Lex con [] ya que [] solo se usa en la declaración y en cualquier otro lugar usaría [var]
Técnicamente, este problema surge de tratar de vincular la gramática con un significado semántico que en realidad no difiere en la sintaxis.
ISTM dice que solo necesita una construcción gramatical única que describa tanto los tipos como las expresiones. Haga la distinción en el código y no en la gramática, especialmente si no hay realmente una diferencia sintáctica. Yacc se llama generador de compiladores, pero no es en absoluto cierto. Simplemente hace analizadores.
Dicho esto, reconocer []
como un símbolo de terminal podría ser una forma más fácil de solucionar el problema y seguir adelante con las cosas. Yacc no es muy bueno en gramáticas ambiguas y necesita tomar decisiones tempranas sobre qué camino seguir.