Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Reportelya

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 9

INSTITUTO TECNOLOGICO DE ACAPULCO

Ingeniería en Sistemas Computacionales

Lenguajes y Autómatas I

Equipo:
Jafet Iván Lozano Lara 20321091
Alejandro Martinez Martinez 20321104

Fecha: 03 de junio del 2024


Introducción
Los analizadores sintácticos, también conocidos como parsers, son componentes
cruciales en el ámbito de la compilación y el procesamiento de lenguajes formales.
Su función principal es procesar una secuencia de símbolos conforme a las reglas
de una gramática formal, verificando la correcta estructuración y conformidad del
código fuente o de una cadena de entrada.

Un analizador sintáctico es una parte integral del compilador, ubicado entre el


análisis léxico y el análisis semántico. Su tarea es recibir tokens generados por el
analizador léxico y organizarlos en una estructura jerárquica que representa la
sintaxis del lenguaje de programación. Esta estructura jerárquica se conoce
comúnmente como árbol de análisis o árbol sintáctico.

El proceso de análisis sintáctico generalmente sigue estos pasos:

1. Entrada de Tokens: El analizador recibe una secuencia de tokens del


analizador léxico.
2. Aplicación de Reglas: Utiliza una gramática formal (conjunto de reglas de
producción) para combinar tokens en estructuras mayores.
3. Construcción del Árbol: Organiza los tokens y sus combinaciones en un
árbol sintáctico.
4. Detección de Errores: Identifica errores sintácticos si la secuencia de
tokens no cumple con las reglas de la gramática.

El análisis sintáctico es esencial para:

 Verificación de la Correctitud: Asegura que el código fuente cumple con


las reglas del lenguaje.
 Facilitación del Análisis Semántico: Proporciona una estructura
organizada para el análisis semántico posterior.
 Transformaciones del Código: Permite optimizaciones y transformaciones
del código fuente antes de la generación de código máquina.
Desarrollo

Este analizador léxico está diseñado para reconocer varios elementos de un


lenguaje de programación similar a Java, como tipos de datos, palabras
reservadas, operadores, delimitadores, identificadores y números. Los tokens
reconocidos se devuelven a un analizador sintáctico para su posterior
procesamiento.
A continuación, explico la función de cada parte del código:
Estas reglas especifican cómo debe comportarse el lexer cuando encuentra
ciertas secuencias de caracteres:
 Espacios en blanco y comentarios se ignoran.
 Salto de línea: Devuelve el token Linea.
 Comillas: Devuelve el token Comillas.
 Tipos de datos (byte, int, char, long, float, double) y String: Devuelven el
token T_dato y Cadena, respectivamente.
 Palabras reservadas: if, else, do, while, for devuelven los tokens
correspondientes (If, Else, Do, While, For).
 Operadores: igualdad, suma, resta, multiplicación, división, lógicos,
relacionales, de atribución, de incremento/decremento, booleanos.
 Delimitadores: paréntesis, llaves, corchetes.
 Identificadores: Palabras que empiezan con una letra o guion bajo y
pueden contener letras y dígitos.
 Números: Dígitos, con soporte para números negativos.
 Cualquier otro carácter se considera un error (ERROR).
El parser definido en este código valida la estructura sintáctica de programas
escritos en un lenguaje similar a Java. Está diseñado para reconocer
declaraciones de variables y la estructura básica de un programa con una función
principal (main). El analizador utiliza símbolos terminales y no terminales para
definir las reglas gramaticales que debe cumplir el código fuente.

Este bloque define el comportamiento del parser en caso de errores sintácticos:


 private Symbol s;: Variable para almacenar el símbolo donde ocurre un
error.
 syntax_error(Symbol s): Método que se llama cuando ocurre un error
sintáctico y almacena el símbolo erróneo.
 getS(): Método para obtener el símbolo erróneo almacenado.

Se definen los terminales, que corresponden a los tokens generados por el analizador
léxico.
Se definen los no terminales, que representan estructuras sintácticas complejas en
el lenguaje.

La regla para INICIO define dos posibles estructuras:


 Un programa que empieza con int main() { SENTENCIA }.
 Un programa que empieza con main() { SENTENCIA }

La regla para SENTENCIA define una lista de declaraciones:


 Una SENTENCIA puede ser una secuencia de DECLARACION.
 Una SENTENCIA puede ser una sola DECLARACION.

La regla para DECLARACION define varias formas de declarar variables:


 Declaración de un entero: int x;.
 Declaración e inicialización de un entero: int x = 10;.
 Declaración de una variable de cualquier tipo de dato: T_dato x;.
 Declaración e inicialización de una variable de cualquier tipo de dato:
T_dato x = 10;.
 Declaración e inicialización de una cadena vacía: String x = "";.
 Declaración e inicialización de una cadena con un identificador: String x =
"y";.
Funcionamiento general:

1. Entrada de Tokens: El parser recibe tokens generados por el analizador léxico.


Estos tokens representan elementos léxicos del programa fuente, como
identificadores, operadores, y delimitadores.
2. Análisis Sintáctico: El parser utiliza las reglas de producción definidas para validar
la estructura de los tokens. Si los tokens siguen una secuencia que coincide con
alguna de las reglas, el parser los acepta como sintácticamente correctos.
3. Errores Sintácticos: Si los tokens no coinciden con ninguna regla de producción,
se llama al método syntax_error para manejar el error y almacenar el símbolo
problemático.
Conclusión

A través de la implementación del analizador léxico y sintáctico, hemos desarrollado una


solución integral para la validación y procesamiento de un lenguaje de programación
similar a Java. Esta tarea ha involucrado la creación de dos componentes esenciales:

1. Analizador Léxico: Usando JFlex, diseñamos un lexer capaz de reconocer y


categorizar diversos elementos léxicos del lenguaje, como tipos de datos,
operadores, delimitadores, identificadores y números. Este lexer no solo transforma
la secuencia de caracteres del código fuente en una serie de tokens, sino que
también ignora elementos irrelevantes como espacios en blanco y comentarios, y
gestiona errores léxicos de manera eficiente.
2. Analizador Sintáctico: Mediante Java CUP, construimos un parser que verifica la
estructura gramatical de la secuencia de tokens generada por el lexer. Este parser
está diseñado para validar la correcta declaración e inicialización de variables, así
como la estructura básica de un programa que contiene una función principal
(main). Además, incluye mecanismos para manejar y reportar errores sintácticos,
asegurando así que el código fuente cumple con las reglas gramaticales definidas.

Estos componentes, cuando trabajan juntos, forman la base de un compilador simple,


permitiendo la traducción de código fuente en una representación estructurada y manejable.
Este proyecto ha sido una valiosa experiencia en la comprensión y aplicación de conceptos
fundamentales de compilación, desde el análisis léxico hasta el análisis sintáctico. El
resultado es una herramienta robusta que puede servir como base para futuros desarrollos
en el ámbito de los compiladores y lenguajes de programación.

También podría gustarte