compiladores e intérpretes análisis léxico ii profesor: eridan otto

23
Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Upload: josefa-de-la-cruz-bustos

Post on 02-Feb-2016

232 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Compiladores e intérpretesAnálisis Léxico II

Profesor: Eridan Otto

Page 2: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis Léxico II

• Implementación de un AL• Tabla de símbolos• Interfaz con el analizador sintáctico• Tratamiento de errores• Generador de Al

Page 3: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un AL Compiladores e intérpretes

– Implementación de autómatas finitos con Arreglo – Reconociminto de una constante numérica cualquieraConst::=[0-9]*(.[0-9]+)?(e[0-9]+)?, donde ? Significa una o 0 veces.

Ejemplos:123.1,.212,2.123e10,12e1,...d = 0..9

0

41

3

d2

d

Return(const_entero)

5

.

d

.

d

dReturn(const_real)

6

e

ed

d Return(const_real_exp)

Page 4: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un AL Compiladores e intérpretes

– Implementación de autómatas finitos con Arreglo El arreglo queda definido por sus filas que corresponden a los estados y sus

columnas que corresponden a la entrada,los guiones son estados de error y deben dar un tratamiento de errores. Además debe incluirse un arreglo con la acción, indicando que el estado es final

. d e 0 1 2 -1 - 4 -2 3 2 53 - 4 -4 - 4 55 - 6 -6 - 6 -

estado actual

entradaestados finales accion 2 Return(const _entero) 4 Return(const _real) 6 Return(const real_exp)

Page 5: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un AL Compiladores e intérpretes

– Implementación de autómatas finitos con Arreglo PseudocódigoAcceso al próximo estado:valor=“”;siguiente_estado:=“-” c:=Getchar() final:=falseWhile( IsDigit(c) or c=‘.’ or c=‘e’) and NOT final do valor:=valor + c Siguiente_estado:=transic[estado_actual][c] c:=Getchar() if siguiente_estado=“-” then final:=true else if siguiente estado está en estados_finales then final:=true else estado_actual:=suguiente_estado FinWhile if siguiente_estado está en estados finales then fail() else rertact() token=de acuerdo a tabla de estados finales y convanum(valor) Accept() Return(token)

Page 6: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un AL Compiladores e intérpretes

– Implementación de autómatas finitos con Tabla compacta– Esencialmente es la misma idea de usar un arreglo como función de

transición.– Para ahorrar memoria se guardan los elementos no nulos en una matriz

VALOR de dos columnas y con tantos elementos como posiciones no nulas del arreglo original TRANSIC.

– Se crea otro arreglo o tabla, PIRFIL, con el primer valor de cada fila de VALOR y una segunda columna con el número de elementos no nulos de una fila valor col

0 1 01 2 12 4 13 3 04 2 15 5 26 4 17 4 18 5 29 6 110 6 1

prifil fil0 0 21 2 12 3 33 6 14 7 25 9 16 10 1

Ejemplo•Transic(2,1)•Prifil(2)=3•Fil=3, significa que losElementos 3 ,4 ,5 de valor contienen lastransiciones del estado 3El que tiene el valor col=1 corresponde a 2.

Page 7: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un AL Compiladores e intérpretes

– Implementación de autómatas finitos:programado– Representa directamente con un programa el autómata en cuestón:

estado :=0;valor:=“” salir :=false while not salir do car :=getchar() case estado of 0: if car =“.” then estado:=1 else if IsDigit(car) then estado:=2 else salir:=true 1: if IsDigit(car) then estado:=4 else salir:=true 2: if car =“.” then estado:=3 else if car =“e” then estado:=5 else if IsDigit(car) then estado:=2 else salir:=true ..... if not salir valor:=valor+car endCase endWhile if estado = 2 or estado = 4 or estado = 6 then rertact() token=de acuerdo a tabla de estados finales y convanum(valor) Accept() Return(token) else fail()

Page 8: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un AL Consideraciones– El AL agrupa caracteres para formar tokens, por lo tanto es importante

definir el “delimitador “– Definición: carácter que separa dos lexemas sin pertenecer al patron de

