Sunteți pe pagina 1din 47

Programacin de Sistemas Unidad IV INTRPRETES Y COMPILADORES

MCC Enrique Ayala Franco

Objetivo y Temas Objetivo Disear e implementar un sistema que realice las funciones de un intrprete y/o compilador. Temas 4.1 Intrpretes: caractersticas y componentes 4.2 Compiladores: caractersticas y componentes. 4.3 Diferencias entre intrpretes y compiladores. 4.4 Diseo e Implementacin de los componentes de un compilador y/o un intrprete.
4.4.1 Analizador lxico, sintctico y semntico 4.4.2 Generacin de Cdigo objeto y ejecutable
2

4.4 Diseo e Implementacin de los componentes de un compilador y/o un intrprete. La implementacin de un compilador puede hacerse usando dos alternativas: Implementacin automtica
Especificacin de los patrones de la gramtica Uso de LEX y YACC para el lenguaje C (FLEX y BISON ms modernos y eficientes, JFLEX/Cup para Java)

Implementacin manual
Codificacin con estructuras condicionales (if, case, )

4.4.1 Analizador lxico, sintctico y semntico

ANALIZADOR LXICO Programa Fuente = Serie de Smbolos Los smbolos representan las construcciones del lenguaje
Variables, etiquetas, palabras reservadas, constantes, operadores

El analizador lxico identifica los significados de estas construcciones Lee el programa fuente carcter a carcter Los compara con patrones que representan unidades sintcticas primarias o tokens.
5

ANALIZADOR LXICO Un analizador lxico: Transforma el programa fuente en tiras de tokens

Cada token pueden tener asociado uno o varios atributos Ejemplo: Un atributo de un token puede ser un puntero a la tabla de smbolos o un puntero a la tabla de constantes.
6

Ejemplo 1
posicin := principal + velocidad * 60
IDENT ASIGNACION IDENT MAS IDENT POR ENTERO

Funciones del Analizador Lexicogrfico


Funciones Bsicas
Leer carcter a carcter del programa fuente. Entregarle los tokens identificados al analizador sintctico Producir parte del listado con los errores de compilacin

Funciones Complementarias
Ignorar, del programa fuente los comentarios, espacios en blanco y tabuladores. Reconocer las palabras reservadas del lenguaje. Reconocer las variables y asignarles una posicin en la tabla de smbolos. Relacionar mensajes de error con el nmero de lnea en el que aparecen. 8

Lexemas, expresiones regulares y tokens


perimetro := radio + 47

IDENT ASIG IDENT MAS ENTERO


9

Lexemas, expresiones regulares y tokens


Lexemas:
Son caracteres o conjuntos de caracteres (palabras) que pertenecen al lxico del lenguaje.

Expresiones Regulares (Patrones):


Definen las reglas que permiten identificar los componentes lxicos o tokens.

Tokens:
Son los componentes lxicos generados por el analizador lexicogrfico

Atributos:
Son informacin adicional para cada componente lxico que sern utilizadas en el anlisis semntico y/o en la fase de sntesis (ej. Lexema, Tipo, Valor, Lnea). Depende del token
10

Ejemplo 2
Expresiones Regulares a*(b | c)+ L1 = {w : w=a*(b | c)+}
bccbcbccbc abbbccc abbcbcccbbc

(0-9)*.(0-9)+
0.236425 3567.45627 .753473 5.0

L2 = {w: w=(0-9)*.(0-9)+}
a* 0 o ms a (b | c) b o c c+ 1 o ms c 0-9 0 1 2 9
11

Ejemplo 3

12

Implementacin de analizador lexicogrfico con LEX Uso bsico:


Implementacin de la fase de Anlisis Lexicogrfico de un compilador. Uso combinado con el Analizador sintctico YACC

Otros usos de Lex:


Transformaciones sencillas de ficheros fuente Ej: Dado un texto completamente en maysculas convertirlo en un texto en formato frase: mayscula slo la primera letra de una palabra tras un punto.

