TECNOLOGICO NACIONAL DE MEXICO
Instituto Tecnológico de la Laguna Ingeniería en Sistemas Computacionales
LENGUAJES Y AUTOMATAS II
SEMESTRE: Ene - Jun / 2015 GRUPO: “A” 10 – 11 Hrs
PRACTICA No. P01a
P01a - Parser predictivo recursivo del lenguaje SIMPLE
ALUMNO:
11130022 Esmeralda Aldaco Balderas 11130036 Eduardo Díaz Salazar
11130601 Anselmo Garcia Espino
PROFESOR: Ing. Luis Fernando Gil Vázquez
Torreón, Coah. a 17 de Febrero del 2015
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 2
Ejercicio 1
Diseñar un Parser Predictivo Recursivo para la siguiente gramática libre de contexto que define un lenguaje básico llamado SIMPLE, el cual permite declarar variables de tipo entero, real y carácter y soporta la sentencia de asignación en el cuerpo principal del programa.
P V C V id : T V | empty
T entero | real | caracter
C inicio S fin
S id opasig E S | empty
E num | num.num
El Parser deberá incluir una modificación a la gramática que permita soportar la sentencia si-entonces que tiene la siguiente estructura sintáctica:
si <condición> entonces
inicio <sentencias>
fin
donde
<condición> := <expresión> oprel <expresión> oprel := > | < | >= | <= | = | <> <expresión> := son las expresiones generadas por el símbolo E
Análisis Es necesario calcular los conjuntos primeros de todas las producciones.
PRIMEROS (P) = {PRIMEROS (V), PRIMEROS (C)}
PRIMEROS (V) = {id, €}
PRIMEROS (T) = {entero, real, caracter}
PRIMEROS (C) = {inicio}
PRIMEROS (S) = {id, si, €}
PRIMEROS (E) = {num, num.num}
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 3
Diseño
Procedure P
begin
if preanalisis IN {id} then
begin
//P VC
V
C
end
else if preanalisis == ‘inicio’ then
begin
//P € C
C
end
else
error // error sintáctico
end
Procedure V
begin
if preanalisis == ‘id’ then
begin
//V id : T
emparejar (‘id’)
emparejar (‘:’)
T
end
else
begin
//V €
end
end
Procedure T
begin
if preanalisis == ‘entero’ then
begin
//T entero
emparejar (‘entero’)
end
else if preanalisis == ‘real’ then
begin
//T real
emparejar (‘real’)
end
else if preanalisis == ‘caracter’ then
begin
//T caracter
emparejar (‘caracter’)
end
else
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 4
error // error sintáctico
end
Procedure C
begin
if preanalisis == ‘inicio’ then
begin
//C inicio S fin
emparejar (‘inicio’)
S
emparejar (‘fin’)
end
else
error // error sintáctico
end
Procedure S
begin
if preanalisis == ‘id’ then
begin
//S id opasig E S
emparejar (‘id’)
emparejar (‘opasig’)
E
S
end
else if preanalisis == ‘si’ then
begin
//S si E oprel E entonces C S
emparejar (‘si’)
E
emparejar (‘oprel’)
E
emparejar (‘entonces’)
C
S
end
else
begin
//S €
end
end
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 5
Procedure E
begin
if preanalisis == ‘num’ then
begin
//E num
emparejar (‘num’)
end
if preanalisis == ‘num.num’ then
begin
//E num.num
emparejar (‘num-num’)
end
else
error // error sintáctico
end
Código
SintacticoSemantico.java
/*:-----------------------------------------------------------------------------
*: INSTITUTO TECNOLOGICO DE LA LAGUNA
*: INGENIERIA EN SISTEMAS COMPUTACIONALES
*: LENGUAJES Y AUTOMATAS II
*:
*: SEMESTRE: ENE-JUN/2015 HORA: 10 - 11 HRS
*:
*:
*: Clase con la funcionalidad del Analizador Sintactico
*
*:
*: Archivo : SintacticoSemantico.java
*: Autor : Fernando Gil ( Estructura general de la clase )
*: Grupo de Lenguajes y Automatas II ( Procedures )
*: Fecha : 03/Sep/2014
*: Compilador : Java JDK 7
*: Descripción : Esta clase implementa un parser descendente del tipo
*: Predictivo Recursivo. Se forma por un metodo por cada simbolo
*: No-Terminal de la gramatica mas el metodo emparejar ().
*: El analisis empieza invocando al metodo del simbolo inicial.
*: Ult.Modif. :
*: Fecha Modificó Modificacion
*:=============================================================================
*: 12/Feb/2015 Eduardo Díaz Se agregaron los procedures correspondientes
*: a la gramatica del lenguaje simple
*: 13/Feb/2015 Eduardo Díaz Se modifico el procedure S y se agrego
*: soporte para que reconociera una sentencia
*: condicional.
*:-----------------------------------------------------------------------------
*/
package compilador;
import javax.swing.JOptionPane;
public class SintacticoSemantico {
private Compilador cmp;
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 6
private boolean analizarSemantica = false;
private String preanalisis;
//--------------------------------------------------------------------------
// Constructor de la clase, recibe la referencia de la clase principal del
// compilador.
//
public SintacticoSemantico ( Compilador c ) {
cmp = c;
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Metodo que inicia la ejecucion del analisis sintactico predictivo.
// analizarSemantica : true = realiza el analisis semantico a la par del sintactico
// false= realiza solo el analisis sintactico sin comprobacion semantica
public void analizar ( boolean analizarSemantica ) {
this.analizarSemantica = analizarSemantica;
preanalisis = cmp.be.preAnalisis.complex;
P();
// * * * INVOCAR AQUI EL PROCEDURE DEL SIMBOLO INICIAL * * *
}
//--------------------------------------------------------------------------
private void emparejar ( String t ) {
if ( cmp.be.preAnalisis.complex.equals ( t ) ){
cmp.be.siguiente ();
preanalisis = cmp.be.preAnalisis.complex;
}
else
errorEmparejar ( t , cmp.be.preAnalisis.lexema );
}
//--------------------------------------------------------------------------
// Metodo para devolver un error al emparejar
//--------------------------------------------------------------------------
private void errorEmparejar ( String _token, String _lexema ) {
String msjError = "ERROR SINTACTICO: ";
if ( _token.equals ( "id" ) )
msjError += "Se esperaba un identificador";
else if ( _token.equals ( "num" ) )
msjError += "Se esperaba una constante entera";
else if ( _token.equals ( "num.num" ) )
msjError += "Se esperaba una constante real";
else if ( _token.equals ( "literal" ) )
msjError += "Se esperaba una literal";
else if ( _token.equals ( "oparit" ) )
msjError += "Se esperaba un operador aritmetico";
else if ( _token.equals ( "oprel" ) )
msjError += "Se esperaba un operador relacional";
else if ( _token.equals ( "opasig" ) )
msjError += "Se esperaba operador de asignacion";
else
msjError += "Se esperaba " + _token;
msjError += " se encontró " + _lexema;
cmp.me.error ( Compilador.ERR_SINTACTICO, msjError );
}
// Fin de ErrorEmparejar
//--------------------------------------------------------------------------
// Metodo para mostrar un error sintactico
private void error ( String _descripError ) {
cmp.me.error ( cmp.ERR_SINTACTICO, _descripError );
}
// Fin de error
//--------------------------------------------------------------------------
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 7
// * * * * PEGAR AQUI EL CODIGO DE SUS PROCEDURES * * * *
//--------------------------------------------------------------------------
// Metodo del procedimiento P
//--------------------------------------------------------------------------
private void P() {
if (preanalisis.equals("id")) {
//P-->VC
V();
C();
} else if (preanalisis.equals("inicio")) {
//P-->emptyC
C();
} else {
error("El programa debe iniciar con una declaracion de una variable o con la palabra inicio");
}
}
// Fin de P
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Metodo del procedimiento V
//--------------------------------------------------------------------------
private void V() {
if (preanalisis.equals("id")) {
//V-->id:T
emparejar("id");
emparejar(":");
T();
V();
} else {
} //V-->empty
}
// Fin de V
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Metodo del procedimiento T
//--------------------------------------------------------------------------
private void T() {
if (preanalisis.equals("entero")) {
//T-->entero
emparejar("entero");
} else if (preanalisis.equals("real")) {
//T-->real
emparejar("real");
} else if (preanalisis.equals("caracter")) {
//T-->caracter
emparejar("caracter");
} else {
error("Error en el tipo de dato de la variable, se esperaba entero, real o caracter");
}
}
// Fin de T
//--------------------------------------------------------------------------
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 8
//--------------------------------------------------------------------------
// Metodo del procedimiento C
//--------------------------------------------------------------------------
private void C() {
if (preanalisis.equals("inicio")) {
//C-->inicio S fin
emparejar("inicio");
S();
emparejar("fin");
} else {
error("Error en el cuerpo del programa.");
}
}
// Fin de C
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Metodo del procedimiento S
//--------------------------------------------------------------------------
private void S() {
if (preanalisis.equals("id")) {
//S-->id opasig E S
emparejar("id");
emparejar("opasig");
E();
S();
} else if (preanalisis.equals("si")) {
//S--> si condicinal entonces C
emparejar("si");
E();
emparejar("oprel");
E();
emparejar("entonces");
C();
S();
} else { // S--> empty
}
}
// Fin de S
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Metodo del procedimiento E
//--------------------------------------------------------------------------
private void E() {
if (preanalisis.equals("num")) {
//E-->num
emparejar("num");
} else if (preanalisis.equals("num.num")) {
//E-->num.num
emparejar("num.num");
} else {
error("Error, se esperaba entero o real");
}
}
// Fin de E
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
}
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 9
Lexico.java /*:-----------------------------------------------------------------------------
*: INSTITUTO TECNOLOGICO DE LA LAGUNA
*: INGENIERIA EN SISTEMAS COMPUTACIONALES
*: LENGUAJES Y AUTOMATAS II
*:
*: SEMESTRE: ENE-JUN/2015 HORA: 10 - 11 HRS
*:
*:
*: # Clase que implementa la etapa de Analisis de Lexico
*
*:
*: Archivo : Lexico.java
*: Autor : Fernando Gil
*: Fecha : 03/SEP/2014
*: Compilador : Java JDK 7
*: Descripción :
*:
*:
*: Ult.Modif. :
*: Fecha Modificó Modificacion
*:=============================================================================
*: 12/Feb/2015 Eduardo Díaz Se agregaron las palabras reservadas del
*: lenguaje simple
*: 13/Feb/2015 Eduardo Díaz Se modifico el metodo EsPalabraReservada.
*: Se agrego "si" y "entonces" como soporte
*: de un condicional.
*:-----------------------------------------------------------------------------
*/
package compilador;
public class Lexico {
final int TOKREC = 15;
final int MAXTOKENS = 500;
private String[] _lexemas;
private String[] _tokens;
private String _lexema;
private int _noTokens;
private int _i;
private int _iniToken;
private Automata oAFD;
private Compilador cmp;
//--------------------------------------------------------------------------
public Lexico ( Compilador cmp ) // constructor por defecto
{
this.cmp = cmp;
_lexemas = new String[MAXTOKENS];
_tokens = new String[MAXTOKENS];
oAFD = new Automata();
_i = 0;
_iniToken = 0;
_noTokens = 0;
}
//--------------------------------------------------------------------------
public void Inicia()
{
_i = 0;
_iniToken = 0;
_noTokens = 0;
_lexemas = new String[MAXTOKENS];
_tokens = new String[MAXTOKENS];
}
//--------------------------------------------------------------------------
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 10
public void Analiza(String texto)
{
Boolean recAuto;
int noAuto;
while (_i < texto.length())
{
recAuto=false;
noAuto=0;
for(;noAuto<TOKREC&&!recAuto;)
if(oAFD.Reconoce(texto,this,noAuto))
recAuto=true;
else
noAuto++;
if (recAuto)
{
_lexema = texto.substring(_iniToken, _i);
switch (noAuto)
{
//-------------- Automata Delimita--------------
case 0 : //_tokens[_noTokens] = "Delimita";
break;
//-------------- Automata Opmult--------------
case 1 : _tokens[_noTokens] = "opmult";
break;
//-------------- Automata Opsuma--------------
case 2 : _tokens[_noTokens] = "opsuma";
break;
//-------------- Automata Identi--------------
case 3 : _tokens[_noTokens] = "id";
break;
//-------------- Automata Literal--------------
case 4 : _tokens[_noTokens] = "literal";
break;
//-------------- Automata Signo--------------
case 5 : _tokens[_noTokens] = "signo";
break;
//-------------- Automata Opasigna--------------
case 6 : _tokens[_noTokens] = "opasig";
break;
//-------------- Automata Reales1--------------
case 7 : _tokens[_noTokens] = "num.num";//"Reales1";
break;
//-------------- Automata Reales2--------------
case 8 : _tokens[_noTokens] = "num.num";//"Reales2";
break;
//-------------- Automata Reales3--------------
case 9 : _tokens[_noTokens] = "num.num";//"Reales3";
break;
//-------------- Automata Enteros--------------
case 10 : _tokens[_noTokens] = "num";//"Enteros";
break;
//-------------- Automata Oprel--------------
case 11 : _tokens[_noTokens] = "oprel";
break;
//-------------- Automata Oprel2--------------
case 12 : _tokens[_noTokens] = "oprel";
break;
//-------------- Automata CarEsp--------------
case 13 : _tokens[_noTokens] = "caresp";
break;
//-------------- Automata Punto--------------
case 14 : _tokens[_noTokens] = "punto";
break;
}
if(noAuto != 0)
_lexemas[_noTokens++] = _lexema;
}
else
_i++;
_iniToken = _i;
}
//Activar metodo pasarBufferEntrada
pasarBufferTabla ( );
} // fin del método Analiza()
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 11
//--------------------------------------------------------------------------
public int getI()
{
return _i;
}
//--------------------------------------------------------------------------
public void setI(int valor)
{
_i=valor;
}
//--------------------------------------------------------------------------
public int getIniToken()
{
return _iniToken;
}
//--------------------------------------------------------------------------
public String[] Tokens()
{
return _tokens;
}
//--------------------------------------------------------------------------
public String[] Lexemas()
{
return _lexemas;
}
//--------------------------------------------------------------------------
public int NOTOKENS()
{
return _noTokens;
}
//--------------------------------------------------------------------------
private Boolean EsPalabraReservada(String lex)
{
String palres[] = { "entero",
"real",
"caracter",
"inicio",
"fin",
"si",
"entonces"
};
for (int i = 0; i < palres.length; i++) {
if (lex.equals ( palres[i] ) ) {
return true;
}
}
return false;
}
//--------------------------------------------------------------------------
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 12
// Toma los tokens y los pasa a la tabla de simbolos y buffer de entrada
// Revision en 22/Nov/2012
private void pasarBufferTabla ( )
{
// Comenzamos con establecer la entrada, la l?nea y una bandera para
// palabras reservadas
int entrada = 0;
Linea_BE lineaBE = null;
Linea_TS lineaTS = null;
Boolean noPalres = true;
//tabla de simbolos, linea reservada
lineaTS = new Linea_TS ( "", "", "", "");
entrada = cmp.ts.insertar ( lineaTS );
lineaTS = null;
//Vamos a comparar todos los tokens obtenidos e insertar en la tabla
//de s?mbolos
for ( int i = 0; i < _noTokens; i++ )
{
//Comparando el identificador que no sea palabra reservada
if ( _tokens[ i ].equals ( "id" ) )
{
if(EsPalabraReservada(_lexemas[i])){
lineaBE = new Linea_BE (
_lexemas [ i ], _lexemas [ i ], 0 );
}
else {
lineaTS = new Linea_TS (
_tokens [ i ], _lexemas [ i ], "", "" );
entrada = cmp.ts.insertar ( lineaTS );
lineaBE = new Linea_BE (
_tokens [ i ], _lexemas [ i ], entrada );
}
}
//Variables que deja pasar a tabla de simbolos
else if ( _tokens [ i ].equals ( "num" ) ||
_tokens [ i ].equals ( "num.num" ) ||
_tokens [ i ].equals ( "literal" ) )
{
lineaTS = new Linea_TS (
_tokens [ i ], _lexemas [ i ], "", "" );
entrada = cmp.ts.insertar ( lineaTS );
lineaBE = new Linea_BE (
_tokens [ i ], _lexemas [ i ], entrada );
}
//Los siguientes no se insertan en tabla simbolos
else if ( _tokens [ i ].equals ( "opmult" )
|| _tokens [ i ].equals ( "opsuma" )
|| _tokens [ i ].equals ( "signo" )
|| _tokens [ i ].equals ( "opasig" )
|| _tokens [ i ].equals ( "oprel" ) )
lineaBE = new Linea_BE (
_tokens [ i ], _lexemas [ i ], 0 );
else if ( _tokens [ i ].equals ( "caresp" ) ||
_tokens [ i ].equals ( "punto" ) )
lineaBE = new Linea_BE (
_lexemas [ i ], _lexemas [ i ], 0 );
//Verificar que la línea no está vacía para agregar a la tabla
if ( lineaBE != null )
cmp.be.insertar ( lineaBE );
//Limpiar lineas
lineaBE = null; lineaTS = null;
}
}//Fin del metodo para pasar al buffer entrada y tabla simbolos
//--------------------------------------------------------------------------
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 13
}
Prueba de Ejecución
En esta captura se puso a prueba el compilador, se agregaron 2 declaraciones al inicio seguidas de 4 condicionales
con una sentencia dentro cada una. Y El compilador superó la prueba.
ITL Lenguajes y Automatas II Ene-Jun/2015
Pag. 14
En esta captura a diferencia de la anterior hay dos condicionales y dentro de cada condicional se encuentra otra condicion con su respectiva sentencia cada una. Al fina se agrego una sentencia y el compilador nuevamente pasó
la prueba.
Aquí intencionalmente por motivos de prueba se puso “finww” en lugar de “fin” en el terminador del condicional y el
compilador nos muestra 6 errores.
Top Related