los tokens– Otro concepto importante es el de “palabra reservada”

– El lenguaje prohibe el uso libre al programador de determinadas palabras que tienen un significado específico y único en el lenguaje

– Se pueden clasificar los lenguajes de programación por el uso de los delimitadores y palabras reservadas:

– Delimitadores blancos con palabras reservadas– Caso más simple para un AL (C, PASCAL)

– Delimitadores blancos sin palabras reservadas– Produce ambiguedades, Ej:PL/ISentencia válida:IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;

– Blancos se ignoran sin palabras reservadas– Este es el caso más dificil. Aparecen ambiguedadesEj:FORTRAN

Compiladores e intérpretes

Page 9: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un AL Acciones semánticas– El AL no es sólo la implementación de un autómata que identifica una

cadena como válida o inválida.– Realmente realiza una “traducción” (conceptualmenta hablando), frente a

lexemas toma ciertas acciones clasificándolos.– El scanner realiza comprobaciones en la tabla de símbolos– Las acciones semánticas más comunes son:

– AÑADIR: concatena caracteres para construir cadenas (+)– LEECAR: lee caracteres de entrada (Getchar())– VER:comprueba si un identificador está o no en la tabla de símbolos– AGREGA:añade un identificador a la tabla de símbolos

Compiladores e intérpretes

Page 10: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Implementación de un ALCompiladores e intérpretes

Eliminación de comentarios• Depende de la estructura de comentrios que se defina, el autómata será

diferente. La idea es que una vez reconocido, el analizador no envíe token a el parser y siga con la próxima cadena.

• Ej: comentarios en C /* $.....*/ donde $ representa cualquier carácter distinto de * y /. Aquí surge la posible detección de / como operador

1

43

$2 Return(op)

*

*6

/

0/

$ $

Comentario, seguir explorando

Page 11: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Tabla de SímbolosConsideraciones– Una función esencial es almacenar los identificadores definidos en el

programa fuente y recopilar información acerca de varios atributos de cada uno.

– Los atributos proveen información de:– la cantidad de almacenamiento asignado al identificador– su tipo– su ámbito (área de validez dentro del programa)– en caso de procedimientos o funciones, alcunas cosas como el número

y tipo de parámetros, el método de pasada de cada parámetro (Ej:referencia), el tipo retornado por la función.

– La tabla de símbolos es una estructura de datos que contiene un registro para cada identificador.

– El objetivo es poder acceder al registro de un identificador rápidamente para almacenar o recuperar datos.

– El analizador léxico es el primer proceso que hace uso de la tabla de símbolos.

Compiladores e intérpretes

Page 12: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Tabla de SímbolosConsideraciones– Sin embargo muchos atributos del identificador no pueden ser

determinados durante esta fase.– Ej: en PASCAL VAR i,desviacion:REAL. El tipo REAL no es

conocido para el AL al agregar los identificadores promedio y desviación. Sin embargo en otras fases se van completando los datos y utilizando la tabla.

– Interfase con la tabla de símbolos– El detalle de las dos funciones anteriores:

– AGREGA(S,T): retorna el índice de la tabla de símbolos donde se ha ubicado un nuevo identificador cuyo lexema es S y T su Token

– VER(S):retorna el índice de la entrada a la tabla para S o 0 si no es encontrado.

– Cuando un identificador es detectado en el programa fuente por el AL– Comprueba (VER) si este ya existe– Si no existe AGREGA el identificador a la tabla de símbolos

– Manejo de palabras reservadas– Una forma simple de asegurarse de que no se usen como identficadores

es agregar todas las palabras reservadas a la tabla de símbolos al iniciarce el análisis léxico.

Compiladores e intérpretes

Page 13: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Tabla de SímbolosCompiladores e intérpretes

Implementación• Estructura de datos

• Consieraciones de eficiencia espacial y temporal. Una primera aproximación, que se refinará más adelante tiene la siguiente estructura.

Arreglo tab_sym

1 Begin2 Const3 id4 id

indice token ptrlex

B e g i n / C o n s t i d e s v i a c i o n

