Post on 12-Apr-2017
Analizador SintácticoAdrián Alonso Vega
Pruebas
Introducción
Conclusion
Problema
SoluciónHerramientas
IntroducciónResumen de la práctica
Introducción Para realizar el analizador sintáctico utilizaremos la herramienta LEX que no
es más que un generador de analizadores léxicos, el cual toma como entrada una serie de configuraciones y construye un analizador léxico aplicando unos patrones definidos con expresiones regulares y unas acciones que realizar al localizar esos patrones en nuestro fichero de entrada.
En este caso por cada token que reconozca el analizador léxico la acción a realizar será pasárselo al analizador sintáctico para verificarlo y compararlo con una gramática libre de contexto y verificar si es correcta la estructura formada.
Este analizador deberá recuperarse de errores y mostrar los distintos errores
de sintaxis y léxicos que aparezcan en el código. Para ello las herramientas nos proporcionan la posibilidad de interconectarlas a través de ciertas directivas.
En la siguiente presentación se explica la solución para construir un analizador sintáctico con el generador de analizadores léxico JFLEX y el generador de analizadores Sintácticos CUP para Java que estudie un código fuente de un lenguaje L proporcionado por el profesorado
Pruebas
Introducción
Conclusion
Problema
SoluciónHerramientas
ProblemaMétodo constructivo
Requisitos Obtenidos Detección de errores en la declaración de variables. Detección de errores en la declaración de funciones. Detección de expresiones mal formadas.. Detección de invocaciones incorrectas a funciones (por sintaxis, no
por semántica) Si hay alguna función declarada pero no invocada en el código ha de
emitirse un aviso (warning) indicándolo al final del proceso. El analizador propuesto deberá mostrar un mensaje que indique la
línea donde se ha producido el error informe con el número de errores que se han producido, tanto
léxicos como sintácticos.
Empleando la práctica anterior tenemos los pilares para poder avanzar y basarnos en ella para construir el analizador sintáctico. El enunciado de la práctica expone unos ciertos requisitos que obtendremos para realizar la práctica con éxito.
Gestión de Errorres
Declaración de variables
Declaración de funciones
Expresiones mal
formadas
Invocaciones incorrectas
Funciones no
invocadas
Pruebas
Introducción
Conclusion
Problema
SoluciónHerramientas
Pruebas
Introducción
Conclusion
Problema
SoluciónHerramientas
¿Cómo Funciona?
Scanner.java
Parser.java
Sym.javatoken
Código.prog
¿Cómo Funciona?
JLex¿Qué es?
Partes de JLex El fichero de especificación de JFlex esta dividido entres secciones separadas
por el delimitador %%. Cadauna de ellas tiene una semántica diferente
I. Sección de código de usuario La sección de código de usuario se utiliza para incluir cualquier declaración java
(paquete, importación o clase) que sea necesario para compilar el scanner II. Sección de directivas Se incluyen directivas de compatibilidad con cup, gestión de fila, columna y
lexema, declaración de estados y macros e inclusión de código de Inicialización
III. Sección de reglas patrón - acción La definición se basa en reglas patrón acción que indican el código java que
debe ejecutarse cuando la entrada encaja con determinado patrón léxico.
JLex es una herramienta para la generación de analizadores léxicos escritos en java.
A partir de un fichero de especificación que describe las características léxicas de un lenguaje, JFlex genera un código fuente compilable que puede ser utilizado como analizador léxico
Scanner.lex I. Sección de código de usuario import java_cup.runtime.Symbol; import java.io.*;
II. Sección de directivas y macros
%line%cup
VARIABLE=[a-zA-Z][a-zA-Z0-9]*FUNCION=[$][a-zA-Z][a-zA-Z0-9]*NUMERO=[0-9]+RARO=[0-9]+{VARIABLE}COMENTARIO=\/\/[a-zA-Z0-9 \t]*
III. Sección de reglas patrón – acción
[\r\n\t ]+ {/*prescindir de blancos*/}
{DIRECTIVA} {return new Symbol (sym.IDVARIABLE,yyline + 1 ,1, yytext()); }
"RETURN“ {return new Symbol (sym.RETURN,yyline + 1 ,1, yytext());}
. {System.out.println("Error lexico en la linea "+(yyline + 1)+" -> Caracter no aceptado"); contadorlexicos++;}
Cup¿Qué es?
Partes de Cup
I. Paquetes e importaciones
II. Action code
III. Parser code
IV. Declaración de terminales
V. Declaración de no terminales
VI. Declaración del reglas de producción
Cup es una herramienta para la generación de analizadores sintácticos escritos en java. A partir de un fichero de especificación que describe las características sintácticas de un lenguaje, Cup generaun código fuente compilable que puede ser utilizado como analizador sintáctico
Parser.cup I. Paquetes e importaciones
import java_cup.runtime.*;import java.io.*;import java.util.ArrayList;
action code {:
ArrayList<String> funciones =new ArrayList<String>();
public void warning(){
for(int i=0;i<funciones.size();i++){System.out.println(("Warning la funcion "+ funciones.get(i) + " ha
sido declarada pero no invocada: \n"));}
}
:};
II. Action Code
Parser.cup III. Parser Code
parser code {:public void syntax_error(Symbol s)
{report_error("Detectado error sintactico en linea "+Integer.toString(s.left)+"\nToken leido \""+s.value+"\" se esperaba otro token",null);
}
public void unrecovered_syntax_error(Symbol s) throws java.lang.Exception{report_fatal_error("No se pudo recuperar el error", null);
}
IV. Declaración de terminales
terminal FLECHA, SUMA, RESTA, ASIGNACION, COMA, PUNTOYCOMA, PARENTESISA, PARENTESISC;
terminal PROGRAM, VARDECL, FUNCTION, BEGIN, END, BOOL, INT, RETURN, TRUE, FALSE, NUMERO;
terminal String IDVARIABLE, IDFUNCION;
Parser.cup V. Declaración de no terminales
non terminal gramatica, declaracionvariables, listavariables, tipo, declaracionfunciones, unitario, listaparametros;
non terminal listadoexpresiones, expresion, formula, operacion, operando, llamadafuncion,listadopar, arg;
IV. Declaración de reglas de producción
start with gramatica;
gramatica ::= PROGRAM VARDECL declaracionvariables END PUNTOYCOMA declaracionfunciones BEGIN listadoexpresiones END PUNTOYCOMA
Este es el axioma principal de nuestra gramática. Hemos dividido la lectura del código en distintos bloques principales. Uno de ellos se encarga a la declaración de variables, otro se encarga de la declaración de funciones y el otro gran bloque es el de las expresiones dentro del codigo.
Análisis del Lenguaje
Gramáticastart with gramatica;
gramatica ::= PROGRAM VARDECL declaracionvariables END PUNTOYCOMA declaracionfunciones BEGIN listadoexpresiones END PUNTOYCOMA ;
declaracionvariables::= declaracionvariables listavariables FLECHA tipo PUNTOYCOMA
| | error PUNTOYCOMA;
tipo::= BOOL | INT;
listavariables::= IDVARIABLE COMA listavariables | IDVARIABLE;
declaracionfunciones::= FUNCTION IDFUNCION:F1 listaparametros listadoexpresiones RETURN unitario PUNTOYCOMA declaracionfunciones
|
| error declaracionfunciones;
unitario::= TRUE | FALSE | NUMERO;
listaparametros::= IDVARIABLE PARENTESISA tipo PARENTESISC COMA listaparametros| IDVARIABLE PARENTESISA tipo PARENTESISC
|;
listadoexpresiones::= expresion listadoexpresiones | ;
expresion::= IDVARIABLE ASIGNACION formula PUNTOYCOMA| error PUNTOYCOMA;
formula::= PARENTESISA formula PARENTESISC operacion formula | PARENTESISA formula PARENTESISC
| operando operacion formula | operando;
operacion::= SUMA | RESTA;
operando::= NUMERO | IDFUNCION:F2 | IDVARIABLE | llamadafuncion ;
llamadafuncion::=IDFUNCION:F2 PARENTESISA listadopar PARENTESISC | errorPARENTESISC;| arg | ;
arg::= TRUE | FALSE | NUMERO| IDVARIABLE;
listadopar::= arg COMA listadopar | arg
| ;
arg::= TRUE | FALSE | NUMERO| IDVARIABLE;
Gramática
Pruebas
Introducción
Conclusion
Problema
SoluciónHerramientas
PruebasIdentificativo P01Elemento/s a probar
En esta prueba se procederá a probar la declaración de variables cuando el código es correcto.
Entrada PROGRAMVARDECLid,id2,id3 -> INT;id4,id5,id6 -> BOOL;cont, asd -> int;END;function $nombre1 a1 (bool), b1 (int)id3 = 4 + b1;return true;BEGINid=$nombre2(4);END;
Resultados obtenidos
Numero de errores léxicos: 0Numero de errores sintácticos: 0Compilación Terminada
Resultado CorrectoIncidencias -
Identificativo P02Elemento/s a probar
En esta prueba se procederá a probar la declaración de variables cuando hay errores sintacticos
Entrada PROGRAMVARDECLid,id2,id3 -> INT;id4,id5,id6 BOOL;cont, asd -> int;END;function $nombre1 a1 (bool), b1 (int)id3 = 4 + b1;return true;BEGINid=$nombre2(4);END;
Resultados obtenidos
Detectado error sintáctico en línea 4Token leído “BOOL” se esperaba otro tokenError de declaración de variables
Numero de errores léxicos: 0Numero de errores sintácticos: 1Compilacion Terminada
Resultado CorrectoIncidencias -
PruebasIdentificativo P03Elemento/s a probar
En esta prueba se procederá a probar la declaración de variables cuando hay errores sintacticos
Entrada PROGRAMVARDECLid,id2,id3 -> ;id4,id5,id6 -> BOOL;cont asd -> int;END;function $nombre1 a1 (bool), b1 (int)id3 = 4 + b1;return true;BEGINid=$nombre2(4);END;
Resultados obtenidos
Detectado error sintáctico en línea 3Token leído “BOOL” se esperaba otro tokenError de declaración de variables
Detectado error sintáctico en línea 5Token leído “asd” se esperaba otro tokenError de declaración de variables
Numero de errores léxicos: 0Numero de errores sintácticos: 2Compilacion Terminada
Resultado CorrectoIncidencias -
Identificativo P04Elemento/s a probar
En esta prueba se procederá a probar la declaración de variables cuando hay errores sintacticos
Entrada PROGRAMVARDECLid,id2,id3 -> INT;id4,id5,id6 -> BOOLcont,asd -> int;END;function $nombre1 a1 (bool), b1 (int)id3 = 4 + b1;return true;BEGINid=$nombre2(4);END;
Resultados obtenidos
Detectado error sintáctico en línea 5Token leído “cont” se esperaba otro tokenError de declaración de variables
Numero de errores léxicos: 0Numero de errores sintácticos: 1Compilacion Terminada
Resultado CorrectoIncidencias -
PruebasIdentificativo P05Elemento/s a probar
En esta prueba se procederá a probar la declaración de funciones cuando todo es correcto
Entrada PROGRAMVARDECL id,id2,id3 -> INT;END;function $nombre1 a1 (bool), b1 (int) id3 = 4 + b1;return true;function $nombre2 return 4;BEGINid2=$nombre2(id);END;
Resultados obtenidos
Warning la función declarada pero no invocada: $nombre1
Numero de errores léxicos: 0Numero de errores sintácticos: 0Compilacion Terminada
Resultado CorrectoIncidencias -
Identificativo P06Elemento/s a probar
En esta prueba se procederá a probar la declaración de funciones cuando hay errores sintacticos
Entrada PROGRAMVARDECL id,id2,id3 -> INT;END;function $nombre1 a1 (bool, b1 (int) id3 = 4 + b1;return true;function $nombre2 return 4;BEGINid2=$nombre2(id);END;
Resultados obtenidos
Detectado error sintáctico en línea 5Token leído “,” se esperaba otro tokenError de declaración de funcion
Numero de errores léxicos: 0Numero de errores sintácticos: 1Compilacion Terminada
Resultado CorrectoIncidencias -
PruebasIdentificativo P07Elemento/s a probar
En esta prueba se procederá a probar la declaración de funciones cuando hay errores sintácticos
Entrada PROGRAMVARDECL id,id2,id3 -> INT;END;function a1 (bool, b1 (int) id3 = 4 + b1;return true;function $nombre2 return ;BEGINid2=$nombre2(id);END;
Resultados obtenidos
Detectado error sintáctico en línea 5Token leído “a1” se esperaba otro tokenError de declaración de función
Detectado error sintáctico en línea 9Token leído “return” se esperaba otro tokenError de declaración de funcion
Numero de errores léxicos: 0Numero de errores sintácticos: 2Compilacion Terminada
Resultado CorrectoIncidencias -
Identificativo P08Elemento/s a probar
En esta prueba se procederá a probar la estructura correcta de expresiones
Entrada PROGRAMVARDECL id,id2,id3 -> INT;END;function $nombre1 a1 (bool), b1 (int) id3 = 4 + b1;return true;function $nombre2 return 4;BEGINid2=$nombre2(id);END;
Resultados obtenidos
Warning la función $nombre1 ha sido declarada pero no invocada:
Numero de errores léxicos: 0Numero de errores sintácticos: 0Compilacion Terminada
Resultado CorrectoIncidencias -
PruebasIdentificativo P09Elemento/s a probar En esta prueba se procederá a probar la estructura
correcta de expresionesEntrada PROGRAM
VARDECL id,id2,id3 -> INT;END;function $nombre1 a1 (bool), b1 (int) id3 = 4 + b1;return true;function $nombre2 return 4;BEGINid2=$nombre2(id);END;
Resultados obtenidos
Warning la función $nombre1 ha sido declarada pero no invocada:
Numero de errores léxicos: 0Numero de errores sintácticos: 0Compilacion Terminada
Resultado CorrectoIncidencias -
Identificativo P10Elemento/s a probar
En esta prueba se procederá a probar la estructura incorrecta de llamadas a funciones
Entrada PROGRAMVARDECL id,id2,id3 -> INT; id4,id5,id6 -> BOOL; cont, asd -> int;END; function $nombre1 a1 (bool), b1 (int) id3 = 4 + b1;return true; function $nombre2 a2return 4; function $nombre3return true; BEGIN//fichero de pruebaid3=(6 + 6) - $nombre2(2);id=$nombre2(4);id4=$nombre1(false,2;id2=$nombre2(id);END;
Resultados obtenidos
Detectado error sintáctico en línea 13Token leído “return” se esperaba otro tokenError de declaración de función
Detectado error sintáctico en línea 22Token leído “;” se esperaba otro tokenError en llamada a funcion
Warning la función $nombre1 ha sido declarada pero no invocada:Warning la función $nombre3 ha sido declarada pero no invocada:
Numero de errores léxicos: 0Numero de errores sintácticos: 2Compilacion Terminada
Resultado CorrectoIncidencias -
PruebasIdentificativo P11Elemento/s a probar
En esta prueba se procederá a probar todo tipo de errores encontrados
Entrada PROGRAMVARDECL id,id2,id3 -> INT; id4,id5,5id6 -> BOOL; cont, asd int;END;ñfunction $nombre1 a1 (bool), b1 (int) id3 = 4 + b1;return true; function $nombre2 a2return 4; function $nombre3return true; BEGIN//fichero de pruebaid3=(6 + 6) - $nombre2(,2);id=$nombre2(4);id4=$nombre1(false,2);id2=$nombre2(id);END;
Resultados obtenidos
Error léxico en la línea 4 -> identificador 5id6 mal escrito
Detectado error sintáctico en línea 4Token leído “->” se esperaba otro tokenError de declaración de variables
Detectado error sintáctico en línea 5Token leído “int” se esperaba otro tokenError léxico en la línea 7 -> Carácter no aceptadoError de declaración de variables
Detectado error sintáctico en línea 13Token leído “return” se esperaba otro tokenError en declaración de función
Detectado error sintáctico en línea 20Token leído “,” se esperaba otro tokenError en llamada a funcion
Warning la función $nombre3 ha sido declarada pero no invocada:
Numero de errores léxicos: 2Numero de errores sintácticos: 4Compilacion Terminada
Resultado CorrectoIncidencias -
Identificativo P12Elemento/s a probar
En esta prueba se procederá a probar el código proporcionado en la práctica.
Entrada PROGRAMVARDECL id,id2,id3 -> INT; id4,id5,id6 -> BOOL; cont, asd -> int;END; function $nombre1 a1 (bool), b1 (int) id3 = 4 + b1;return true; function $nombre2 a2return 4; function $nombre3return true; BEGIN//fichero de pruebaid3=(6 + 6) - $nombre2(2);id=$nombre2(4);id4=$nombre1(false,2);id2=$nombre2(id);END;
Resultados obtenidos
Detectado error sintáctico en línea 13Token leído “return” se esperaba otro tokenError de declaración de funcion
Warning la función $nombre3 ha sido declarada pero no invocada:
Numero de errores léxicos: 0Numero de errores sintácticos: 1Compilacion Terminada
Resultado CorrectoIncidencias -
Pruebas
Introducción
Conclusion
Problema
SoluciónHerramientas
ConclusiónLa conclusión final de la práctica es que trata de hacernos comprender como coopera un analizador léxico con un analizador sintáctico, y como este último a través de la definición de una gramática correcta se pueden detectar todo tipos de errores sintácticos y recuperarse de ellos siguiendo con el análisis.
Hoy en día todos los lenguajes de programación se pueden representar con una gramática libre de contexto. Realizando la práctica se asientan muchos conceptos teóricos de los analizadores sintácticos y nos amplía la visión para posteriormente implementar un analizador semántico empleando lo anteriormente construido.