Kategorien: Alle - sintáctico - integración - tabla

von BRAVO CAMPOVERDE BRAVO CAMPOVERDE Vor 4 Jahren

326

IMPLEMENTACIÓN DE ANALIZADORES LÉXICO / SINTÁCTICO.

El documento se centra en la implementación de analizadores léxicos y sintácticos utilizando JFlex, una herramienta que permite generar analizadores léxicos rápidamente y con soporte completo para caracteres Unicode.

IMPLEMENTACIÓN DE ANALIZADORES LÉXICO / SINTÁCTICO.

GRUPO #2

* BENAVIDES PAGUAY MAYRA. * BRAVO CAMPOVERDE CRISTHIAN. * RIVERA JORDAN JUSTIN.

IMPLEMENTACIÓN DE ANALIZADORES LÉXICO / SINTÁCTICO.

Implementación de analizador léxico sintáctico

Haciendo usos de la estructura de análisis de un diagrama de Conway verificamos que todos los caminos desde el inicio de nuestro código, hasta el final; representan formas senténciales válidas. main ( ) { get_token ( ); do { expresión ( ); while (token != PUNTOYCOMA) {!Error en expresión¡ get_token ( ); }; get_token( ); }while (token != EOF); };
En este caso se considera al ‘;’ como un token de seguridad, lo que permite hacer una recuperación de errores mediante el método panic mode. El programa flex por medio de su proceso de compilación reconoce los errores sintácticos dentro de la estructura de análisis. Estos errores corresponden a que el analizador sintáctico pide al lexicográfico tokens a través de get_token ( );, y que el lexicográfico deja el token actual en la variable global token. Es decir que antes de entrar a una función, en token debemos tener el token de lookahead, que esa función necesita consultar.
Analizador Sintáctico(Parser) Sintaxis: El orden correcto de las palabras Ej. Programa Fuente: 34:= *x - 640; Analex: NUM ASIGN POR ID MENOS NUM PTOCOMA Parser: "Error Sintáctico"

Integración de JFlex (analizadores léxico y sintáctico)

CARACTERÍSTICAS DE JFLEX
* Soporte completo con caracteres Unicode * Permite generar analizadores léxicos rápidamente. * Tiene una sintaxis cómoda de manipular y fácil de interpretar. * Es independiente de la plataforma debido a que está diseñado. * para ser integrado con Java. * Permite la integración con CUP (Analizador sintáctico).
ESTRUCTURA UN ARCHIVO DE JFLEX
Un archivo JFex está dividido en 3 secciones: * Opciones y declaraciones. * Código de usuario. * Reglas lexicográfica.
OPCIONES Y DECLARACIONES
El bloque de configuración se define por el conjunto de parámetros que Unicode, es una gran tabla, que en la actualidad asigna un código a cada uno de los más de cincuenta mil símbolos, los cuales abarcan todos los alfabetos europeos, ideogramas chinos, japoneses, coreanos, muchas otras formas de escritura, y más de un millar de símbolos especiales.
Luego sigue un par de signos de porcentaje (%) para indicar que empezará la definición del bloque de configuración del analizador.
La primera parte del archivo es el bloque donde se importaran los paquete que se van a utilizar para nuestro analizador, es decir, si en nuestro programa utilizaremos componentes del paquete útil debemos importar aquí dicho paquete: Import java.util.*;

EJEMPLOS DE LA TABLA DE SIMBOLOS.

* Crear: Crea una tabla vacía. * Insertar: Parte de una tabla de símbolo y de un nodo, lo que hace es añadir ese nodo a la cabeza de la tabla. * Buscar: Busca el nodo que contiene el nombre que le paso por parámetro. * Imprimir: Devuelve una lista con los valores que tiene los identificadores de usuario, es decir recorre la tabla de símbolos. Este procedimiento no es necesario pero se añade por claridad, y a efectos de resumen y depuración
El programa lex : * Si se encuentra un número lo convierte a int y devuelve el token NUMERO. Si se encuentra un identificador de usuario: * Primero lo busca en la tabla de símbolos, Si lo encuentra, entonces devuelve su valor Si no lo encuentra, lo inserta

