Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad

Análisis Léxico y Sintáctico de Expresiones Aritméticas usando Java y JFlex, Ejercicios de Teoría de Lenguajes Formales para Autómatas

Cómo crear un analizador lexico y sintactico para expresiones aritmeticas usando java y jflex. El documento incluye el código fuente de los archivos cup, jflex y java, asi como instrucciones para compilarlos. El analizador lexico reconocera tokens como numeros enteros y operadores aritmeticos, mientras que el analizador sintactico construira el árbol de parseo para la expresión ingresada.

Tipo: Ejercicios

2022/2023

A la venta desde 18/02/2024

leonardo-de-jesus-azamar-tegoma-1
leonardo-de-jesus-azamar-tegoma-1 🇲🇽

1 documento

1 / 21

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
INSTITUTO TECNOLÓGICO SUPERIOR DE
SAN ANDRÉS TUXTLA
MÓDULO:
Lenguaje y Autómatas II
CLAVE DE ASIGNATURA:
SCC1023-B
DOCENTE:
MTI Eneida Yasmin Honorato Rodríguez
ALUMNO:
Leonardo de Jesús Azamar Tegoma
CARRERA:
ING En Sistemas Computacionales
GRUPO:
604-A SEXTO SEMESTRE
NOMBRE DEL TRABAJO: Reporte de Practicas U1
FECHA DE ENTREGA: 7 de Marzo del 2023
PERIODO ESCOLAR:
FEBRERO JULIO 2023
SAN ANDRÉS TUXTLA, VER
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15

Vista previa parcial del texto

¡Descarga Análisis Léxico y Sintáctico de Expresiones Aritméticas usando Java y JFlex y más Ejercicios en PDF de Teoría de Lenguajes Formales para Autómatas solo en Docsity!

INSTITUTO TECNOLÓGICO SUPERIOR DE

SAN ANDRÉS TUXTLA

MÓDULO: Lenguaje y Autómatas II

CLAVE DE ASIGNATURA: SCC1023-B

DOCENTE: MTI Eneida Yasmin Honorato Rodríguez

ALUMNO: Leonardo de Jesús Azamar Tegoma

CARRERA: ING En Sistemas Computacionales

GRUPO: 604 - A SEXTO SEMESTRE

NOMBRE DEL TRABAJO: Reporte de Practicas U

FECHA DE ENTREGA: 7 de Marzo del 2023

PERIODO ESCOLAR: FEBRERO – JULIO 2023

SAN ANDRÉS TUXTLA, VER

PRÁCTICA NO. 1

NOMBRE DE LA PRÁCTICA

Análisis Semántico (Atribución de la gramática)

OBJETIVO:

El alumno aprenderá a asignar atributos a la gramática y utilizará atributos sintetizados

FUNDAMENTO TEÓRICO

Análisis semántico Además de controlar que un programa cumple con las reglas de la gramática del lenguaje, hay que comprobar que lo que se quiere hacer tiene sentido. El análisis semántico dota de un significado coherente a lo que hemos hecho en el análisis sintáctico. El chequeo semántico se encarga de que los tipos que intervienen en las expresiones sean compatibles o que los parámetros reales de una función sean coherentes con los parámetros formales: p.ej. no suele tener mucho sentido el multiplicar una cadena de caracteres por un entero. Comenzaremos viendo un ejemplo sencillo en el que se introduce el concepto de atributo mediante la construcción del intérprete de una calculadora. Traducción dirigida por sintaxis A partir de este epígrafe se desarrolla la traducción de lenguajes guiada por gramáticas de contexto libre. Se asocia información a cada construcción del lenguaje de programación proporcionando atributos a los símbolos de la gramática que representan dicha construcción. Los valores de los atributos se calculan mediante reglas (acciones) semánticas asociadas a las reglas de producción gramatical. Como hemos visto, hay dos notaciones para asociar reglas semánticas con reglas de producción: Las definiciones dirigidas por sintaxis son especificaciones de alto nivel para traducciones. No es necesario que el usuario especifique explícitamente el orden en el que tiene lugar la ejecución de las acciones. Los esquemas de traducción indican el orden en que se deben evaluar las reglas semánticas. Conceptualmente, tanto con las definiciones dirigidas por sintaxis como con los esquemas de traducción, se analiza sintácticamente la cadena de componentes léxicos de entrada, se construye el árbol de análisis sintáctico y después se recorre el árbol para evaluar las reglas semánticas en sus nodos. La evaluación de las reglas semánticas puede generar código, guardar información en una tabla de símbolos, emitir mensajes de error o realizar otras actividades, como p.ej. evaluar expresiones aritméticas en una calculadora. La traducción de la cadena de componentes léxicos es el resultado obtenido al evaluar las reglas semánticas. En la práctica, no todas las implementaciones tienen que seguir al pie de la letra este esquema tan nítido de una fase detrás de otra. Hay casos especiales de definiciones dirigidas por la sintaxis que se pueden implementar en una sola pasada evaluando las reglas semánticas durante el análisis sintáctico, sin construir explícitamente un árbol de análisis sintáctico o un grafo que muestre las dependencias entre los atributos.

