04.03.2015 Views

Introducción a Yacc - GIAA

Introducción a Yacc - GIAA

Introducción a Yacc - GIAA

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Yacc</strong><br />

Gramática<br />

BNF<br />

plan.y<br />

YACC<br />

plan.tab.c<br />

Compilador<br />

+<br />

Enlazador<br />

Ejecutable<br />

Otros<br />

módulos


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Estructura de <strong>Yacc</strong><br />

Yet Another Compiler-Compiler<br />

• Bison: versión GNU<br />

Herramienta para generar analizadores sintácticos<br />

para gramáticas LALR<br />

YACC programa fuente<br />

{definición}<br />

%%<br />

{reglas}<br />

%%<br />

{subrutinas de usuario}<br />

Reglas: acción<br />

producciones pertenecen a una gramática G2 en BNF<br />

Acción: fragmentos de código C que especifican que<br />

hacer cuando se reduce una producción


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Estructura de <strong>Yacc</strong><br />

La forma natural de trabajar es conjuntamente con<br />

LEX:<br />

• yylex(): petición de siguiente token<br />

El analizador está contenido en la función<br />

yyparse()<br />

home\> yacc ejemplo.y<br />

home\> ls *.c<br />

home\> ejemplo.tab.c<br />

home\> flex patrones.lex<br />

home\> ls *.c<br />

home\> lex.yy.c ejemplo.tab.c<br />

home\> gcc -o sint lex.yy.c ejemplo.tab.c


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Principio de <strong>Yacc</strong><br />

Análisis previo de la gramática para construir<br />

el analizador LALR: notifica incidencias<br />

Funcionamiento general del analizador: pide<br />

tokens definidos al analizador léxico (yylex)<br />

• Como es LALR(1), pide un token de pre-análisis<br />

• Cuando realiza desplazamiento pide el siguiente<br />

token<br />

• Cuando realiza reducciones de producciones,<br />

ejecuta el código en sus acciones


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Formato de <strong>Yacc</strong><br />

Tres partes separadas por una línea con<br />

“%%”<br />

Declaraciones<br />

%%<br />

Reglas<br />

%%<br />

Código de usuario<br />

Previas al uso del scanner<br />

Reglas sintácticas y lo que hay<br />

que hacer cuando se activan<br />

Funciones C que se copian al<br />

fichero de salida


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Sección de Declaraciones<br />

Declaraciones:<br />

• Código de usuario<br />

• Se copia a la salida<br />

• %{....%}<br />

• Declaraciones<br />

• Terminales y no terminales (opt):<br />

• %token símbolo<br />

• %type símbolo<br />

• Precedencia y asociatividad<br />

de operadores<br />

• %noassoc símbolos<br />

• %left símbolos<br />

• %right símbolos<br />

• Símbolo de arranque de la gramática<br />

• %start símbolo<br />

• Directivas de comportamiento<br />

%{<br />

%}<br />

%%<br />

%%<br />

Código de usuario<br />

#include


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Sección de Declaraciones<br />

Terminales<br />

• Es lo que devuelve la función yylex() (llamada<br />

automáticamente desde yyparse()<br />

• Se convierten en #define en el fichero de salida<br />

• Se les asocia un número comenzando por 257<br />

• Se puede obligar a que tenga uno en concreto<br />

• %token T_LLAVE 345<br />

• Los terminales de un carácter no hace falta<br />

declararlos (están implícitos)<br />

• En yacc se podrá utilizar directamente el terminal ‘(‘<br />

• Son tokens con valores numéricos el código ASCII<br />

(


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Declaraciones de terminales<br />

Ejemplo definición terminales<br />

• Lenguaje de expresiones aritméticas con enteros<br />

%{<br />

#include <br />

%}<br />

%token NUMERO, MAS, MENOS, POR, DIV, PAR_I, PAR_D<br />

%start expr /* simbolo axioma sentencial */<br />

…<br />

Declaración en YACC de terminales<br />

(expresiones.y)


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Declaraciones de terminales<br />

Ejemplo definición terminales<br />

%{<br />

#include "expresiones_tab.h"<br />

%}<br />

digito [0-9]<br />

%%<br />

[ \t]+ ;<br />

{digito}+ {yylval=atoi(yytext); return NUMERO;}<br />

"+" return MAS;<br />

"-" return MENOS;<br />

"*" return POR;<br />

"/" return DIV;<br />

"(" return PAR_I;<br />

")" return PAR_D;<br />

. {printf("token erroneo\n");}<br />

Definición en Lex de patrones


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Comunicación Flex-<strong>Yacc</strong><br />

fich.l<br />

header<br />

fich.y<br />

lex fich.l<br />

yacc -d fich.y<br />

lex.yy.c<br />

fich.tab.h<br />

fich.tab.c<br />

cc lex.yy.c -c<br />

cc fich.tab.c -c<br />

lex.yy.o<br />

fich.tab.o<br />

gcc lex.yy.o fich.tab.o -o an_sintactico<br />

calc


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Reglas en YACC<br />

Formato BNF simplificado<br />

LI: LD acción;<br />

• LI: es un símbolo no-terminal del lenguaje<br />

• LD: secuencia de símbolos no-terminales y terminales<br />

Agrupar varias reglas del mismo no terminal :<br />

expr: expr ´+´ expr {....}<br />

| expr ´-´ expr {....}<br />

;<br />

Si se deja vacía es el regla de la palabra vacía<br />

sentencias : sentencias ´;´ sentencia {....}<br />

|<br />

;<br />

acción: { sentencias en C } (puede ser vacío)


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Declaraciones de reglas<br />

%token NUMERO, MAS, MENOS, POR, DIV, PAR_I, PAR_D<br />

%start expr /* simbolo axioma sentencial */<br />

%%<br />

expr: expr MAS term<br />

{printf("expr --> expr MAS term\n");}<br />

|expr MENOS term {printf("expr --> expr MENOS term\n");}<br />

|term<br />

{printf("expr --> term\n");}<br />

;<br />

term: term POR factor {printf("term --> term POR factor\n");}<br />

|term DIV factor {printf("term --> term DIV factor\n");}<br />

|factor<br />

{printf("term --> factor\n");}<br />

;<br />

factor: NUMERO<br />

{printf("factor--> NUMERO(%d)\n",$1);}<br />

|PAR_I expr PAR_D{printf("factor--> ( expr )\n");}<br />

;<br />

%%<br />

. . .


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo de análisis<br />

Gramática<br />

exprexpr + term<br />

exprterm<br />

termterm * factor<br />

termfactor<br />

factorNUMERO<br />

factor(expr)<br />

Ejemplo de ejecución<br />

• 5*(6+1)+3<br />

factor--> NUMERO (5)<br />

term --> factor<br />

factor--> NUMERO (6)<br />

term --> factor<br />

expr --> term<br />

factor--> NUMERO (1)<br />

term --> factor<br />

expr --> expr MAS term<br />

factor--> ( expr )<br />

term --> term POR factor<br />

expr --> term<br />

factor--> NUMERO (3)<br />

term --> factor<br />

expr --> expr MAS term


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Resolución de ambigüedad<br />

Por defecto, después de avisar, yacc resuelve<br />

• D/R: Desplazar prioridad sobre reducir<br />

• R/R: Reducir por la producción primera<br />

Preferible resolver los conflictos explícitamente<br />

• Criterios de prioridad


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Precedencia<br />

Especificación de precedencia<br />

• Asociatividad izquierda<br />

• %left op: x op y op z (x op y) op z<br />

• Asociatividad derecha<br />

• %right op: x op y op z x op (y op z)<br />

• No asociatividad<br />

• %nonassoc op: x op y op z INCORRECTO<br />

• Con otros operadores: los declarados en líneas posteriores<br />

más precedencia<br />

Ejemplo de asociación:<br />

% left ‘+’ ‘-’<br />

% left ‘*’ ‘/’<br />

• El último declarado es el que tiene más precedencia


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Gramática expresiones con prioridad<br />

%token NUMERO, MAS, POR, '(', ')'<br />

%left MAS<br />

%left POR<br />

%start S /* simbolo axioma sentencial */<br />

%%<br />

S: expr {printf("resultado: %d\n", $$); }<br />

expr: expr MAS expr<br />

|expr POR expr<br />

|'(' expr ')'<br />

| NUMERO<br />

%%


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Reglas: valores semánticos<br />

El valor semántico que proporciona yylex() se utiliza<br />

con los operadores $n<br />

expr: NAT ´+´ NAT {$$=$1+$3};<br />

• $$ identifica a la parte izquierda de la regla de producción<br />

• $n se corresponde con el n-ésimo símbolo de la parte<br />

derecha<br />

En la parte derecha cada componente se identifica<br />

por el orden que ocupa<br />

Por defecto se suponen valores enteros<br />

• Pueden declararse tipos complejos para los atributos


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo transporte atributos<br />

%%<br />

%token NUMERO, MAS, MENOS, POR, DIV, PAR_I, PAR_D<br />

%start S /* simbolo axioma sentencial */<br />

%%<br />

S: expr {printf("resultado: %d\n", $$); }<br />

expr: expr MAS term {$$=$1+$3;}<br />

|expr MENOS term {$$=$1-$3;}<br />

|term {$$=$1;}<br />

;<br />

term: term POR factor {$$=$1*$3;}<br />

| term DIV factor {$$=$1/$3;;}<br />

| factor {$$=$1;}<br />

;<br />

factor: NUMERO {$$=$1;}<br />

| PAR_I expr PAR_D {$$=$1;}<br />

;<br />

. . .<br />

Se agrega<br />

automáticamente


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Reglas: valores semánticos<br />

Los atributos de los tokens se obtienen en el<br />

análisis léxico: variable yylval<br />

• Es la comunicación lex-yacc<br />

• Representa el atributo del último token en el<br />

patrón reconocido<br />

• Por defecto es un atributo de tipo entero (int)<br />

• Ej.: …<br />

digito [0-9]<br />

%%<br />

Plantilla<br />

Lex:<br />

[ \t]+ ;<br />

"+" return MAS;<br />

"*“ return POR;<br />

{digito}+ {yylval=atoi(yytext); return NUMERO;}


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Sección de Declaraciones<br />

Directiva %union<br />

• Por defecto todos los terminales tienen un atributo<br />

de tipo entero, yyval, asignado en yylex()<br />

• Los valores semánticos se declaran en %union<br />

%union{<br />

int valent;<br />

char *cadena;<br />

tblPos *ptr;<br />

}


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Sección de Declaraciones<br />

Por defecto todos los terminales tienen un atributo<br />

de tipo entero, yyval, asignado en yylex()<br />

• Para utilizar otro tipo de atributo puede usarse la variable<br />

YYSTYPE<br />

#define YYSTYPE double<br />

Directiva %union<br />

• Da mayor flexibilidad, permitiendo definir varios atributos<br />

por símbolo y atributos alternativos<br />

• Declara los tipos posibles como una “unión” de C<br />

%union{<br />

int valent;<br />

char *cadena;<br />

tblPos *ptr;<br />

}


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Sección de Declaraciones<br />

Uso de un tipo declarado en %union<br />

• Se puede asociar a un terminal en su declaración<br />

%token NATURAL<br />

• Para un no terminal en su declaración<br />

%type NO_TERMINAL<br />

• En una producción específica<br />

expr: NAT ´+´ NAT {$$=$1+$3};<br />

En un símbolo terminal (análisis léxico)<br />

[-+]?{digito}+ { yyval.valent=atoi(yytext);<br />

return ENTERO;}


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Sección de Declaraciones<br />

%union{<br />

int valent;<br />

char *cadena;<br />

tblPos *ptr;<br />

}<br />

Uso de los tipos declarados en %union<br />

• Se puede asociar a un terminal en su declaración<br />

%token NATURAL<br />

• Para un no terminal en su declaración<br />

%type NO_TERMINAL<br />

• En una producción específica<br />

expr: NAT ´+´ NAT {$$=$1+$3};<br />

En un símbolo terminal (análisis léxico): hay que<br />

especificar<br />

[-+]?{digito}+ { yyval.valent=atoi(yytext);<br />

return NUMERO;}


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Almacenamiento de Atributos<br />

cima<br />

cima -1<br />

cima-2<br />

Técnica frecuente en analizadores ascendentes (LALR:yacc/bison,<br />

cup)<br />

Los atributos sintetizados se almacenan en una pila, y se evalúan<br />

al efectuar las reducciones: “pila semántica”:<br />

• Correspondencia con la pila de estados LR, asociados a los símbolos<br />

gramaticales<br />

Producción<br />

A::= XYZ<br />

Pila LR<br />

val<br />

... ...<br />

Z<br />

Y<br />

X<br />

Acciones<br />

semánticas<br />

A.s=f(X.x,Y.y,Z.z)<br />

Z.z<br />

Y.y<br />

X.x<br />

val [cima]<br />

val [cima –1]<br />

val [cima-2]<br />

int<br />

char<br />

%union{<br />

int val1;<br />

char val2;}<br />

%typeX<br />

%typeY


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Implementación en YACC<br />

Acciones embebidas:<br />

Las acciones pueden aparecer en el medio de una regla,<br />

ejecutándose antes de que la regla sea completamente<br />

evaluada.<br />

X: Y {acción} Z;<br />

Por ejemplo:<br />

X: Y {$$ := 2*$1;} z {$$ := $2+$3;}<br />

Establece el valor de x como 2*(valor de Y) + (valor de z)<br />

Pueden introducir conflictos en la resolución<br />

de la gramática!!!


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Infija-Postfija<br />

Traductor infija->postfija<br />

E<br />

E::=T E’<br />

E’::= op T {escribe op.lex} E’<br />

E’::=λ<br />

T::= num {escribe num.lex}<br />

¡No hay atributos!<br />

Acc. sem.: escribir código<br />

(esquema de traducción)<br />

Sentencia: 9-5+2<br />

Resultado: 9 5 – 2 +<br />

T E’<br />

num 1. e(‘9’) 3. e(‘-’)<br />

9<br />

operador T E’<br />

- 2. e(‘5’)<br />

num<br />

5. e(‘+’)<br />

5<br />

operador T E’<br />

+ 4. e(‘2’)<br />

num λ<br />

2


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Infija-Postfija<br />

digito [0-9]<br />

letra [a-zA-Z]<br />

%option noyywrap<br />

%%<br />

[ \t]+ ;<br />

"(" return PAR_I;<br />

")" return PAR_D;<br />

[-+] {strcpy(yylval.lex, yytext); return OP;}<br />

{letra}({digito}|{letra})*<br />

{strcpy(yylval.lex, yytext); return VAR;}<br />

{digito}+ {strcpy(yylval.lex, yytext); return NUMERO;}<br />

. {printf("token erroneo\n");}<br />

%%


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Infija-Postfija<br />

%union<br />

{<br />

char lex[50];<br />

}<br />

%token NUMERO, OP, PAR_I, PAR_D ASIG VAR<br />

%start E /* simbolo axioma sentencial */<br />

%%<br />

E: T E1 {}<br />

E1: OP T {printf("%s ",$1);} E1<br />

| {}<br />

;<br />

T: NUMERO {printf("%s ",$1);}<br />

| VAR {printf("%s ",$1);}<br />

|PAR_I E PAR_D {}<br />

%%


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Ejecución lex-yacc<br />

7-a+C-(4-b) 7 a - C + 4 b - -


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Declaración Tipos<br />

digito [0-9]<br />

letra [a-zA-Z]<br />

%%<br />

[ \t]+ ;<br />

"," return COMA;<br />

";" return PCOMA;<br />

"=“ return ASIG;<br />

[-+*/] return OP;<br />

"float" return FLOAT;<br />

"int" return INT;<br />

{letra}({digito}|{letra})* {strcpy(yylval.nombre,<br />

yytext); return VAR;}<br />

{digito}+ {yylval.valor=atoi(yytext);<br />

return NUMEROENT;}<br />

{digito}+(.{digito}+)<br />

{yylval.valor=atof(yytext);<br />

return NUMEROREAL;}<br />

. {printf("token erroneo\n");}


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Declaración Tipos<br />

%union<br />

{<br />

int valor;<br />

char nombre[50];<br />

char tipo[50];<br />

}<br />

%token VAR<br />

%token NUMEROENT, NUMEROREAL<br />

%token OP, ASIG, COMA, PCOMA FLOAT, INT<br />

%left MAS OP<br />

%type T L S E<br />

%start P /* simbolo axioma sentencial */<br />

...


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Declaración Tipos<br />

...<br />

P: T L PCOMA S {}<br />

;<br />

L: L COMA VAR {printf("ponerTS(%s,%s)\n",$3,$0);}<br />

|VAR<br />

{printf("ponerTS(%s,%s)\n",$1,$0);}<br />

;<br />

T: FLOAT {sprintf($$, "float");}<br />

|INT<br />

{sprintf($$, "int");}<br />

;<br />

S: VAR ASIG E {printf("comprobar tipo var %s\n", $1);}<br />

| {}<br />

;<br />

E: E OP E {/*reglas combinacion de tipos (promocion)*/}<br />

|VAR<br />

{printf("buscarTS(%s)\n", $1);/*asignar tipo<br />

de VAR a E0*/}<br />

|NUMEROENT {strcpy($$, "int");}<br />

|NUMEROREAL {strcpy($$, "real");}<br />

;


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Herencia de atributos, declaración tipos<br />

En la pila sólo hay atributos sintetizados<br />

Todos los atributos heredados están en posiciones predecibles en<br />

la pila (incluyendo el de la parte izquierda)<br />

cima<br />

cima -1<br />

cima -2<br />

cima -3<br />

símbolo val<br />

... ...<br />

VAR VAR.s<br />

COMA -<br />

L M 1 .s<br />

T T.s<br />

L->L COMA ID<br />

val [cima] $3<br />

val [cima–1] $2<br />

…<br />

val [cima-2] $1<br />

val [cima–3] $0


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Ejecución lex-yacc<br />

float a,b,c,d,e,f;<br />

a=4*c-2.0<br />

ponerTS(a,float)<br />

ponerTS(b,float)<br />

ponerTS(c,float)<br />

ponerTS(d,float)<br />

ponerTS(e,float)<br />

ponerTS(f,float)<br />

buscarTS(c)<br />

comprobar tipo var a


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Algunas opciones útiles<br />

Depuración del analizador: directiva<br />

YYDEBUG. Describe:<br />

• Cada una de las acciones realizadas<br />

(desplazamiento/reducción)<br />

• Tokens leídos<br />

• Estados visitados durante el análisis<br />

• Situación de la pila


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Algunas opciones útiles<br />

Ejemplo de<br />

depuración:<br />

((a))


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo salida depuración<br />

Ejemplo de depuración: ((a))<br />

Starting parse<br />

Entering state 0<br />

Reading a token: Next token is 40 ('(')<br />

Shifting token 40 ('('), Entering state 2<br />

Reading a token: Next token is 40 ('(')<br />

Shifting token 40 ('('), Entering state 2<br />

Reading a token: Next token is 97 ('a')<br />

Shifting token 97 ('a'), Entering state 1<br />

Reducing via rule 2 (line 12), 'a' -> S<br />

state stack now 0 2 2<br />

Entering state 3<br />

Reading a token: Next token is 41 (')')<br />

Shifting token 41 (')'), Entering state 4<br />

Reducing via rule 1 (line 11), '(' S ')' -> S<br />

state stack now 0 2<br />

Entering state 3


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo salida depuración<br />

Ejemplo de depuración: ((a))<br />

state stack now 0 2<br />

Entering state 3<br />

Reading a token: Next token is 41 (')')<br />

Shifting token 41 (')'), Entering state 4<br />

Reducing via rule 1 (line 11), '(' S ')' -> S<br />

state stack now 0<br />

Entering state 5<br />

Reading a token: Now at end of input.<br />

Shifting token 0 ($), Entering state 6<br />

Now at end of input.


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo activación depuración<br />

%{<br />

#include <br />

#define YYDEBUG 1<br />

%}<br />

%token NUMERO, MAS, MENOS, POR, DIV, PAR_I, PAR_D<br />

%start S /* simbolo axioma sentencial */<br />

%%<br />

... producciones<br />

%%<br />

main(int argc, char *argv[])<br />

{<br />

yydebug=1;<br />

...<br />

}<br />

Cuando yydebug no<br />

es 0: depuración


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Gramática expresiones ambigua<br />

%token NUMERO, MAS, POR, '(', ')'<br />

%start S /* simbolo axioma sentencial */<br />

%%<br />

S: expr {printf("resultado: %d\n", $$); }<br />

expr: expr MAS expr<br />

|expr POR expr<br />

|'(' expr ')'<br />

| NUMERO<br />

%%


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Información del analizador<br />

Opción “verbose” –v (descriptivo)<br />

• Descripción detallada de la tabla de análisis<br />

sintáctico LALR(1), y del autómata de<br />

reconocimiento<br />

• Características de la gramática: terminales no<br />

utilizados, símbolos no generativos, etc.<br />

• Notifica si hay conflictos desp/red y red/red<br />

home\> yacc –d –v ejemplo.y<br />

home\> ls<br />

home\> ejemplo.y ejemplo.tab.h<br />

ejemplo.tab.c ejemplo.output


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Gramática Sencilla<br />

Ejemplo: Lenguaje: {( n a ) n }, n≥0<br />

Gramática:<br />

Σ T ={(, a, )}, Σ T ={S}, S, P}<br />

P: S(S)<br />

Sa


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Salida yacc -v<br />

Grammar<br />

rule 1 S -> '(' S ')'<br />

rule 2 S -> 'a'<br />

Terminals, with rules where they appear<br />

$ (-1)<br />

'(' (40) 1<br />

')' (41) 1<br />

'a' (97) 2<br />

error (256)<br />

Nonterminals, with rules where they appear<br />

S (6)<br />

on left: 1 2, on right: 1


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ejemplo Salida yacc -v<br />

state 0<br />

'a' shift, and go to state 1<br />

'(' shift, and go to state 2<br />

S go to state 5<br />

state 1<br />

S -> 'a' . (rule 2)<br />

$default reduce using rule 2 (S)<br />

state 2<br />

S -> '(' . S ')' (rule 1)<br />

'a' shift, and go to state 1<br />

'(' shift, and go to state 2<br />

S go to state 3


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Análisis de ambigüedad con yacc<br />

Opción -v<br />

home\> yacc –v expresiones.y<br />

home\> expresiones.y contains 4<br />

shift/reduce conflicts<br />

home\> ls<br />

home\> expresiones.y expresiones_tab.c<br />

expresiones.output


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ambigüedad con yacc<br />

State 8 contains 2 shift/reduce conflicts.<br />

State 9 contains 2 shift/reduce conflicts.<br />

Grammar<br />

rule 1 S -> expr<br />

rule 2 expr -> expr MAS expr<br />

rule 3 expr -> expr POR expr<br />

rule 4 expr -> '(' expr ')'<br />

rule 5 expr -> NUMERO<br />

Terminals, with rules where they appear<br />

$ (-1)<br />

'(' (40) 4<br />

')' (41) 4<br />

NUMERO (258) 5<br />

MAS (259) 2<br />

POR (260) 3


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ambigüedad con yacc<br />

state 8<br />

expr -> expr . MAS expr (rule 2)<br />

expr -> expr MAS expr . (rule 2)<br />

expr -> expr . POR expr (rule 3)<br />

MAS shift, and go to state 5<br />

POR shift, and go to state 6<br />

MAS<br />

POR<br />

$default<br />

[reduce using rule 2 (expr)]<br />

[reduce using rule 2 (expr)]<br />

reduce using rule 2 (expr)


<strong>Yacc</strong>. Procesadores de Lenguaje II<br />

Ambigüedad con yacc<br />

state 9<br />

expr -> expr . MAS expr (rule 2)<br />

expr -> expr . POR expr (rule 3)<br />

expr -> expr POR expr . (rule 3)<br />

MAS shift, and go to state 5<br />

POR shift, and go to state 6<br />

MAS<br />

POR<br />

$default<br />

[reduce using rule 3 (expr)]<br />

[reduce using rule 3 (expr)]<br />

reduce using rule 3 (expr)

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!