13

Implementacin de analizador lexicogrfico con LEX Acepta una especificacin del lenguaje de programacin mediante un conjunto de expresiones regulares A cada expresin regular se le puede asociar cdigo C que se ejecutar cuando se identifique el correspondiente lexema en el programa de entrada Genera un programa en C (yylex) que reconoce dichas expresiones regulares Si se usa conjuntamente con YACC los tokens identificados se pasan directamente al analizador sintctico.
14

Ejemplo 4
Programa para borrar de la entrada todos los espacios en blanco y todos los tabuladores del final de lnea:
%% [ \t]+$ ;
%% Indica el inicio de las rdenes

Expresin Regular: Una o ms (+) apariciones del espacio en blanco ( ) o tabulador (\t) antes del final de la lnea ($) Accin: No se hace nada si est al final Qu se hace con el resto de los caracteres?
Se pasan todos directamente a la salida

15

Para usar el lex (flex)


Para correr el ejemplo: $ flex ejem4.l (extensin .l o .lex) si tiene xito, generar el archivo lex.yy.c. $ cc -o ejem4 lex.yy.c -ll $ ./ejem4

16

Para usar el lex (flex) en windows


Para correr el ejemplo: > flex ejem4.l (extensin .l o .lex) si tiene xito, generar el archivo lex.yy.c. >cc -o ejem4 lex.yy.c L. libfl.a >ejem4

17

Formato del archivo LEX


Formato del Fichero Fuente
El formato general de un fichero lex es: {definiciones} %% {rdenes} %% {subrutinas del usuario}

Las definiciones y subrutinas se omiten a menudo


Programa lex mnimo: %%

Copia la entrada exactamente igual en la salida


18

Ejemplo 5
rdenes:
%% Integer printf(Localizada palabra reservada INT); Float printf(Localizada palabra reservada FLOAT);

Columna izquierda: Expresiones regulares Columna derecha: Fragmentos de programa o Acciones

19

Ejemplo 6
Programa que cambia palabras de la ortografa britnica a la ortografa americana
%% colour mechanise petrol printf(color); printf(mechanize); printf(gas);

Qu ocurrira si el fichero de entrada contiene la palabra petroleum?


En la salida tendra petroleum?? En la salida tendra gaseum??
20

Expresiones Regulares en Lex


Expresin :: Conjunto de literales Literales :: caracteres de texto | operadores Caracteres de texto :: Carcter correspondiente del literal que se compara
Las letras del alfabeto y los dgitos son siempre caracteres de texto

Operadores :: \ [ ] ^ - ? , * + | ( ) $ / { } % < >


Para usarlos como caracteres de texto incluirlos entre comillas dobles o usar \ delante

21

Expresiones Regulares en Lex Clases de Caracteres


[abc]
Cualquier carcter que sea una a o una b o una c

[a-z0-9<>_]
Cualquier carcter desde la a a la z o un dgito del 0 al 9, o < o > o _

[-+0-9]
Cualquier dgito o los signos - y + Como - es un operador para incluirlo como carcter debe ir al principio de la clase de caracteres

[^abc]
Todos los caracteres excepto a, b y c
22

Expresiones Regulares en Lex


Expresiones opcionales Uso de ?
ab?c
Coincide con ac y con abc. La b es opcional

Expresiones repetidas Uso de * o +


a*
0 o ms repeticiones del carcter a

a+
1 o ms repeticiones del carcter a

[A-Za-z][A-Za-z0-9]*
Identificadores que empiezan por una letra (mayscula o minscula) y siguen por 0 o ms letras o dgitos

23

Expresiones Regulares en Lex Expresin de alternacin Uso de |


(ab|cd)
Coincide con ab o con cd.

Expresin de agrupamiento Uso de ( )


(ab | cd+)?(ef)*
Coincide con literales como abefefef, efefefef, cdefefef, cddddd, cddddef. No coincide con literales como abc o abcddd

