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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top