El programa Yacc: %union { int numero; símbolo * For símbolo; } Esto es un registro con parte variante, en el que todo es parte variante. Si ponemos % unión ya no hay que poner YYSTYPE. Cosas interesantes de la gramática: prog : prog asig ... | (J forma parte de un prog). ; asig : ID ASIG expr | ID ASIG asig Como podemos observar esta regla es recursiva a la derecha. Se permiten cosas como a := b := c := 3 * 4 En cuanto a la regla expr produce ambigüedad, ésta se soluciona introduciendo las instrucciones % left ‘+’ % left ‘*’ El atributo del identificador de usuario ‘ID’, es un puntero a un símbolo.

TABLA DE SÍMBOLOS

Una tabla de símbolos es una estructura de datos usada en el proceso de traducción de un lenguaje de programación (por un compilador o un intérprete), dónde cada símbolo en el código fuente de un programa está asociado con información tal como la ubicación, el tipo de datos y el ámbito de cada variable, constante o procedimiento.
La estructura inicial de la tabla de símbolos suele constar de dos partes:

PARTE VARIABLE

Definida por el programador: con el significado de los identificadores utilizados en cada frase (programa).

PARTE FIJA

Formada por las palabras clave del lenguaje (suelen ser de uso reservado y del orden de unas decenas de palabras en un lenguaje programación típico)

Operaciones con la Tabla de símbolos.

En general en la Tabla de símbolos (TS a partir de ahora) se realizan dos operaciones: la inserción y la búsqueda. En C la operación de inserción se realiza cuando se procesa una declaración. Hay dos posibilidades: que la TS esté ordenada (o sea, nombres de variables por orden alfabético) o que no esté ordenada.

Interfaz de la tabla de símbolos

Como ya se ha comentado, la interfaz de la tabla de símbolos debe quedar clara desde el principio de manera que cualquier modificación en la implementación de la tabla de símbolos no tenga repercusión en las fases del compilador ya desarrolladas. Las operaciones básicas que debe poseer son:

Crear(): crea una tabla vacía. Insertar(símbolo): añade a la tabla el símbolo dado. Buscar(nombre): devuelve el símbolo cuyo nombre coincide con el parámetro. Si el símbolo no existe devuelve null. Imprimir(): a efectos informativos, visualiza por la salida estándar la lista de variables almacenadas en la tabla de símbolos junto con sus valores asociados.

Estructura

Cada entrada de la tabla de símbolos corresponde a al declaración de un nombre. El formato de las entradas no tiene que ser uniforme porque la información de un nombre depende del uso de dicho nombre. Cada entrada en principio puede considerarse: (Nombre, descriptor) LEXEMA ATRIBUTOS

IDENTIFICADORES DE USUARIO

La información que el desarrollador decida almacenar en esta tabla dependerá de las características concretas del traductor que esté desarrollando. Entre esta información puede incluirse:
• Valor del elemento

Cuando se trabaja con intérpretes sencillos, y dado que en un intérprete se solapan los tiempos de compilación y ejecución, puede resultar más fácil gestionar las variables si almacenamos sus valores en la tabla de símbolos.

• Dirección de memoria en que se almacenará su valor en tiempo de ejecución

Esta dirección es necesaria, porque las instrucciones que referencian a una variable deben saber donde encontrar el valor de esa variable en tiempo de ejecución con objeto de poder generar código máquina, tanto si se trata de variables globales como de locales.

Tipos de los parámetros formales

Si el identificador a almacenar pertenece a una función o procedimiento, es necesario almacenar los tipos de los parámetros formales para controlar que toda invocación a esta función sea hecha con parámetros reales coherentes.

• Tipo del elemento

Cuando se almacenan variables, resulta fundamental conocer el tipo de datos a que pertenece cada una de ellas, tanto si es primitivo como si no, con objeto de poder controlar que el uso que se hace de tales variables es coherente con el tipo con que fueron declaradas.

• Nombre del elemento.

El nombre o identificador puede almacenarse limitando o no la longitud del mismo.

• Número de dimensiones.

Si la variable a almacenar es un array, también pueden almacenarse sus dimensiones.