uso de yacc
YACC con gramáticas ambiguas.
Si la gramática de la especificación en YACC es ambigua se producen conflictos
en las acciones del analizador sintáctico. YACC informará del número de
conflictos en las acciones del análisis sintáctico que se produzcan. Se puede
obtener una descripción de los conjuntos de elementos y de los conflictos en las
acciones de análisis sintáctico invocando a YACC con la opción -v. Esta
opción generará un archivo adicional llamado
y.output
que contiene los núcleos de los conjuntos de elementos encontrados por el
analizador sintáctico, una descripción de los conflictos en las acciones del
análisis, y una representación legible de la tabla de análisis sintáctico LR
que muestra cómo se resolvieron los conflictos de las acciones del análisis
sintáctico.
A menos que se ordene lo contrario, YACC resolverá todos los conflictos en las acciones del análisis sintáctico utilizando las dos reglas siguientes:
Como estas reglas que se siguen por omisión, no siempre reflejan lo que quiere el escritor del compilador, YACC proporciona un mecanismo general para resolver los conflictos de desplazamiento/reducción. En la parte de declaraciones, se pueden asignar precedencias y asociatividades a los terminales. La declaración
%left '+' '-'
hace que
'+'
y
'-'
tengan la misma precedencia y que sean asociativos por la izquierda. Se puede
declarar que un operador es asociativo por la derecha diciendo
%right '^'
y se puede obligar a un operador a ser un operador binario no asociativo (por ejemplo, dos casos del operador no se pueden combinar en absoluto) diciendo:
%nonassoc '<'
A los componentes léxicos se les dan precedencias en el orden en que aparecen en la parte de declaraciones, siendo los primeros los de menor precedencia. Los componentes léxicos de una misma declaración tienen la misma precedencia. Así, la declaración
%right MENOSU
daría al componente léxico MENOSU un nivel de precedencia mayor que a los terminales declarados anteriormente.
YACC
resuelve los conflictos de desplazamiento/reducción asociando una
precedencia y asociatividad a cada producción implicada en un conflicto, así
como a cada terminal implicado en un conflicto. Si debe elegir entre
desplazar el símbolo de entrada
a
y reducir por la producción
A->a,
YACC reduce si la precedencia de la producción es mayor que la de
a
o si las precedencias son las mismas y la asociatividad de la regla es
%left.
De lo contrario se elige la acción de desplazar.
Generalmente, la precedencia de una producción se considera igual a la del símbolo terminal situado más a la derecha. En la mayoría de los casos, esta es la decisión sensata. En las situaciones en que el símbolo terminal situado más a la derecha no proporcione la precedencia adecuada a una producción, se puede forzar una precedencia añadiendo al final a la regla la etiqueta
%prec < terminal >
Entonces, la precedencia y
asociatividad de la producción serán las mismas que las de
terminal,
que se define seguramente en la sección de declaraciones. YACC no informa
de los conflictos de desplazamiento/reducción que se resuelven utilizando
este mecanismo de precedencia y asociatividad.
Este "terminal"
puede ser simplemente un marcador. Es decir, el terminal no es devuelto por el
analizador léxico, sino que se declara tan sólo para definir una precedencia
para una producción. Por ejemplo,
expr : '-' expr %prec MENOSU
hace que la
regla anterior tenga la precedencia correspondiente al token
MENOSU,
en lugar de la del token
'-'.
Ml-Yacc es un generador del programa de análisis para el ml estándar modelado después del generador del programa de análisis de Yacc. Genera los programas de análisis para las idiomas de LALR, como Yacc, y tiene un sintaxis similar.Los programas de análisis generados utilizan un diverso algoritmo para recuperarse de errores del sintaxis que los programas de análisis generados por Yacc.. MAS