You are on page 1of 14

TECNOLOGICO NACIONAL DE MEXICO

Instituto Tecnolgico de la Laguna


Ingeniera 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 Daz Salazar
11130601 Anselmo Garcia Espino

PROFESOR:
Ing. Luis Fernando Gil Vzquez

Torren, Coah. a 17 de Febrero del 2015

ITL

Lenguajes y Automatas II

Ejercicio

Ene-Jun/2015

Disear un Parser Predictivo Recursivo para la siguiente gramtica libre de contexto que define un lenguaje bsico
llamado SIMPLE, el cual permite declarar variables de tipo entero, real y carcter y soporta la sentencia de
asignacin 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 modificacin a la gramtica que permita soportar la sentencia si-entonces que tiene la
siguiente estructura sintctica:
si <condicin> entonces
inicio
<sentencias>
fin

donde
<condicin>
oprel
<expresin>

:= <expresin> oprel <expresin>


:= > | < | >= | <= | = | <>
:= son las expresiones generadas por el smbolo E

Anlisis
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}

Pag. 2

ITL

Lenguajes y Automatas II

Ene-Jun/2015

Diseo
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 sintctico
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
Pag. 3

ITL

Lenguajes y Automatas II

Ene-Jun/2015

error // error sintctico


end
Procedure C
begin
if preanalisis == inicio then
begin
//C inicio S fin
emparejar (inicio)
S
emparejar (fin)
end
else
error // error sintctico
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

Pag. 4

ITL

Lenguajes y Automatas II

Ene-Jun/2015

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 sintctico
end

Cdigo
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
*: Descripcin
: 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 Daz
Se agregaron los procedures correspondientes
*:
a la gramatica del lenguaje simple
*: 13/Feb/2015 Eduardo Daz
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;
Pag. 5

ITL

Lenguajes y Automatas II

Ene-Jun/2015

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
//--------------------------------------------------------------------------

Pag. 6

ITL

Lenguajes y Automatas II
//

PEGAR AQUI EL CODIGO DE SUS PROCEDURES

Ene-Jun/2015
*

//-------------------------------------------------------------------------// 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
//--------------------------------------------------------------------------

Pag. 7

ITL

Lenguajes y Automatas II

Ene-Jun/2015

//-------------------------------------------------------------------------// 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
//-------------------------------------------------------------------------//-------------------------------------------------------------------------}

Pag. 8

ITL

Lenguajes y Automatas II

Ene-Jun/2015

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
*: Descripcin
:
*:
*:
*: Ult.Modif.
:
*: Fecha
Modific
Modificacion
*:=============================================================================
*: 12/Feb/2015 Eduardo Daz
Se agregaron las palabras reservadas del
*:
lenguaje simple
*: 13/Feb/2015 Eduardo Daz
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];
}
//--------------------------------------------------------------------------

Pag. 9

ITL

Lenguajes y Automatas II

Ene-Jun/2015

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 mtodo Analiza()
Pag. 10

ITL

Lenguajes y Automatas II

Ene-Jun/2015

//-------------------------------------------------------------------------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;
}
//--------------------------------------------------------------------------

Pag. 11

ITL

Lenguajes y Automatas II

Ene-Jun/2015

// 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
lineaTS
entrada
lineaTS

de simbolos, linea reservada


= new Linea_TS ( "", "", "", "");
= cmp.ts.insertar ( 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 lnea no est vaca 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
//--------------------------------------------------------------------------

Pag. 12

ITL

Lenguajes y Automatas II

Ene-Jun/2015

Prueba de Ejecucin

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.

Pag. 13

ITL

Lenguajes y Automatas II

Ene-Jun/2015

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.

Pag. 14

You might also like