













Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Los mejores documentos en venta realizados por estudiantes que han terminado sus estudios
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Descubre las mejores universidades de tu país según los usuarios de Docsity
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
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
1 / 21
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!
Análisis Semántico (Atribución de la gramática)
El alumno aprenderá a asignar atributos a la gramática y utilizará atributos sintetizados
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.
x64.
EJEMPLO Programa: Operaciones Aritméticas JFLEX
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:
EJEMPLO Programa: Lista de números enteros. JFLEX
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. (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:
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:
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.
de entrada son diferentes.
Se ejecuta el analizador sintáctico de la siguiente manera:
que al menos un par son idénticos. Se ejecuta el analizador sintáctico de la siguiente manera:
que todos los datos de entrada son exactamente iguales. Se ejecuta el analizador sintáctico de la siguiente manera: