ANALIZADOR LÉXICO, SINTÁCTICO Y SEMÁNTICO DEL LENGUAJE PASCAL UTILIZANDO JFLEX Y CUP


ANALIZADOR LÉXICO, SINTÁCTICO Y SEMÁNTICO DEL LENGUAJE PASCAL UTILIZANDO JFLEX Y CUP



1.  DEFINICIONES:

1.1.  ANALIZADOR LEXICO:
Esta fase se encarga de verificar si todas las cadenas pertenecen o no al lenguaje. Es decir realiza un análisis símbolo por símbolo indicando el token por cada uno de los elementos reconocidos.
El analizador léxico opera bajo petición del analizador sintáctico devolviendo un componente léxico conforme el analizador sintáctico lo va necesitando para avanzar en la gramática. Los componentes léxicos son los símbolos terminales de la gramática.
















1.2.  ANÁLISIS SINTÁCTICO: 
En esta fase se analiza la estructura de las expresiones en base a gramáticas. Aquí ya se puede determinar si una estructura por ejemplo una expresión matemática mal formada. El análisis que se realiza es jerárquico es decir en base a arboles de derivación que se obtienen de las mismas gramáticas.














1.3.  ANÁLISIS SEMÁNTICO: 
Este análisis es más difícil de formalizar, determina el tipo de los resultados intermedios, comprobar que los argumentos que tienen un operador pertenecen al conjunto de operadores posible, y si son compatibles entre sí. 

2.  REQUISITOS:
- JFLEX - analizador léxico para Java
 CUP - analizador sintáctico/semántico para Java

2.1.  JFLEX
JFlex es un metacompilador que permite generar rápidamente analizadores léxicos que se integran con Java.

CARACTERÍSTICAS DE JFLEX
Las características sobre salientes de JFlex son las siguientes:
-Soporte completo con caracteres Unicode.
-Permite generar analizadores léxicos rápidamente.
-Tiene una sintaxis cómoda de manipular y fácil de interpretar.
-Es independiente de la plataforma debido a que está diseñado para ser integrado con Java.
-Permite la integración con CUP (Analizador sintáctico).

ESTRUCTURA UN ARCHIVO DE JFLEX
Un archivo jfex está dividido en 3 secciones (cada sección se separa mediante %%).
-Opciones y declaraciones
-Código de usuario
-Reglas lexicográficas


EXPLICANDO ANALIZADOR LÉXICO EN JFLEX



  package Lexico;
  import java_cup.runtime.*;
  import Sintactico.*;
  %%
  %{   
  %}
  //---> Directivas
  %public 
  %class analizador_lexico
  %cupsym Simbolos
  %cup
  %char
  %column
  %full
  %ignorecase
  %line
  %unicode
  //-----> Expresiones Regulares
  L=[a-zA-Z_]
  D=[0-9]
  S=[< <= > >= ; , + - / *]
  punto=[.]
  puntos=[..]
  white=[  \t\r\n]
  //---> Estados
  %%
  //---> Simbolos  
  ":" { TablaSimbolos.addArrayList("SENTENCIA ASIGNATIVA" );                                  TablaSimbolos.addArrayList2(yytext());                                                                    TablaSimbolos.addArrayList3(String.valueOf(yyline+1));        TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1));  return new  Symbol(Simbolos.dospuntos,yycolumn,yyline,yytext()); }
  ":="{TablaSimbolos.addArrayList("SENTENCIA ASIGNATIVA" );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new  Symbol(Simbolos.dospuntosigual,yycolumn,yyline,yytext()); }