MATERIAL Y EQUIPO

❖ Marca: HP

❖ Procesador: Intel ® Core ™ ¡3-6006U CPU @ 2.00Ghz

❖ Tipo de Sistema Operativo: Sistema Operativo Windows 10 Home Single Language de 64 bits, procesador

x64.

❖ Memoria RAM: 8GB

❖ Capacidad: 1TB

❖ Java Development Kit 8 Update (JDK 12.0.1)

❖ JFLEX

 Versión 1.8.

❖ JAVA CUP

 Versión 11

METODOLOGÍA Y DESARROLLO

EJEMPLO Programa: Operaciones Aritméticas JFLEX

import java_cup.runtime.*;

%class Lexer

%unicode

%cup

%line

%column

NUM= ("+"|"-")?[0-9]+

suma = "+"

mult = "*"

parentesis_ini = "("

parentesis_fin = ")"

Salto = \r|\n|\r\n

Blanco = [ \t\f]

{suma} {return new Symbol(sym.suma, yyline, yycolumn, yytext());}

{mult} {return new Symbol(sym.mult, yyline, yycolumn, yytext());}

{parentesis_ini} {return new Symbol(sym.parentesis_ini, yyline, yycolumn, yytext());}

{parentesis_fin} {return new Symbol(sym.parentesis_fin, yyline, yycolumn, yytext());}

{NUM} {return new Symbol(sym.NUM, new Integer (yytext()));}

{Salto} {;}

{Blanco}+ {;}

. {System.out.println("ERROR LEXICO: Caracter ""+yytext()+"" no permitido."); }. {;}

CUP

import java_cup.runtime.Symbol;

import java.io.*;

