Está en la página 1de 11

Un poco de Historia…

Un compilador es un programa informático que transforma


código fuente escrito en un lenguaje de programación o
lenguaje informático (el lenguaje fuente), en otro lenguaje
informático (el lenguaje objetivo, estando a menudo en
formato binario conocido como código objeto). La razón
más común para querer transformar código fuente es crear
un programa ejecutable.
Yacc es un generador de analizador sintáctico desarrollado por Stephen
C. Johnson en AT&T para el sistema operativo Unix. El nombre es un
acrónimo de "Yet Another Compiler Compiler“.
A causa de que Yacc fue el generador de analizador sintáctico por
defecto en la mayoría de sistemas Unix, fue ampliamente distribuido y
usado.

Lex, escrito originalmente por Eric Schmidt y Mike Lesk, es el analizador


léxico estándar en los sistemas Unix.
Aunque tradicionalmente se trata de software propietario, existen
versiones libres de lex basadas en el código original de AT&T en sistemas
como OpenSolaris y Plan 9 de los laboratorios Bell. Otra versión popular
de software libre de lex es Flex
Ahora, ¿Qué es?
LEX es un programa para generar
analizadores léxicos (en inglés
scanners o lexers). Lex se utiliza
comúnmente con el programa YACC
que se utiliza para generar análisis
sintáctico.
¿Analizador ¿Análisis
Léxico? sintáctico?
Es la primera fase de un compilador
consistente en un programa que
recibe como entrada el código Es el programa informático que
fuente de otro programa y produce analiza una cadena de símbolos
una salida compuesta de tokens. de acuerdo a las reglas de una
gramática formal. El análisis
Un token es una cadena de sintáctico convierte el texto de
caracteres que tiene un significado entrada en otras estructuras que
coherente en cierto lenguaje de son más útiles para el posterior
programación. Ejemplos: podrían ser análisis.
palabras clave (if, else, while, int)
identificadores, números, signos, o un
operador de varios caracteres, (por
ejemplo, := "':+"' ).
Tanto el analizador léxico como el sintáctico pueden ser escritos en
cualquier lenguaje de programación.
A pesar de la habilidad de tales lenguajes de propósito general como C,
Lex y Yacc son más flexibles y mucho menos complejos de usar.

Lex genera el código C para un analizador léxico, y Yacc genera el


código para un parser (analizador sintáctico).

Tanto Lex como Yacc toman como entrada un archivo de


especificaciones que es típicamente más corto que un programa hecho
a medida y más fácil de leer y entender.
Por convención, la extensión del archivo de las especificaciones para Lex
es .l y para Yacc es .y. La salida de Lex y Yacc es código fuente C.

Lex crea una rutina llamada yylex en un archivo llamado lexyy.c.


Yacc crea una rutina llamada yyparse en un archivo llamado y_tab.c
La estructura de un archivo de lex es intencionadamente similar a la de
un archivo del yacc; los archivos se dividen en tres secciones:

•La sección de declaraciones: es el lugar para definir macros y para


importar los archivos de cabecera escritos en C. También es posible
escribir cualquier código de C aquí, que será copiado en el archivo
fuente generado. Este código en C debe ir entre los símbolos %{ %}.
•La sección de reglas: es la más importante; asocia patrones a sentencias
de C. Los patrones son simplemente expresiones regulares. Cuando el
lexer encuentra un texto en la entrada que es asociable a un patrón
dado, ejecuta el código asociado de C. Ésta es la base de del
funcionamiento de lex.
•La sección de código C: contiene sentencias en C y funciones que serán
copiadas en el archivo fuente generado
Atributos con Yacc
La función yyparse gestiona una pila paralela a la del análisis sintáctico. Esa pila contiene elementos del
tipo YYSTYPE, que por defecto esta definido a int. Para acceder a esta pila en las acciones se debe utilizar
una notación especial (que yacc traduce a código en C):

• Los símbolos de la parte derecha se numeran del uno en adelante (las acciones en medio de las partes
derechas ocupan el espacio de un símbolo y es necesario tenerlo en cuenta).
• Para hacer referencia a la posición en la pila de un símbolo se pone (dentro del código en C) $n,
donde n es el
• numero de ese símbolo en la parte derecha.
• Para hacer referencia a la parte izquierda se pone $$ (solo en acciones al final de la parte derecha,
justo antes
• de que el analizador reduzca por la regla
• Es muy aconsejable situar las acciones semánticas al final de las reglas. Cuando no sea posible, es
recomendable
• situarlas siempre entre terminales o variables que no generen; si se colocan después de una variable
que
• puede derivar a es probable que el yacc no pueda decidir cuando realizar la acción y produzca
conflictos reduccion-reduccion.
Comunicación entre yacc y lex

• Los programas que son generados por yacc y lex estan diseñados para funcionar
juntos. Así, lex debe devolver los números de token que asigna yacc. Para ello es
necesario ejecutar yacc con la opción -d, que hace que yacc genere un fichero
y.tab.h que contenga solo los defines de los tokens.
• Ese fichero debe ser incluido con #include en el fichero de lex, al principio, para que
los tokens sean conocidos dentro del código generado por lex. Además de devolver
un entero indicando que token se ha reconocido, el analizador léxico debe devolver
el valor léxico de ese token.
• El lexema que el analizador generado por lex ha reconocido se copia en la cadena
de caracteres Yytext.
• El analizador léxico debe procesar esa cadena de caracteres (convertirla a numero,
etc.) y devolver al analizador sintáctico el valor léxico del token (que no tiene por que
coincidir con el lexema). Para hacer esto con yacc y lex existe una variable YYSTYPE
yylval12 que debe rellenar el analizador lexico13 y que yacc copia en la pila
semántica cuando desplaza el símbolo a la pila sintáctica.
EJEMPLO DE UN ARCHIVO FLEX
Si se da esta entrada a flex, será convertida en un archivo de C, lex.yy.c.
Esto se puede compilar en un ejecutable que encuentre y haga salir
cadenas de números enteros. Por ejemplo, dando la entrada:

abc123z.!&*2ghj6

el programa imprimirá:

Encontrado un entero: 123


Encontrado un entero: 2
Encontrado un entero: 6

También podría gustarte