24

Expresiones Regulares en Lex


Sensitividad de Contexto Uso de ^ y $ y /
^ Identifica comienzo de lnea $ Identifica fin de lnea / Identifica contexto al final

ab/cd
Reconoce ab pero slo si va seguido de cd.

ab$
Reconoce ab pero slo si est al final de lnea Es equivalente a ab/\n

^ab
Reconoce ab pero slo si se encuentra al comienzo de lnea
25

Acciones LEX
Accin por defecto
Copiar los literales de la entrada a la salida Se realiza por defecto con todos los literales que no coinciden con ninguna expresin regular Cuando se usa LEX con YACC hay que asegurarse que todos los literales coinciden con alguna expresin regular

Accin nula
Se descarta la entrada de datos y no se pasa nada a la salida Ejemplo:
[ \t\n] ;

26

Acciones LEX
Conocer el lexema que se ha reconocido
Lex deja este texto en una matriz de caracteres llamada yytext Ejemplo:
[a-z]+ printf(%s, yytext);

Alternativa:
[a-z]+ ECHO;

Conocer el tamao del lexema ledo


Ejemplo: Contar nmero de palabras de entrada y caracteres en esas palabras
[a-zA-Z]+ {words++; chars+=yyleng;}

27

Manejo de Especificaciones Ambiguas


Cuando ms de una expresin puede coincidir con la entrada analizada: Se prefiere la coincidencia ms larga De entre las coincidencia de la misma longitud se elige la que aparezca primera en la definicin Ejemplo:
%% integer printf(palabra reservada INT); [a-zA-Z]+ printf(Identificador);

Cmo se reconoce integer? Y integers?y int?


28

Seccin de Definiciones en LEX


Se especifican antes del primer delimitador %% Zona de definicin de variables
Para uso del programa que se generar Para uso del LEX

Cualquier definicin que comience en la columna 1 define literales de sustitucin del LEX
Se utilizan para simplificar la definicin de las rdenes Formato: nombre interpretacin
El nombre tiene que empezar por una letra

29

Ejemplo 7
Seccin de definiciones
D E [0-9] [DEde][-+]?{D}+

Seccin de rdenes
%% {D}+ {D}+.{D}*({E})?| {D}*.{D}+({E})?| {D}+{E} printf(integer);

printf(real);

30

LEX y YACC
Para utilizar de forma conjunta LEX y YACC cada orden LEX debe acabar con:
return(token); Se le indica al YACC el token ledo

Adems si se trata de un analizador lxico para construir un compilador:


ser necesario aadir informacin a las tablas de smbolos ser necesario guardar informacin sobre los atributos de cada token

31

Ejercicio 1
Construir un analizador lxico que sea capaz de reconocer sentencias de la forma: nuevo := viejo * RAZON + 2
Los identificadores tienen que empezar por una letra Los nmeros pueden ser enteros o reales Las operaciones vlidas son la de +, -, * y / No puede haber mas de un 0 a la izquierda de un nmero La salida ser:
IDENT ASIGNACION IDENT POR IDENT MAS ENTERO

32

Solucin ejercicio 1
%% [a-zA-Z][0-9a-zA-Z]* (0|[1-9][0-9]*) (0|[1-9][0-9]*)\.[0-9]* "+ ":=" "-" "* "/ " \t \n . %% int main() { yylex(); } { printf(" IDENT "); } { printf(" ENTERO "); } { printf(" REAL "); } { printf(" MAS "); } { printf(" ASIGNACION "); } { printf(" MENOS "); } { printf(" POR "); } { printf(" DIV "); } ; ; ECHO; { printf(" Caracter inesperado: %c",yytext[0]); }

33

Ejercicio 2
Modificar el analizador anterior para que acepte sentencias condicionales de la forma:
IF (x==5) THEN var := 4 ENDIF

Usar como operadores lgicos slo == Las palabras claves del lenguaje se pueden escribir tanto en minsculas como en maysculas
IF, if, If, iF Todas representan el inicio de una sentencia condicional
34