"("   { TablaSimbolos.addArrayList("ABRE PARÉNTESIS " );    TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1));  return new  Symbol(Simbolos.abrirP,yycolumn,yyline,yytext());  }
  ")" {  TablaSimbolos.addArrayList("CIERRA PARÉNTESIS :" );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1));  return new  Symbol(Simbolos.cerraP,yycolumn,yyline,yytext());}
  ">" { TablaSimbolos.addArrayList("OPERADOR RELACIONAL " );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1));return new  Symbol(Simbolos.oprelacional,yycolumn,yyline,yytext()); }
  ">="{ TablaSimbolos.addArrayList("OPERADOR RELACIONAL" );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1));  return new  Symbol(Simbolos.oprelacional,yycolumn,yyline,yytext());}
  "<" { TablaSimbolos.addArrayList("OPERADOR RELACIONAL " );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new  Symbol(Simbolos.oprelacional,yycolumn,yyline,yytext()); }
  "<="{ TablaSimbolos.addArrayList("OPERADOR RELACIONAL " );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new  Symbol(Simbolos.oprelacional,yycolumn,yyline,yytext()); }
  "<>"{ TablaSimbolos.addArrayList("OPERADOR RELACIONAL " );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new  Symbol(Simbolos.oprelacional,yycolumn,yyline,yytext()); }
  "," {TablaSimbolos.addArrayList("COMA" ); TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new  Symbol(Simbolos.coma,yycolumn,yyline,yytext());}

  ";" {TablaSimbolos.addArrayList("PUNTO Y COMA " );  TablaSimbolos.addArrayList2(yytext());  TablaSimbolos.addArrayList3(String.valueOf(yyline+1));  TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new  Symbol(Simbolos.pycoma,yycolumn,yyline,yytext());}


  "PROGRAM" {TablaSimbolos.addArrayList("INICIO DE PROGRAMA" );     TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Program,yycolumn,yyline,yytext()); }
  "USES" { TablaSimbolos.addArrayList("SENTENCIA USES " ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Uses,yycolumn,yyline,yytext());}
  "type" { TablaSimbolos.addArrayList("SENTENCIA TYPE " ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Type,yycolumn,yyline,yytext());}
  "VAR" { TablaSimbolos.addArrayList("SENTENCIA VAR" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.VAR,yycolumn,yyline,yytext()); }
  "function" { TablaSimbolos.addArrayList("SENTENCIA FUNCTION" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Function,yycolumn,yyline,yytext());}
  "procedure" { TablaSimbolos.addArrayList("SENTENCIA PROCEDURE" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Procedure,yycolumn,yyline,yytext());}
  "BEGIN" {  TablaSimbolos.addArrayList("INICIO DE PROGRAMA" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Begin,yycolumn,yyline,yytext());}
  "END." {  TablaSimbolos.addArrayList("FIN DE PROGRAMA" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.EndFinal,yycolumn,yyline,yytext());}
  "END;" { TablaSimbolos.addArrayList("CIERRE DE BEGIN" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.End,yycolumn,yyline,yytext());  }

  "FOR" { TablaSimbolos.addArrayList("SENTENCIA FOR" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.FOR,yycolumn,yyline,yytext()); }

  "to" { TablaSimbolos.addArrayList("SENTENCIA TO" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.To,yycolumn,yyline,yytext()); }
  "downto" { TablaSimbolos.addArrayList("SENTENCIA DOWNTO" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Downto,yycolumn,yyline,yytext()); }
  "Do" { TablaSimbolos.addArrayList("SENTENCIA DO" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Do,yycolumn,yyline,yytext());  }

  "REPEAT" { TablaSimbolos.addArrayList("SENTENCIA REPEAT" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.REPEAT,yycolumn,yyline,yytext());}
  "Until" { TablaSimbolos.addArrayList("SENTENCIA UNTIL" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Until,yycolumn,yyline,yytext());}

  "If" { TablaSimbolos.addArrayList("SENTENCIA IF" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.IF,yycolumn,yyline,yytext());}
  "then" { TablaSimbolos.addArrayList("SENTENCIA THEN" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Then,yycolumn,yyline,yytext()); } 
  "While" { TablaSimbolos.addArrayList("SENTENCIA WHILE" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.WHILE,yycolumn,yyline,yytext());  }

  "Integer" { TablaSimbolos.addArrayList("TIPO INTEGER" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Integer,yycolumn,yyline,yytext());}
  "String" { TablaSimbolos.addArrayList("TIPO STRING" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.String,yycolumn,yyline,yytext()); }
  "Char" { TablaSimbolos.addArrayList("TIPO CHAR" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Char,yycolumn,yyline,yytext()); }
  "BOOLEAN" { TablaSimbolos.addArrayList("TIPO BOOLEAN" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Boolean,yycolumn,yyline,yytext()); }
  "True" { TablaSimbolos.addArrayList("TRUE" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Booleant,yycolumn,yyline,yytext());}
  "False" { TablaSimbolos.addArrayList("FALSE" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Booleanf,yycolumn,yyline,yytext()); }

  {L}({L}|{D})* { TablaSimbolos.addArrayList("IDENTIFICADOR" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.ID,yycolumn,yyline,yytext()); }

  {D}({D})* { TablaSimbolos.addArrayList("ENTERO" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Int,yycolumn,yyline,yytext()); }

  ((D)*{puntos}(D)*) { TablaSimbolos.addArrayList("SUBRANGO INT" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.subrangoInt,yycolumn,yyline,yytext());  }

  (("'"{L}"'"){puntos}("'"{L}"'")) { TablaSimbolos.addArrayList("SUBRANGO CHAR" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.subrangoChar,yycolumn,yyline,yytext()); }

  (("'"{L}"'")) { TablaSimbolos.addArrayList("CHAR" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.Char,yycolumn,yyline,yytext()); }

  //-----> Espacios
    {white} {/*Ignore*/} 
     "//".* {/*Ignore*/}
     "{" .* "}"  {/*Ignore*/ } 
     "(*" .* "*)"  {/*Ignore*/} 
     "'" .* "'" { TablaSimbolos.addArrayList("CADENA" ); TablaSimbolos.addArrayList2(yytext()); TablaSimbolos.addArrayList3(String.valueOf(yyline+1)); TablaSimbolos.addArrayList4(String.valueOf(yycolumn+1)); return new Symbol(Simbolos.cadena,yycolumn,yyline,yytext()); }

  //-----> Errores lexicos 
      . {System.out.println(" Error Lexico "+yytext()+" Linea " + yyline + " Columna " +yycolumn); }

