Yacc

23
Yacc García Vélez María Azucena Ortega Piña Efraín UASLP-FI-Área de Computación e Informática-Compiladores e Interpretes A

description

Introduccion a Yacc

Transcript of Yacc

Page 1: Yacc

Yacc

García Vélez María Azucena

Ortega Piña Efraín

UASLP-FI-Área de Computación e Informática-Compiladores e Interpretes A

Page 2: Yacc

Generalidades

• Yacc es un programa para generar analizadores sintácticos LALR. Las siglas del nombre significan Yet Another Compiler-Compiler, es decir, "Otro generador de compiladores más". Genera un analizador sintáctico (la parte de un compilador que comprueba que la estructura del código fuente se ajusta a la especificación sintáctica del lenguaje).

• Yacc genera el código para el analizador sintáctico en el Lenguaje de programación C.

Page 3: Yacc

• Fue desarrollado por Stephen C. Johnson en AT&T para el sistema operativo Unix. Después se escribieron programas compatibles, por ejemplo Berkeley Yacc, GNU bison, MKS yacc y Abraxas yacc (una versión actualizada de la versión original de AT&T que también es software libre como parte del proyecto de OpenSolaris de Sun).

• Puesto que el analizador sintáctico generado por Yacc requiere un analizador léxico, se utiliza a menudo conjuntamente con un generador de analizador léxico, en la mayoría de los casos lex o Flex, alternativa del software libre.

Page 4: Yacc

Funcionamiento de Yacc

• Igual que sucedía con lex, yacc no es directamente un analizador sino un generador de analizadores. A partir de un fichero fuente en yacc, se genera un fichero fuente en C que contiene el analizador sintáctico. Sin embargo, un analizador sintáctico de yacc no puede funcionar por sí solo, sino que necesita un analizador léxico externo para funcionar. Dicho de otra manera, el fuente en C que genera yacc contiene llamadas a una función yylex() que debe estar definida y debe devolver el tipo de lexema encontrado. Además, es necesario incorporar también una función yyerror(), que será invocada cuando el analizador sintáctico encuentre un símbolo que no encaja en la gramática.

Page 5: Yacc
Page 6: Yacc

Estructura de un programa en Yacc

• Declaraciones o Definiciones

%%

• Reglas de Traduccion

%%

• Soporte de las rutinas en C

Page 7: Yacc

• De estas tres secciones, sólo la segunda es obligatoria, y no debe estar vacía (nótese que en lex, las tres secciones pueden estar vacías). Esto quiere decir que el mínimo programa en yacc es:

%%

regla gramatical acción en C

Page 8: Yacc

Declaraciones o definiciones

• Esta parte se toma por dos secciones en la primera sección se declaran las primeras secciones ordinarias en c delimitadas por %{ y %}, la segunda sección a la declaración de tokens %Token TOKEN %. En esta seccion se pueden emplear la definicion de la asociatividad y precedencia de los tokens empleando, e incluso se pueden definir los tipos de datos %type es importante en esta seccion definir los tipos de datos para la pila de Yacc mediante la definicion YYSTYPE o bien mediante una estructura de union.

Page 9: Yacc

• La sección de declaraciones puede incluir varias cosas, tal y como ocurría en lex, pero ahora su función principal no es definir expresiones regulares, sino declarar los símbolos terminales de la gramática mediante la directriz %token. Todo lo que no sea un terminal, será considerado un símbolo no terminal, y por tanto debe haber un a regla para él:

• %token IF,ELSE,LLAVE_AB,LLAVE_CE,IDENT

Page 10: Yacc

• En algunos de los casos es conveniente indicarle a yacc cual es el simbolo NT de inicio mediante el cual se realiza por ejemplo % start SIMBOLO.

Page 11: Yacc

Reglas de traducción

• En esta seccion se colocan las reglas de traduccion empleando el siguiente formato.