Solucin Ejercicio 2
%% [If][fF] [Ee][Nn][Dd][If][Ff] [Tt][Hh][Ee][Nn] [a-zA-Z][0-9a-zA-Z]* (0|[1-9][0-9]*) (0|[1-9][0-9]*\.[0-9]*) "+" ":=" "-" "*" "/" "==" [ \t] [\n\(\)] . %% int main() { yylex(); } { printf(" IF "); } { printf(" ENDIF "); } { printf(" THEN "); } { printf(" IDENT "); } { printf(" ENTERO "); } { printf(" REAL "); } { printf(" MAS "); } { printf(" ASIGNACION "); } { printf(" MENOS "); } { printf(" POR "); } { printf(" DIV "); } { printf(" IGUAL_A ");} ; ECHO; { printf(" Caracter inesperado: %c",yytext[0]); }

35

Ejercicios 3,4,5 y 6
3. Escribir un analizador lxico que reciba como entrada un texto y muestre como salida el nmero de caracteres, el nmero de palabras y el nmero de lneas que hay en el texto 4. Escribir un analizador lxico para cifrar un texto de entrada invirtiendo el orden de las letras de cada palabra 5. Modificar el programa anterior para que cifre todo menos los nmeros, que deben mantenerse en el orden en el que aparecen 6. Modificar el programa anterior para que invierta lnea a lnea y no palabra a palabra
36