2.2. CUP

Un archivo de entrada CUP consta de las siguientes cinco partes:
1. Definición de paquete y sentencias import.
2. Sección de código de usuario.
3. Declaración de símbolos terminales y no terminales.
4. Declaraciones de precedencia.
5. Definición del símbolo inicial de la gramática y reglas de producción.


EXPLICANDO ANALIZADOR SINTÁCTICO Y SEMÁNTICO EN CUP




//---->importaciones y paquetes

package Sintactico;

import Semantico.*;

import java.util.ArrayList;

import java_cup.runtime.Symbol;



//----> Codigo para el parser,variables, metodos

parser code

{: //Metodo al que se llama automaticamente para algun error

   public void syntax_error(Symbol s)

   {

       String lexema=s.value.toString();

       int fila=s.right;

       int columna=s.left;
       System.out.println(" !!! Eror Sintactico Recuperado !!!!");
       System.out.println("\t\t Lexema : " +lexema);
       System.out.println("\t\t Fila : " +fila);
       System.out.println("\t\t Columna : " +columna);
    }
//Metodo al que se llama en el momento en que ya no es posible recuperacion de errores
public void unrecovered_syntax_error (Symbol s) throws java.lang.Exception
{
   String lexema=s.value.toString();
   int fila=s.right;
   int columna=s.left;
   System.out.println(" !!! Eror Sintactico  !!!!");
   System.out.println("\t\t Lexema : " +lexema);
   System.out.println("\t\t Fila : " +fila);
   System.out.println("\t\t Columna : " +columna);
}

:}
//-->Codigo para acciones gramaticales
action code
{:
        TablaFunciones tF =new TablaFunciones();
        TablaProcedimiento tP =new TablaProcedimiento();
        TablaTypes tT =new TablaTypes();
        TablaVariables tV =new TablaVariables();
        ArrayList<String> listadeId = new ArrayList();
        String tipo="",tipoaux="";
        int nparametros;
Boolean bandera=false;
Boolean banderaasig=false;
:}
//---> declaracion  terminales
terminal dospuntosigual,dospuntos,abrirP,cerraP,oprelacional,coma,pycoma;      
terminal Program,Uses,Type,VAR,Function,Procedure,Begin,EndFinal,End,FOR,
             To,Downto,Do,REPEAT,Until,IF,Then,ELSE, WHILE,Integer,Int,String,
             cadena,Char,Boolean,subrangoInt,subrangoChar,Booleant,Booleanf;
terminal String ID;



//---> declaracion de no terminales



non terminal structProgram,BloqueUse,BloqueType,BloqueVarA,BloqueVar,Cuerpo;

non terminal defProgram,defFunction,defProcedure,sentencia;

non terminal sentencias,sentIF,sentFor,sentWhile,sentRepeat,llamarFuncion;

non terminal nuevoType,expresionVar, listaID,existenteType,parametro,asignacion,

                     expresionlogica,step,sentUse,sentType,valor,sentIFBASE,argumentos,

                     parametro2,llamarMetodo ;



start with structProgram;

structProgram::=defProgram BloqueUse BloqueType BloqueVarA Begin Cuerpo EndFinal

|defProgram BloqueType BloqueVarA Begin Cuerpo EndFinal

|defProgram BloqueVarA Begin Cuerpo EndFinal

|defProgram BloqueUse BloqueVarA Begin Cuerpo EndFinal;

defProgram::=Program ID;
BloqueUse::= sentUse pycoma |sentUse pycoma BloqueUse ;
sentUse ::=Uses ID ;

BloqueType::=sentType|sentType BloqueType ;
sentType::=Type ID:x dospuntos nuevoType pycoma{: 
 tT.insertar( x,tipo); 
tipo="-1";:};

nuevoType::= Integer{:tipo="Integer";:}|Boolean{:tipo="Boolean";:}
             |Char{:tipo="Char";:}|String{:tipo="String";:}
             |subrangoInt{:tipo="Integer";:}
             |subrangoChar{:tipo="Char";:};

