PROCESADORES DE LENGUAJES. Práctica 1: Análisis Léxico

Anuncio
13048- PROCESADORES DE LENGUAJE
Curso: 2003-2004
Práctica 1: Diseño de un Analizador Léxico y Sintáctico
Se desea implementar un analizador léxico y sintáctico de un pequeño subconjunto del
lenguaje de consulta de Bases de Datos SQL. Como sabéis una sentencia de este
lenguaje viene definida por tres clausulas o partes: la clausula SELECT, la clausula
FROM y la clausula WHERE.
Un ejemplo de una consulta que permite mostrar los nombres y apellidos de los
estudiantes de edad superior a 20, es:
select estudiantes.nombre, estudiantes.apellidos
from estudiantes
where (estudiantes.edad>20);
Otro tipo de sentencias un tanto mas complejas son las que usan la función group by.
Por ejemplo si queremos mostrar la edad media de los alumnos por titulación a la que
pertenecen y que estén en segundo curso. Hemos supuesto que toda esta información
está en una única tabla (Tabla estudiantes).
select avg(estudiantes.edad)
from estudiantes
where (estudiantes.curso=2)
group by estudiantes.titulacion;
Otro caso a considerar es el caso en el que la información se encuentre en varias tablas.
Por ejemplo, supongamos que queremos mostrar los nombres de las asignaturas del
alumno con DNI 25400000.
select asignaturas.nombre
from estudiantes, asignaturas
where (estudiantes.DNI=2540000) and
(estudiantes.modulo=asignaturas.modulo)
Análisis Léxico (1ª sesión)
Se trata de implementar un analizador léxico, en el que exista una función que
devuelva el siguiente token dentro del programa fuente, es decir, que devuelva el tipo
de token en forma de constante entera, y su lexema, en forma de cadena. En esta
primera fase de la práctica, y con la finalidad de comprobar que funciona correctamente,
esta función será llamada por la función main, que solicitará nuevos tokens hasta que se
agote el texto del fichero de que contiene las consultas en SQL. El programa deberá
imprimir una lista de tokens de la forma (tipo_de_token, lexema) como resultado,
deteniéndose en el caso de un error léxico e indicando la línea y columna del texto
fuente donde éste se produjo. Los componentes léxicos a reconocer son los siguientes:
TKN_NUM = digito+ (. digito+)?
TKN_ID = letra (letra | digito)*
siendo digito = 0 | 1 | ... | 9
Símbolos especiales
TKN_APAR (
TKN_CPAR )
letra = a | b | ... | z | A | B | ... | Z
TKN_PTOCOMA ;
TKN_PTO .
Palabras reservadas:
SELECT
TKN_SELECT
FROM
TKN_FROM
WHERE
TKN_WHERE
GROUP
TKN_GROUP
BY
TKN_BY
Funciones sobre campos agregados:
AVG
SUM
MAX
MIN
TKN_AVG //calcula el promedio
TKN_SUM //calcula la suma
TKN_MAX //calcula el máximo
TKN_MIN //calcula el mínimo
Operadores:
TKN_MENOR
TKN_MAYOR
TKN_MENORIG
TKN_MAYORIG
TKN_IG
TKN_DISTINTO
TKN_Y
TKN_O
<
>
<=
>=
=
!=
and
or
NOTA: La distinción entre identificadores y palabras reservadas debe hacerse mediante
el método de añadir las palabras reservadas a una lista de tokens predefinidos y
comprobar cada candidato si es un identificador o palabra reservada.
Análisis Sintáctico (2ª y 3ª sesión)
Partiendo del analizador léxico ya programado, se trata de implementar un analizador
sintáctico direccional determinista descendente basado en el uso de una gramática
LL(1). El programa deberá imprimir como resultado la lista de producciones que
generan la derivación más a la izquierda. En el caso de que haya errores sintácticos, el
programa debe proporcionar la información sobre la línea y columna del texto original
donde se produjo el error, e intentar efectuar una recuperación del error en modo de
pánico.
Diseño de una gramática LL(1)
Construir una Gramática LL(1) que genere el lenguaje a reconocer: un subconjunto del
lenguaje SQL.
- Una sentencia SQL se compone de al menos de la clausula SELECT y FROM.
La clausula WHERE y GROUP BY son opcionales. Si aparecen todas el orden
es: SELECT, FROM, WHERE y GROUP BY.
- En la clausula SELECT pueden aparecer varios identificadores separados por
comas, o funciones de agregados.
- Los identificadores pueden venir indicados mediante el atributo o bien mediante
nombre_de_la_tabla.atributo.
- En la clausula FROM pueden aparecer varios nombres de tablas separados por
comas.
-
-
En la clausula WHERE pueden aparecer combinaciones de expresiones
relacionales y operadores lógicos. Recordad que los operadores lógicos tienen
mayor prioridad que los relacionales y que puede existir anidamiento en las
expresiones.
Supondremos que el programador puede escribir más de una sentencia SQL
consecutiva.
Una sentencia viene separada de otra por el carácter ;
Implementación del analizador sintáctico descendente
Implementar el analizador sintáctico predictivo recursivo correspondiente para la
gramática que habéis diseñado.
Implementación de un sencillo traductor dirigido por la sintaxis
Imaginemos que queremos enseñar SQL a una persona que no sabe inglés y que
queremos traducir todos los ejemplos de nuestro manual de referencia al castellano (o
valenciano). Es decir, donde aparece SELECT, debe aparecer la palabra
SELECCIONAR. Igual para el resto de palabras reservadas. Añade las acciones
semánticas a tu código para que durante el proceso de análisis sintáctico se realice la
traducción y vuelque a un fichero de salida las sentencias traducidas. También habría
que traducir los operadores AND por Y, OR por O.
El primer ejemplo traducido a castellano sería:
seleccionar estudiantes.nombre, estudiantes.apellidos
desde estudiantes
donde (estudiantes.edad>20);
Implementación de un mecanismo de recuperación de errores
Implementa un sencillo mecanismo de recuperaciones de errores sintácticos por el
método de recuperación en modo de pánico.
Duración: 3 sesiones
Fecha de entrega máxima: para todos los grupos, Día 7 de Enero de 2004
Entregar: ficheros con la implementación y la gramática al profesor correspondiente.
Descargar