Arreglo lexemas. Usa / seperador de strings, eventualmente permite hahorrar espacio frente a la alternativa de manejar los lexemas en la tábla de símbolos con un largo fijo.Por otro lado la estructura de los atributos quedará por ahora sin definir.

/ / /

atributos

Page 14: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Tabla de SímbolosCompiladores e intérpretes

Implementación• Acceso a la tabla

• Como ya se ha visto las operaciones que reliza el analizdor léxico sobre la tabla de símbolos son de inserción y búsqueda de identificadores (palabras reservadas). Estas operaciones deben realizarce muy rápidamente, y su velocidad , idealmente debiera ser independiente del tabaño del arreglo.

• Uso de métodos de HASH (transformación de claves)• La idea es asignar un valor al string del lexema de manera que sirva de

clave de acceso a la tabla:• Llave=h(lexema)

• Implementación:Const TAM_HASH= 997

Function hash(s:string):integerVar clave:longint;i:integer;Begin clave:=0; for i:=1 to largo(s) do clave := clave + 1000*ORD(s[i]); hash(clave MOD TAM_HASH)End;

Page 15: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Tabla de SímbolosCompiladores e intérpretes

Implementación• Acceso a la tabla:Hashing

• Si se usa este método hay que cubrir el posible problema de las colisiones. Estas se pueden resolver con varios métodos de resolución, por ejemplo:

• Encadenamiento directo: consiste en construir una lista enlazada a partir de la posición ocupada. (Habría que ahregar un campo al registro para fabricar la lista)

• Es recomendable usar la función módulo para asegurar una distribución uniforme entre [0,TAM_HASH]. Se recomienda que el tamaño máximo de la tabla sea un número primo para reducir la posibilidad de colisiones.

• Esta función debiera agregarse a VER y BUSCAR.• Se pueden pensar otros esquemas alternativos, (Estructura de datos)

dependiendo del compilador el lenguaje y su uso.

Page 16: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Interfaz con el analizador sintáctico

Compiladores e intérpretes

• El analizador léxico es habitualmente una función o método de la clase lexico, denominado por ejemplo yylex(), llamado por el analizador sintáctico.• El método o función yylex() toma el siguiente lexema o token del programa

fuente o del buffer y devuelve al parser el tipo de componente léxico y el atributo del token en una variable o registro que puede llamarse yylval. Los atributos pueden ser de distintos tipos según el componente léxico reconocido

• Los tipos de componentes léxicos o tokens se definen por medio de constantes enteras predefinidas o con un tipo enumerado para su representación interna.

• Ejemplo representación interna deTOKENS implementados en C:# define IDENTIFICADOR 300# define CADENA 301# define RELACION 302# define IF 303.....• Ejemplo representación interna deTOKENS implementados en PASCAL :CONST IDENTIFICADOR = 300;

CADENA = 301; RELACION = 302; IF = 303;

Page 17: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Interfaz con el analizador sintáctico

Compiladores e intérpretes

• Ejemplo representación interna de yylval implementado en C:extern union{ int tokenrec; int pt_simbolo; /*indice a la tabla de símbolos*/ int atributo_entero; /*caso en que el atributo sea un número entero*/ int atributo_real; /* caso en que el atributo sea un número real*/ char *atr_string;} yylval;

• Ejemplo de dunción analizador léxica que devuelve la variable token con estructura de yylval implementado en C:

yylval yylex(){ yylval token; .......

Return(token)}• Las ideas de cómo implementar el código para devolver un token correcto ya

han sido vistas.

Page 18: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Tratamiento de erroresCompiladores e intérpretes

• Debe servir a otras fases que detectan la mayor cantidad de errores manteniendo una variable, por ejemplo yylineo, que indique la línea en curso. Esta variable es usada por el módulo de tratamiento de errores.

• Los erores léxicos propiamente tales son escazos, formalmente se producen si se introducen caracteres no permitidos en el alfabeto de entrada o cuando una expresión regular no es reconocida.

• Por ejemplo para el caso• Then::= 3 + x1 , hay un error, falta un if o then: es un

identificador???• Errores detectables