BloqueVarA::=VAR BloqueVar;
BloqueVar::= expresionVar pycoma BloqueVar
            |defFunction  BloqueVar
            |defProcedure BloqueVar|expresionVar pycoma|defFunction|defProcedure  ; 

defFunction::= Function ID:x parametro dospuntos existenteType Begin Cuerpo End{:tF.insertar( x,tipo,nparametros);    tipo="-1"; nparametros=0;:};

parametro::= abrirP argumentos cerraP
|abrirP cerraP{:
nparametros=0;:};

argumentos::= listaID dospuntos existenteType{:
nparametros=nparametros+1;
listadeId.clear();
:}|listaID dospuntos existenteType coma argumentos{:
nparametros=nparametros+1;
listadeId.clear();
:};
defProcedure::= Procedure ID:x parametro Begin Cuerpo End{:
tP.insertar( x,nparametros); 
nparametros=0;
:};
expresionVar::= listaID dospuntos existenteType {:
bandera=true;
:} ;
|Procedure ID:x parametro Begin  End{:
tP.insertar( x,nparametros); 
nparametros=0;

:};
expresionVar::= listaID dospuntos existenteType {:
:} ;
existenteType::= Integer{: 
tipo="Integer";
  for (int i = 0; i < listadeId.size(); i++) 
    {tV.insertar(listadeId.get(i), tipo);
    listadeId.clear();  }:}
    |Boolean{: 

tipo="Boolean";
  for (int i = 0; i < listadeId.size(); i++) 
    {tV.insertar(listadeId.get(i), tipo);
    listadeId.clear();  }:}
    |Char{: 

tipo="Char";
  for (int i = 0; i < listadeId.size(); i++) 
    {tV.insertar(listadeId.get(i), tipo);
    listadeId.clear();}:}
    |String{:

tipo="String"; 
  for (int i = 0; i < listadeId.size(); i++)  
    {tV.insertar(listadeId.get(i), tipo);
    listadeId.clear();}:}
    |subrangoInt{:

tipo="Integer";
  for (int i = 0; i < listadeId.size(); i++) 
    {tV.insertar(listadeId.get(i), tipo);
    listadeId.clear();} bandera=false;:}
    |subrangoChar{:

tipo="Char";  
  for (int i = 0; i < listadeId.size(); i++) 
    {tV.insertar(listadeId.get(i), tipo);
    listadeId.clear();} bandera=false;
    | ID:a{:

tipo= tT.Buscar(a);
  if (tipo=="-1") {System.out.println("Error tipo no asignado");
     }else{for (int i = 0; i < listadeId.size(); i++) 
     {tV.insertar(listadeId.get(i), tipo);
     listadeId.clear();
   }}:};
listaID::= ID:x {:
    listadeId.add(x);

:} | ID:x coma listaID {:
    listadeId.add(x);
    nparametros=nparametros+1;
:};

Cuerpo::= sentencia  | sentencia  Cuerpo;
sentencias::= Begin Cuerpo End | sentencia  ;
sentencia::= sentIF | sentFor | sentWhile | sentRepeat | asignacion pycoma|llamarMetodo;
llamarMetodo::= ID parametro2  pycoma ;
asignacion::= ID:x dospuntosigual valor
{:

tipoaux=tV.buscar(x);
    if(tipo!=tipoaux){
        System.out.println("Tipos incompatibles "+ x +", "+tipo+","+tV.buscar(x));}
:};

valor ::= ID:x{:tipo=tV.buscar(x);if (tipo=="-1") 
  {System.out.println("No se declaro variable "+ x);}   
           
:}|llamarFuncion |Booleant{:
tipo="Boolean";

:}|Booleanf{:
tipo="Boolean";

:}|subrangoInt{:
tipo="Integer";

:}|subrangoChar{:
tipo="Char";

:}|Int{:
tipo="Integer";

:}|cadena {:
tipo="String";

:}|Char {:
tipo="Char";
:};

llamarFuncion::= ID:x 
  parametro2{:tipo=tF.Buscar(x);
  if (tipo=="-1") {System.out.println("No se declaro variable "+ x);}   
:};

  parametro2::=abrirP listaID cerraP{:
  listadeId.clear();
:}
|abrirP cerraP;

sentIF::= sentIFBASE ;
sentIFBASE::=IF expresionlogica Then sentencias;
sentFor::= FOR asignacion step Int Do sentencias;
step::= To | Downto;
sentWhile::= WHILE expresionlogica Do sentencias;
sentRepeat::= REPEAT Cuerpo Until expresionlogica;
expresionlogica::= Booleant | Booleanf| ID oprelacional ID;