• <encabezados>:<cuerpo>1<accion semantica>1} | <cuerpo>2<accion semantica>2} : | <cuerpo>n<accion semantica>n}

Page 12: Yacc

• La sección de reglas contiene la gramática en sí. Componentes es una combinación de terminales y no terminales que describe al no terminal de la izquierda de la regla:

• no_terminal: componentes {acciones en C}

Page 13: Yacc

Rutinas en C

• En esta sección se incluyen todas las rutinas a incrustarse en el código final. Es importante tener un analizador léxico mediante el nombre yylex, de tal manera que si no se realiza el enlace entre lex y yacc se deberá de implementar dicha función en esta parte.

Page 14: Yacc

Asociatividad y Precedencia

• Por defecto Yacc es asociativo a la derecha pero esto puede modificarse en la sección de definiciones utilizando las siguientes directivas:

▫ %left asocia a la izquierda

▫ %right asocia a la derecha

• Supongamos el siguiente fragmento de programa Yacc para una gramática que reconoce expresiones de sumas de números:

Page 15: Yacc

• La sección de rutinas tiene la misma función que la de lex, pero yacc (dependiendo de su variante) no define por defecto las funciones main(), yylex() e yyerror(), así que hay que incluirlas aquí, o bien en otro fichero que se enlazará en la fase final de la compilación.

Page 16: Yacc

• Yacc genera una función llamada yyparse() que contiene el analizador sintáctico. Esta función se comporta como una máquina de estados cuya misión es intentar reducir todo el fichero de entrada al símbolo inicial de la gramática (el primero que se haya definido). Si yacc lo consigue, el analizador sintáctico volverá sin error, y en caso contrario, se invocará a la función yyerror(), que debe estar definida también en algún sitio.

Page 17: Yacc
Page 18: Yacc

• Si la entrada fuese 5+6+8 por defecto se resolvería como 5+(6+8) (asociación por la derecha),pero al haber definido %left al símbolo ‘+’ en la sección de definiciones el resultado es (5+6)+8 (asociación por la izquierda).

Page 19: Yacc
Page 20: Yacc

• %left, %right y %nonassoc Además de indicar asociatividad se utilizan en la sección de definiciones para indicar precedencia de los operadores teniendo mayor precedencia cuanto más alejados estén del principio del fichero. La última de las tres directivas no indica asociatividad solo precedencia.

• %pred Se utiliza en una regla para dar distinta prioridad al primer símbolo de esa regla, solo para la aplicación de esa regla. Se usa cuando un mismo símbolo puede tener significados distintos con prioridades diferentes. Por ejemplo el símbolo ‘-‘ puede ser unario y binario, cuando es binario tiene la misma prioridad que ‘+’, pero cuando es unario tiene mayor prioridad. En este caso se le puede asignar la misma prioridad que a ‘*’, tal y como se muestra en el ejemplo siguiente.

Page 21: Yacc
Page 22: Yacc

Conflictos y Ambigüedad

• Cuando la gramática de entrada no es LALR(1), Yacc informará de que ha encontrado “conflictos”. Los conflictos se producen cuando el algoritmo de construcción de las tablas no ha permitido, en un momento dado, que se sepa si la acción adecuada es desplazar o reducir (conflicto shift/reduce), o bien cuando haya varias posibilidades de reducción (conflicto reduce/reduce). Se podrá encontrar cuales son los conflictos aparecidos examinando el contenido de y.output.

Page 23: Yacc

• Aveces es conveniente conocer cuales son los conflictos que provoca nuestra gramática y tratar de evitarlos, para ello puede ser útil utilizar la opción –v de Yacc para examinar el autómata descrito en el fichero y.output. Independientemente de la información mostrada Yacc continua el proceso, generando un programa que resuelve sistemáticamente los conflictos aplicando las siguientes normas: ▫ Entre desplazar y reducir, elige desplazar. ▫ Entre dos reducciones distintas, elige la

correspondiente a la regla que aparezca en primer lugar.