• Límite para número de caracteres de los identificadores sobrepasado• Carácter ilegal• Restricciones propias del lenguaje, por ejemplo .5 no aceptado, si 0.5• Falla en el reconocimiento 32. O identificador 1aab

Page 19: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Tratamiento de erroresCompiladores e intérpretes

• Se informa al módulo de errores y se sigue procesando deteniéndose y avisando al usuario de los errores

• Acciones posibles• Borrar un carácter• Insertar un carácter• Reemplazar un carácter• Intercambiar caracteres

• Corrección automática es muy costosa

Page 20: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Generador de ALCompiladores e intérpretes

• Se han desarrollado algunas herramientas para construir analizadores léxicos a partir de notaciones de propósito especial basadas en expresiones regulares.

• Como ejemplo se verá el lenguaje LEX y el generador de AL PCLEX. Este lenguaje permite expresar expresiones regulares y la acción a tomar al encontrar cada una de ellas. http://www.abxsoft.com/ se puede conseguir una versión en demostración.

• El programa fuente generado es la implementación de un autómata finito reconocedor de los componentes léxicos. Habitualmente genera código C.

• Es posible que se requiera alguna modificación a el código, luego se compila y el analizador lexico se transforma en un ejecutable.

• Interactúa con el parser de la siguiente forma: cuando es activado, por el parser, el analizador léxico genera una función llamada yylex, que una vez llamada comienza a leer la entrada, carácter a carácter, hasta que la cadena concuerde con alguna expresión regular, entonces se ejecuta la acción correspondiente, si es un token devuelve el control al parser junto con la información del mismo en yylval, en otros casos realiza labores propias del AL y sigue procesando.

Page 21: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Generador de ALCompiladores e intérpretes

• Especificaciones generales:un archivo de entrada en lex se compone de tres secciones:

%{ codigo c en la cabecera }%Declaraciones o definiciones%%Reglas o acciones%%Procedimientos auxiliares del usuario• En la primera sección generalmente se definirá

nombre expresión regular que lo reconoce• Lex siempre toma el lexema más largo que concuerda con la expresión • En caso de conflicto asigna el nombre definido primero. Es por eso que las

palabras se definen antes que el identificador.• Ejemplo de caracteres especiales en lex:

• []: indica clases de caracteres. [abc] es equivalente a(a|b|c). -: rango• ?:una o ninguna vez. * :0 mas veces lo que lo precede. + : una o más veces

lo que lo precede. . : representa cualquier carácter exepto retorno de carro• ():agrupación

Page 22: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Generador de ALCompiladores e intérpretes

• La segunda sección es la principal y generalmente se definiráexpresión acción

• Expresión: es una expresión regular o un nombre definido en la sección anterior. En este último caso deberá ir entre llaves.

• Acción: Es un fragmento de programa en C, que indica la acción a tomar por el analizador léxico, cuando reconoce el patrón situado a su izquierda.

• Hay una serie de funciones y variables propias de lex que están disponibles en la parte de acciones.

• La tercera sección corresponde a procedimientos auxiliares, formada exclusívamente de código C.

Ejemplo simple: permite contar cuantas veces aparece la palabra “casa” en un archivo.

%{ int cont=0 %}%%casa {cont++;}.|\n {;}%% Void main() { yylex(); printf(“casa aparace %d veces”,cont);}

Page 23: Compiladores e intérpretes Análisis Léxico II Profesor: Eridan Otto

Análisis léxicoII: Generador de ALCompiladores e intérpretes

• Podría usarse para reconocer como analizador léxico:delimitador [ \n\t]blancos {delimitador}+letra [a-zA-Z]digito [0-9]id {letra}({letra}|{digito})*numero {digito}+(.{digito}+)?(E[+-]{digito}+)?%%{blancos} {}if {return(IF)}then {return(THEN)}while {return(WHILE)}.... .......

{id} {yylval.pt_simbolo = Installname(yytext)...; return(yylval)} {numero} {yylval.atributo_real = yytext...; return(yylval)}

> {yyval.token=RELACION;yylval.atr_string=“<“;return(yylval}

%% Definicion de funciones usadas arriba