parser code {:

public static void main(String[] args){

try

{FileReader f= new FileReader(args[0]); // se genera el archivo de entrada a leer

parser parserObj = new parser(); /* creo el objeto que debe ser de la clase que genere en cup

(parser.class) */

Lexer miAnalizadorLexico = new Lexer(f); /* crear el objeto para el analizador léxico que

debe coincidir con la clase que genere en Jflex en este caso Lexer*/

Se compilan en java los archivos generados: Javac sym.java Javac parser.java Por último, se compila el archivo de jflex Jflex archivo.flex Se genera el archivo de acuerdo al nombre que se puso en %class en este caso se puso Lexer por lo tanto se genera el archivo en java Lexer.java. Se compila en java Javac Lexer.java Ya tenemos nuestros analizadores Lexico: Lexer.class y Sintactico: parser.class Se genera el archivo de texto de entrada que es el archivo que se va a analizar el cual debe contener lista de números separados por espacios en blanco. Por ejemplo: 5+4* Se ejecuta el analizador sintáctico de la siguiente manera:

  1. Java parser Entrada.txt //entrada es el nombre de i archivo de texto Se debe mostrar el resultado de la suma de todos los números introducidos en el archivo de texto. Ejemplo: 19

EJEMPLO Programa: Lista de números enteros. JFLEX

import java_cup.runtime.*;

%class Lexer

%unicode

%cup

%line

%column

NUM= ("+"|"-"|"*"|"/")?[0-9]+

Salto = \r|\n|\r\n

Blanco = [ \t\f]

{NUM} {return new Symbol(sym.NUM, new Integer (yytext()));}

{Salto} {;}

{Blanco}+ {;}

. {System.out.println("ERROR LEXICO: Caracter ""+yytext()+"" no permitido."); }

CUP

import java_cup.runtime.Symbol;

import java.io.*;

parser code {:

public static void main(String[] args){

try

{FileReader f= new FileReader(args[0]); // se genera el archivo de entrada a leer

parser parserObj = new parser(); /* creo el objeto que debe ser de la clase que genere en cup

(parser.class) */

Lexer miAnalizadorLexico = new Lexer(f); /* crear el objeto para el analizador léxico que debe

coincidir con la clase que genere en Jflex en este caso Lexer*/

parserObj.setScanner(miAnalizadorLexico); /*realiza la llamada del analizador léxico desde el

analizador sintáctico */

try{ //manejo de errores

parserObj.parse();

}catch(Exception x){

System.out.println("Error fatal.");

catch(Exception e){e.printStackTrace();}

Javac Lexer.java Ya tenemos nuestros analizadores Lexico: Lexer.class y Sintactico: parser.class Se genera el archivo de texto de entrada que es el archivo que se va a analizar el cual debe contener lista de números separados por espacios en blanco. Por ejemplo: Se ejecuta el analizador sintáctico de la siguiente manera:

  1. Java parser Entrada.txt //entrada es el nombre de i archivo de texto Se debe mostrar el resultado de la suma de todos los números introducidos en el archivo de texto. Ejemplo:

CUESTIONARIO

1. (Máximo)Atribuya la gramática del ejemplo para calcular el máximo de todos los números que aparecen en la entrada. JFLEX import java_cup.runtime.; %% %class Lexer %unicode %cup %line %column Salto = \r|\n|\r\n Blanco = [ \t\f] NUM= ("+"|"-")?[0-9]+ %% {Blanco}+ {;} {Salto}+ {;} {NUM} {return new Symbol(sym.NUM,new Integer (yytext()));} . {System.out.println("ERROR LÉXICO: Carácter ""+yytext()+"" no permitido."); } CUP import java_cup.runtime.Symbol; import java.io.; parser code {: public static void main(String[] args){ try {FileReader f= new FileReader(args[0]); // se genera el archivo de entrada a leer parser parserObj = new parser(); /* creo el objeto que debe ser de la clase que genere en cup (parser.class) / Lexer miAnalizadorLexico = new Lexer(f); / crear el objeto para el analizador léxico que debe coincidir con la clase que genere en Jflex en este caso Lexer/ parserObj.setScanner(miAnalizadorLexico); /realiza la llamada del analizador léxico desde el analizador sintáctico */ try{ //manejo de errores parserObj.parse(); }catch(Exception x){ System.out.println("Error fatal."); } } catch(Exception e){e.printStackTrace();} } :}; terminal Integer NUM; non terminal Integer ent; non terminal imprimir; imprimir::= ent:e {: System.out.println ("El numero mayor es: " + e ); :}; ent::= ent:e NUM:n {:RESULT = Math.max(e.intValue(), n.intValue()); :} |NUM:n {:RESULT= n;:};

Se genera el archivo de texto de entrada que es el archivo que se va a analizar el cual debe contener lista de números separados por espacios en blanco. Por ejemplo: 4 3 2 5 10 Se ejecuta el analizador sintáctico de la siguiente manera:

  1. Java parser Entrada.txt //entrada es el nombre de i archivo de texto Se debe mostrar el resultado de las operaciones de los números introducidos en el archivo de texto. Ejemplo: El número mayor es: 10 Otro caso de ejemplo: - 1 - 2 - 3 - 4. El número mayor es: - 1

2. (Desorden)Atribuya la gramática del ejemplo para que en el caso de encontrar dos números consecutivos x e y desordenados, los muestre en pantalla con el formato “(x,y)”. JFLEX import java_cup.runtime.; %% %class Lexer %unicode %cup %line %column NUM= ("+"|"-")?[0-9]+ Salto = \r|\n|\r\n Blanco = [ \t\f] %% {NUM} {return new Symbol(sym.NUM, Integer.parseInt(yytext()));} {Salto} {;} {Blanco}+ {;} . {System.out.println("ERROR LEXICO: Caracter ""+yytext()+"" no permitido."); } CUP import java_cup.runtime.Symbol; import java.io.; parser code {: public static void main(String[] args){ try {FileReader f= new FileReader(args[0]); // se genera el archivo de entrada a leer parser parserObj = new parser(); /* creo el objeto que debe ser de la clase que genere en cup (parser.class) / Lexer miAnalizadorLexico = new Lexer(f); / crear el objeto para el analizador léxico que debe coincidir con la clase que genere en Jflex en este caso Lexer/ parserObj.setScanner(miAnalizadorLexico); /realiza la llamada del analizador léxico desde el analizador sintáctico / try{ //manejo de errores parserObj.parse(); }catch(Exception x){ System.out.println("Error fatal."); } } catch(Exception e){e.printStackTrace();} } :}; / Declaración de símbolos terminales y no terminales */ terminal Integer NUM; non terminal imprimir; non terminal Integer ent;

Javac Lexer.java Ya tenemos nuestros analizadores Lexico: Lexer.class y Sintactico: parser.class Se genera el archivo de texto de entrada que es el archivo que se va a analizar el cual debe contener lista de números separados por espacios en blanco. Por ejemplo: 1 2 0 2 4 5 Se ejecuta el analizador sintáctico de la siguiente manera:

  1. Java parser Entrada.txt //entrada es el nombre de i archivo de texto Se debe mostrar el resultado de las operaciones de los números introducidos en el archivo de texto. Ejemplo: (1,2) (4,5) Pares de números consecutivos encontrados: 4

3. (abc)Escriba una gramática para reconocer 1 cadena de la forma aibjck^ imprimiendo: “Regular”(si i≠j≠k), “Independiente del contexto”(si i=j≠k o i=k≠j o j=k≠i) o “Dependiente del contexto”(si i=j=k). JFLEX import java_cup.runtime.; %% %class Lexer %unicode %cup %line %column LETRA= [a-zA-Z]+ Salto = \r|\n|\r\n Blanco = [ \t\f] %% {LETRA} {return new Symbol(sym.LETRA, yytext());} {Salto} {;} {Blanco}+ {;} . {System.out.println("ERROR LEXICO: Caracter ""+yytext()+"" no permitido."); } CUP import java_cup.runtime.Symbol; import java.io.; parser code {: public static void main(String[] args){ try {FileReader f= new FileReader(args[0]); // se genera el archivo de entrada a leer parser parserObj = new parser(); /* creo el objeto que debe ser de la clase que genere en cup (parser.class) / Lexer miAnalizadorLexico = new Lexer(f); / crear el objeto para el analizador léxico que debe coincidir con la clase que genere en Jflex en este caso Lexer/ parserObj.setScanner(miAnalizadorLexico); /realiza la llamada del analizador léxico desde el analizador sintáctico */ try{ //manejo de errores parserObj.parse(); }catch(Exception x){ System.out.println("Error fatal."); } } catch(Exception e){e.printStackTrace();} } :};

Por último, se compila el archivo de jflex Jflex archivo.flex Se genera el archivo de acuerdo al nombre que se puso en %class en este caso se puso Lexer por lo tanto se genera el archivo en java Lexer.java. Se compila en java Javac Lexer.java Ya tenemos nuestros analizadores Lexico: Lexer.class y Sintactico: parser.class Se genera el archivo de texto de entrada que es el archivo que se va a analizar el cual debe contener lista de números separados por espacios en blanco. Para esto se pondrán 3 tipos de entradas diferentes para que se cumplan las condiciones pertinentes junto con su impresión de mensaje.

❖ Entrada donde la impresión de mensaje es “REGULAR”, es decir, que todos los datos

de entrada son diferentes.

Se ejecuta el analizador sintáctico de la siguiente manera:

  1. Java parser Entrada.txt //entrada es el nombre del archivo de texto

❖ Entrada donde la impresión de mensaje es “INDEPENDIENTE DEL CONTEXTO”, es decir,

que al menos un par son idénticos. Se ejecuta el analizador sintáctico de la siguiente manera:

  1. Java parser Entrada.txt //entrada es el nombre del archivo de texto

❖ Entrada donde la impresión de mensaje es “DEPENDIENTE DEL CONTEXTO”, es decir,

que todos los datos de entrada son exactamente iguales. Se ejecuta el analizador sintáctico de la siguiente manera:

  1. Java parser Entrada.txt //entrada es el nombre del archivo de texto