Yacc: Un generador de anal. sintácticos • Yet Another Compiler-Compiler • Yacc es una herramienta UNIX para la generación de analizadores sintácticos para gramáticas LALR • Veremos que, aunque puede trabajar de forma independiente, lo habitual será usarlo en conjunción con Lex • Esquema de un fuente Yacc: sección sección de de declaraciones declaraciones %% %% sección sección de de reglas reglas de de traducción traducción %% %% sección sección de de rutinas rutinas del del usuario usuario Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 1 Yacc: Un generador de anal. sintácticos • La introducción mediante la construcción de un reconocedor para la gramática IDENTIFICADOR: CONSTENTERA: OPAS: MAS: APAR: CPAR: NL: como siempre sin signo := + ( ) \n instrucciones → instrucciones NL instrucción | instrucción instruccion → IDENTIFICADOR OPAS expresion expresion → termino | expresion MAS termino termino → IDENTIFICADOR | CONSTENTERA | APAR expresion CPAR Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 2 Yacc: Un generador de anal. sintácticos • La sección de declaraciones /* */ %{ código C “literal” fichero: instrucciones.y Ejemplo para int. de Yacc símbolo inicial (si no aparece, izda. primera regla) ...... #include <stdio.h> ...... %} %start instrucciones %token IDENTIFICADOR OPAS CONSTENTERA %token MAS APAR CPAR NL %% reglas de traducción %% terminales (suministrados por yylex()) rutinas de usuario Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 3 Yacc: Un generador de anal. sintácticos • La sección de producciones (reglas) sección de declaraciones %% instrucciones: instrucciones NL instruccion | instruccion ; instruccion: IDENTIFICADOR OPAS expresion ; expresion: expresion MAS termino | termino ; termino: IDENTIFICADOR | CONSTENTERA | APAR expresion CPAR ; %% rutinas de usuario Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 4 Yacc: Un generador de anal. sintácticos sección declaraciones • La sección dede rutinas de usuario %% sección de reglas %% int yylex() { ......... } habitualmente, no necesario hacerla (uso conjunto con Lex) int main() { yyparse(); } • En lo que sigue: – asumiremos trabajo con Lex Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 5 Yacc: Un generador de anal. sintácticos • El fuente del analizador léxico lo genera Yacc (#define..,YYSTYPE..) no hay main() /* */ Analizador léxico para instrucciones %{ #include <stdio.h> #include "y.tab.h" %} /*EXPRESIONES REGULARES*/ separador [\t ]+ /*tab,blanco*/ letra [a-zA-Z] digito [0-9] identificador {letra}({letra}|{digito})* constEntera {digito}+ %% {separador} {/*saltarlo*/} {constEntera} {return(CONSTENTERA);} ":=" {return(OPAS);} "+" {return(MAS);} {identificador} {return(IDENTIFICADOR);} "(" {return(APAR);} ")" {return(CPAR);} \n {return(NL);} . {ECHO;} %% Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 6 Yacc: Un generador de anal. sintácticos instrucciones.l instrucciones.y lex instrucciones.l yacc -d instrucciones.y lex.yy.c y.tab.h cc lex.yy.c -c y.tab.c cc y.tab.c -c lex.yy.o y.tab.o cc lex.yy.o y.tab.o -ll -ly -o instrucciones instrucciones Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 7 Yacc: Un generador de anal. sintácticos • Contenido de ‘y.tab.h’ #define #define #define #define #define #define IDENTIFICADOR OPAS CONSTENTERA MAS APAR CPAR 257 258 259 260 261 257 • En casos más generales, tiene mucha más información – ya nos irá apareciendo • Ejemplo de uso: vel1 := (vel2+67)+otro vel1 := (vel2++67) instrucciones instrucciones Syntax Error ???????? Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 8 Yacc: Un generador de anal. sintácticos • Alternativamente, la sección de reglas se podía haber puesto como declaraciones (MODIFICAR ADECUADAMENTE) %% instrucciones: instrucciones ‘\n’ instruccion | instruccion ; instruccion: IDENTIFICADOR OPAS expresion ; expresion: expresion ‘+’ termino | termino ; ¡OJO! termino: IDENTIFICADOR | CONSTENTERA | ‘(‘ expresion ‘)’ ; %% rutinas de usuario Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 9 Yacc: Un generador de anal. sintácticos • El fuente lex para la nueva versión Yacc cambia ligeramente /*Analizador léxico para instrucciones*/ %{ #include <stdio.h> #include "y.tab.h" %} /*EXPRESIONES REGULARES*/ separador [\t ]+ /*tab,blanco*/ letra digito identificador constEntera %% {separador} {constEntera} ":=" "+" {identificador} "(" ")" \n [\+\(\)\n] . %% Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- [a-zA-Z] [0-9] {letra}({letra}|{digito})* {digito}+ {/*saltarlo*/} {return(CONSTENTERA);} {return(OPAS);} {return(MAS);} {return(IDENTIFICADOR);} {return(APAR);} {return(CPAR);} {return(NL);} {return(yytext[0]);} {ECHO;} 10