PRACTICA 3

Anuncio
LABORATORIO DE PROCESADORES DE LENGUAJE
Curso: 2008-2009
Práctica 2: Analizador léxico/sintáctico/semántico con Flex y Bison
Planteamiento del problema
En esta práctica se trata de realizar, mediante el generador de analizadores léxicos FLEX y sintácticos BISON,
un analizador léxico, sintáctico y semántico que reconozca una simplificación del lenguaje de alto nivel
VisualBASIC. Además, la práctica deberá incluir la construcción de la Tabla de Símbolos (TS)
correspondiente.
Especificación a nivel léxico
Consideraremos como comentario todo aquello que vaya precedido por la palabra reservada REM y hasta final
de línea. Por ejemplo: REM Esto es un comentario.
Los identificadores (ID) constarán de una letra seguida opcionalmente de cualquier grupo de letras, dígitos y
símbolos de subrayado „_‟.
Existen dos tipos de constantes numéricas; los números enteros (TKN_NUMENT) formada por 1 o más dígitos
y los números reales (TKN_NUMREAL) formado por 1 ó más dígitos seguidos de un punto y 1 o más dígitos.
Los símbolos especiales son: ( ) “ , + - * / = ;
Todas las palabras reservadas son con MAYUSCULAS. Estas palabras reservadas son: SUB FUNCTION
END REM AS DIM SINGLE INTEGER STRING INPUT PRINT LEN CALL
Especificación a nivel sintáctico
VisualBASIC es un lenguaje de alto nivel que nos va a permitir definir funciones (devuelven un valor y se
especificará con la palabra FUNCTION) o procedimientos (no devuelven valor y se especificará con SUB) al
igual que permite definir distintos tipos de variables, que serán de ámbito local o global. La definición de una
función termina con las palabras reservadas END FUNCTION, de un procedimiento con END SUB y el
programa con la palabra END únicamente. La llamada a procedimientos se hace mediante la palabra reservada
CALL. En las funciones VisualBasic utiliza el propio nombre de la función para devolver el valor de retorno de
la misma.
Ejemplo: Si la función se declara como
FUNCTION Mifuncion () AS INTEGER
Mifuncion = 4;
REM Esto equivalente en C sería return(4)
END FUNCTION
En nuestra versión simplificada del lenguaje vamos a trabajar con los tipos de datos básicos: enteros (las
variables se definen mediante INTEGER), los tipos reales (las variables se definen mediante SINGLE) y tipos
cadenas de caracteres que podrán ser de longitud variable (únicamente la palabra reservada STRING), o de
longitud fija (se añade a continuación de la palabra reservada STRING un asterisco y el numero de elementos
de la cadena). A su vez, podemos definir arrays de estos tipos de datos básicos (los vectores en VisualBasic
introducen una complejidad adicional pues utilizan paréntesis al igual que las funciones). Las palabras
reservadas DIM y AS se usan en la definición de variables de estos tipos de datos.
REM Ejemplo de declaracion de una cadena de longitud variable
DIM cad1 AS STRING
REM Ejemplo de cadena de longitud 10
1
DIM cad2 AS STRING*10
REM Ejemplo de definicion de vectores
REM Deficion de un array de dimensiones 2x3
DIM v(2,3) AS INTEGER
Se han incluido la función de tratamiento de cadenas LEN. LEN devuelve la longitud de la variable.
Ejem:
DIM cad1, cad2 AS STRING
DIM longitud AS INTEGER
cad1 = “El coche es rojo”
longitud = LEN(cad1)
REM en longitud se almacenara el valor 16
Para la petición de información se utiliza la función INPUT, dicha función devuelve un valor que es el dato
introducido por el usuario y tiene un argumento que será el mensaje que se le mostrará al usuario cuando se
realice la petición del dato. Para la impresión de información por pantalla se utiliza el comando PRINT, dicho
comando mostrará por pantalla todos los literales o contenido de variables que haya a continuación del
comando separados por comas (véase el ejemplo 1).
Habrá que tener en cuenta que, tanto las variables como las funciones deben ser insertadas en la Tabla de
Símbolos (TS), quedando reflejado de qué tipo son para las futuras comprobaciones semánticas. Por otra parte,
habrá que diferenciar entre variables globales y locales, pudiendo tener variables con el mismo nombre siempre
y cuando el ámbito de aplicación sea diferente.
Cualquier programa en este lenguaje de alto nivel tendrá la estructura especificada en la siguiente gramática:
Importante: Habrá que tener en cuenta la precedencia entre operadores y el menos unario en las expresiones
que trabajan con dichos operadores. Por otra parte, deberemos indicar la fila y columna de los posibles errores,
tanto léxicos como sintácticos. Por último, se deberá poder visualizar la tabla de símbolos una vez esta haya
sido completamente generada.
Nota: Se podrán incluir modificaciones a la gramática siempre que se genere el mismo lenguaje.
2
Programa
Subrutinas Bloque
Subrutinas
Funcion Subrutinas | Procedimiento Subrutinas |
Procedimiento
TKN_SUB TKN_ID TKN_( Argumentos Bloque TKN_SUB
Funcion
TKN_FUNCTION TKN_ID TKN_( Argumentos TKN_) TKN_AS Tipo Bloque TKN_FUNCTION
Argumentos
TKN_ID DeclaraVector TKN_AS Tipo MasArgumentos |
DeclaraVector
TKN_( TKN_) |
MasArgumentos
TKN_, TKN_ID DeclaraVector TKN_AS Tipo MasArgumentos |
Tipo
TKN_INTEGER | TKN_SINGLE | TKN_STRING Tamano
Tamano
TKN_* TKN_NUMENT |
Bloque
Bdeclaraciones BSentencias
Bdeclaraciones
Declara BDeclaraciones |
Declara
TKN_DIM TKN_ID DefVector MasVariables TKN_AS Tipo
DefVector
TKN_( TKN_NUMENT MasDim TKN_) |
MasDim
TKN_, TKN_NUMENT MasDim |
MasVariables
TKN_, TKN_ID DefVector MasVariables |
Bsentencias
Instruccion TKN_; MasInstruccion
Instruccion
TKN_ID Opcion | TKN_PRINT Impresion | TKN_LEN TKN_( TKN_ID TKN_) |
TKN_CALL TKN_ID TKN_( Args TKN_)
MasInstruccion
Instruccion TKN_; MasInstruccion | TKN_END
Impresión
TKN_ID DefVector MasImp | TKN_” Cadena TKN_” MasImp | Expresión MasImp
Cadena
TKN_ID Cadena |
MasImp
TKN_, Impresión MasImp |
Args
Contenido MasArgs |
Contenido
TKN_ID DeclaraVector | TKN_NUMENT | TKN_NUMREAL | TKN_” Cadena TKN_”
MasArgs
TKN_, Contenido MasArgs |
Opcion
DefVector TKN_= Informacion
Información
Expresion | TKN_” Cadena TKN_”
Frase
TKN_ID | TKN_” Cadena TKN_”
Expresión
| TKN_INPUT TKN_( Frase TKN_)
Expresion TKN_+ Expresion | Expresion TKN_- Expresion | Expresion TKN_* Expresion |
Expresion TKN_/ Expresion | TKN_- Expresion |
TKN_ID DefGen | TKN_NUMENT | TKN_NUMREAL
DefGen
TKN_( Args TKN_) |
3
Ejemplos del lenguaje definido por la gramática:
Ejemplo 1:
DIM i AS INTEGER
DIM nombre AS STRING*20
i = INPUT(“introduce tu edad”);
nombre = INPUT(“Introduce tu nombre”);
PRINT “Hola”, nombre, “tienes”, i, “anyos”;
END
Ejemplo 2:
FUNCTION Suma(d() AS INTEGER, i AS INTEGER) AS INTEGER
DIM total AS INTEGER
total = d(1) + d(i);
Suma = total;
END FUNCTION
SUB Comienzo(cad AS STRING)
PRINT cad;
END SUB
DIM v(2) , result AS INTEGER
DIM total AS INTEGER
CALL Comienzo(“Este programa suma dos numeros”);
v(1) = INPUT(“Introduce un numero”);
v(2) = INPUT(“Otro”);
result= Suma(v(),2);
PRINT “La suma es ”, result;
END
Generación de la tabla de símbolos
En este apartado se trata de generar la tabla de símbolos. Esta estructura, junto con el árbol sintáctico, se usará
también en la siguiente práctica para generar código intermedio.
A la hora de generar la tabla de símbolos se debe tener en cuenta que es necesario almacenar tanto las variables
como las funciones, para ello tendremos que diferenciarlas mediante un campo que nos indique de que tipo de
símbolo se trata. Para el caso de las variables, deberemos contemplar la posibilidad de que estén definidas en el
cuerpo del programa (que serán globales) o dentro de alguna función (que serán locales). Necesitaremos un
campo que nos almacene el ámbito al que pertenece la variable. La primera función definida tiene ámbito uno,
la segunda tiene ámbito dos, así sucesivamente. También habrá que tener en cuenta el número, tipo y nombre de
los argumentos que se le pasa a las funciones.
4
Comprobaciones semánticas
Se deberán realizar las siguientes comprobaciones semánticas básicas con la tabla de símbolos:
 No insertar un identificador de una variable o función dos veces con el mismo nombre y con
el mismo ámbito.
 Dado que los vectores utilizan paréntesis, no podrá haber funciones y variables con el mismo
nombre independientemente del ámbito en el que esté declarado el vector.
 En las llamadas a funciones, deberemos comprobar que esa función ha sido definida y que el
número de argumentos que se le pasa es el correcto y, además, que los argumentos son del
mismo tipo.
 Cuando se usen las variables deberemos comprobar que dichas variable hayan sido
previamente declaradas y que tienen el ámbito adecuado. Igualmente, no se puede llamar a
una subrutina o función si está no existe.
 Se comprobará que en la parte izquierda de una asignación no hay llamadas a funciones.
Exceptuando el nombre de la propia función sin argumentos, ya que este es el método que
utiliza VisualBasic para devolver valores en las funciones.
Ejemplo
FUNCTION Mifuncion (a AS INTEGER) AS INTEGER
REM Permitido, devolución de un valor entero por la función
Mifuncion = a*2;
END FUNCTION
Dim v(3) AS INTEGER
REM La siguiente instrucción es la asignación de un valor a un elemento de REM un vector
v(1) = Mifuncion(4);
REM La siguiente instruccion esta prohibida pues no tiene sentido asignarle un
REM valor a una funcion
Mifuncion(3) = 8;
END
Nota: Opcionalmente se podrán incluir otro tipo de comprobaciones.
Gestión de errores
Siempre que se produzca un error, tanto léxico como sintáctico como semántico, habrá que indicar el tipo de
error de que se trata así como la fila y la columna donde se ha producido dicho error.
Fecha de entrega:
Todos los grupos deberán entregar la práctica con fecha máxima el 25 de Marzo
DURACIÓN: 2 sesiones
5
Descargar