Solucin ejercicio 3
%{ #include <stdlib.h> static unsigned ncaracteres = 0; /* nmero de caracteres*/ static unsigned npalabras = 0; /* nmero de palabras*/ static unsigned nlineas = 0; /* nmero de lineas*/ %} %% \n ncaracteres += 2, ++nlineas; /* fin de linea es CR LF*/ [^ \t\n]+ ++npalabras, ncaracteres += yyleng; . ++ncaracteres; %% main() { yylex(); printf("%d %d %d\n",ncaracteres,npalabras,nlineas); exit(0); }

37

Solucin ejercicio 4
%% [^ \t\n]* { char auxiliar; int cont; for(cont = 1; cont <= (yyleng / 2); cont++) { auxiliar = yytext[cont - 1]; yytext[cont - 1] = yytext[yyleng - cont]; yytext[yyleng - cont] = auxiliar; }; ECHO; } %% int main() { yylex(); }

38

Solucin ejercicio 5
%% [0-9]+ ECHO; [^ \t\n]* { char auxiliar; int cont; for(cont = 1; cont <= (yyleng / 2); cont++) { auxiliar = yytext[cont - 1]; yytext[cont - 1] = yytext[yyleng - cont]; yytext[yyleng - cont] = auxiliar; }; ECHO; } %% int main() { Cul sera el yylex(); 1. C/ Barbero, }

resultado de cifrar n 28 2. C/ Barbero, n28

39

Solucin ejercicio 6
%% [^\n]* { char auxiliar; int cont; for(cont = 1; cont <= (yyleng / 2); cont++) { auxiliar = yytext[cont - 1]; yytext[cont - 1] = yytext[yyleng - cont]; yytext[yyleng - cont] = auxiliar; }; ECHO; } %% int main() { yylex(); }
40

Ejercicio 7 Escribir un analizador lxico para cifrar un texto de la siguiente forma:


Tamao(palabra) <= 4 letras inversa Tamao(palabra) == 5 6 letras inversa en bloques de dos caracteres Tamao(palabra) == 7,8 9 letras en bloques de 3 caracteres Tamao(palabra) > 9 en bloques de 4 caracteres

41

Solucin Ejercicio 7
%{ char auxiliar; int cont, agrupador; #define REVES(paso) cont = yyleng - paso; do { for(agrupador = 0; agrupador < paso; agrupador ++){ if (yytext[cont + agrupador] != '\0') { printf("%c", yytext[cont + agrupador]); yytext[cont + agrupador] = '\0'; } } if (cont > 0) { cont -= paso; if (cont < 0) cont = 0; } else cont = -1; } while (cont >= 0); %} %% [^ \t\n]{1,4} { REVES(1); } [^ \t\n]{5,6} { REVES(2); } [^ \t\n]{7,9} { REVES(3); } [^ \t\n]* { REVES(4); } %%

\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

42

Ejercicio 8
La Secretara de la E.T.S.I. de Informtica recibe de los Departamentos las notas de los alumnos en un fichero formato texto, en el que cada lnea posee tres campos separados por espacios: D.N.I. del alumno, Convocatoria del examen (Diciembre, Febrero o Junio), y la Nota. Hacer un programa LEX que efecte la lectura de dicho fichero, emitiendo al final la media de las notas recuperadas. Asimismo informar de los errores de formato que se pueda encontrar: lneas en las que falten campos, valores incorrectos, etc NOTAS: Para convertir un array de caracteres a un nmero usar sscanf(yytext,%d,&nota); donde nota es una variable de tipo entero.

43

Variable y funciones ya implementadas en lex


Prototipo char *yytext; int yyleng; FILE *yyin; FILE *yyout; int input(void); void unput(int); void output(int); Descripcion Contiene el token que acaba de ser reconocido, su uso es principalmente dentro de las reglas, donde es comun hacer modificaciones al token que acaba de ser leido o usarlo con algun otro fin. En el ejemplo 1 este token es usado para dar echo en la pantalla. Contiene la longitud del token leido, su valor es equivalente a yyleng = strlen(yytext);. Es un apuntador del que se leen los datos, si este no se modifica, su valor por defecto es stdin. Es un apuntador a la salida por default del programa, su valor predefinido es stdout. Esta es en realidad una macro, cuya funcion es alimentar al tokenizer cada vez que se le llama, esta regresa el siguiente caracter de la entrada. Esta macro hace lo contrario a input(), esta pone el caracter especificado como argumento de regreso a la entrada del flujo. Esta macro, escribe su argumento en yyout.

int yyinput(void);

Es una interfaz para la macro input().

void yyunput(int); Es una interfaz para la macro unput(). void yyoutput(int); Es una interfaz para la macro output(). Esta funcion sirve para manejar las condiciones de fin de archivo, cada vez que el lexer llega a un fin de archivo, llama a esta funcion para saber que hacer, si regresa 0, entonces sigue leyendo de la entrada, si es 1 el lexer regresa un token nulo para indicar que se llego al fin de archivo. Esta es la funcin principal de un lexer, para aadir cdigo a esta funcin, es necesario, incluirlo en la seccin de reglas encerrado entre %{ y %}.

int yywrap(void);

int yylex(void);

44

Ejemplo 8
Si quisiramos cambiar la entrada estndar para que se lea desde un archivo:
main(int argc, char *argv[]){ If (argc==2) { //por default yyin apunta a stdin, ahora lo cambiamos. yyin = fopen(argv[1],r); } Yylex(); }
45

Ejemplo 9
Ahora entrada y salida estndar:
int main(int argc, char *argv[]){ if (argc==2){ //por default yyin apunta a stdin, // se cambia al archivo 1 pasado por argumento. yyin = fopen(argv[1],"r"); } if (argc==3) yyin = fopen(argv[1],"r"); //por default yyout apunta a stout, // se cambia al archivo 2 pasado por argumento. yyout = fopen(argv[2],"w"); } yylex(); }
46

Bibliografa
Tutorial de Lex y Yacc
http://www.medinaweb.com/programas/documents/tutoriales/lex_yacc/core/l exyak.html

Sergio Glvez Rojas. Libro Electrnico: Java a tope: Traductores y compiladores con Lex/Yacc, JFlex/Cup y JavaCC, Universidad de Mlaga. La pgina de Lex y Yacc
http://dinosaur.compilertools.net/

47

S-ar putea să vă placă și