Diferencia entre revisiones de «Usuario:ManuelRomero/preferencias/analisisSintacticoSemático»

De WikiEducator
Saltar a: navegación, buscar
(Página creada con '{{:Usuario:ManuelRomero/compiladores/nav}} <br> ==PROGRAMA== <br><br/> {{Resumen|La estructura general de cada producción va a ser: ;Producción ;Atributos ;Acción ;Código Y…')
 
 
(3 revisiones intermedias por el mismo usuario no mostrado)
Línea 1: Línea 1:
{{:Usuario:ManuelRomero/compiladores/nav}}
+
{{:Usuario:ManuelRomero/compiladores/AS/nav}}
 
<br>  
 
<br>  
==PROGRAMA==
+
 
 +
===OBJETIVO===
 +
*Esta parte realizará el análisis sintáctico y semántico  de nuestro programa
 +
*La forma de trabajar será interpretando diferentes producciones y en el momento adecuado validaremos la situación
 +
 
 +
==PLANTILLA UTILIZADA PARA CADA PRODUCCIÓN==
 
<br><br/>
 
<br><br/>
 
{{Resumen|La estructura general de cada producción va a ser:
 
{{Resumen|La estructura general de cada producción va a ser:
Línea 15: Línea 20:
 
*define de qué consta un programa
 
*define de qué consta un programa
 
  programa : tPROGRAMA tIDENTIFICADOR ';' declaracion_variables declaracion_acciones bloque_instrucciones
 
  programa : tPROGRAMA tIDENTIFICADOR ';' declaracion_variables declaracion_acciones bloque_instrucciones
*Acciones a realizar
 
#Dar de alta el identificador del programa para no volver a usarlo
 
#Después de la última instrucción eliminamos items de la tabla de símbolos
 
#Para crear el XML del programa, cada vez que hay un identificador creo un tag diciendo lo que es y lo cierro al final de su ámbito
 
 
<source lang=cpp>
 
programa:
 
    tPROGRAMA tIDENTIFICADOR ';'
 
    {
 
      nivel = 0;
 
      inicializar_tabla (tabsim);
 
      /*El identificador del programa
 
      Es el primer símbolo y por lo tanto seguro
 
      que no va a exixtir, por lo que no lo buscamos*/
 
      introducir_programa(tabsim,$2.NId,0);
 
      AbreTag(xmlin,$2.NId,nivel-1);
 
    }
 
 
    declaracion_variables
 
    declaracion_acciones
 
    bloque_instrucciones
 
    {
 
      eliminar_variables (tabsim, nivel);
 
      eliminar_parametros_ocultos(tabsim,nivel+1);
 
      eliminar_acciones (tabsim, nivel);
 
      eliminar_programa(tabsim);
 
      CierraTag(xmlin,$2.NId,nivel-1);
 
    }
 
;
 
</source>
 
 
==declaracion_variables==
 
*produccion optativa (puede haber o no variables en un programa)
 
*''lista de variables'' que puede tener un programa
 
*Acciones a realizar
 
#ninguna ya que no tenemos ninún terminal solo producciones
 
*Produccion para yacc
 
[[Archivo:declaracionVariables.png]]
 
Vemos que puede estar vacía (épsidon) o que puede contener '''lista de declaraciones''' seguido del token  '''punto y coma'''  ''';'''
 
;Código en yaac
 
declaracion_variables:
 
|    lista_declaraciones ';'
 
;
 
 
==lista_declaraciones==
 
<br><br/>
 
{{Definicion|'''Una lista''' de elementos  uno o varios elementos}}
 
*En este caso va a ser una lista de declaraciones: '''una (declaracion) o varias declaraciones (lista_declaraciones)'''
 
*En yacc siempre usaremos  una recursividad por la izquierda (ver producción)
 
*Acciones a realizar
 
#ninguna ya que no tenemos ningún terminal solo producciones
 
 
<source lang=cpp>
 
  lista_declaraciones ';' declaracion
 
|    declaracion
 
;
 
</source>
 
==declaracion==
 
<br><br/>
 
{{Definicion|'''declaracion de una variable''' es un tipo de variable seguido de una serie de identificadores que representan las variables}}
 
*Una declaracion puede ser de variables simple o un variables compuesta
 
*La forma de daclarar es decir el tipo de variable y luego una lista (1 o mas) de  identificadores
 
*Acciones a realizar
 
#ninguna ya que no tenemos ninún terminal solo producciones
 
;Producción
 
[[imagen:declaracion.png]]
 
;codigo en yacc
 
  variable_simple lista_identificadores
 
|variable_compuesta identificadores_variable_compuesta
 
;
 
 
==variable_simple==
 
;Producción
 
[[imagen:variableSimple.png]]
 
;Atributos
 
%type<tipo> variable_simple
 
<source lang=c>
 
TIPO_VARIABLE tipo;
 
typedef enum {
 
        DESCONOCIDO,
 
        ENTERO,
 
        BOOLEANO,
 
        CHAR,
 
        CADENA,
 
ENUMERATIVO
 
  } TIPO_VARIABLE;
 
</source>
 
;Acción
 
*Asignar al atributo el valor de tipo de variable
 
;Código Yacc
 
<source lang=c>
 
variavariable_simple:
 
    tENTERO{
 
          DEBUGA("variable_simple: tipo entero\n",DVARIABLES,debug);
 
          $$=ENTERO;
 
    }
 
|    tCARACTER{
 
          DEBUGA("variable_simple: tipo caracter\n",DVARIABLES,debug);
 
          $$=CHAR;
 
    }
 
|    tBOOLEANO{
 
          DEBUGA("variable_simple: tipo booleano\n",DVARIABLES,debug);
 
          $$=BOOLEANO;
 
       
 
    }
 
;
 
</source>
 
 
==Lista_identificadores==
 
;Producción
 
[[Image:ListaIdentificadores.png]]
 
;Atributos
 
 
;Acción
 
:Análisis semántico: Verificar que no existe dicho identificador en la tabla de símbolos a ese nivel
 
:Tabla de simbolos: Dar de alta el identificador con el tipo de variable heredado o sintetizado
 
;Código Yacc
 
<source lang=c>
 
lista_identificadores:
 
    tIDENTIFICADOR{
 
        if (($1.PSimbolo==NULL)||($1.PSimbolo->nivel!=nivel)){
 
            char msg[200];
 
            introducir_variable(tabsim,$1.NId,$<tipo>0,nivel,0);
 
           
 
            sprintf(msg,"identificadores:tIDENTIFICADOR ->introducir_variable <%s>",$1.NId);
 
            DEBUGA(msg,DVARIABLES,debug);
 
           
 
        }
 
        else{
 
            char msg[100];
 
            sprintf(msg,"Identificador %s ya utilizado",$1.NId);
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
        }
 
      AbreTag(xmlin,$1.NId,nivel);
 
      CierraTag(xmlin,$1.NId,nivel); 
 
    }
 
|    lista_identificadores ',' tIDENTIFICADOR{
 
        if (($3.PSimbolo==NULL)||$3.PSimbolo->nivel!=nivel){
 
            char msg[200];
 
            introducir_variable(tabsim,$3.NId,$<tipo>0,nivel,0);
 
            sprintf(msg,"identificadores: identificadores ',' tIDENTIFICADOR ->introducir_variable <%s>",$3.NId);
 
            DEBUGA(msg,DVARIABLES,debug);
 
        }
 
        else{
 
            char msg[100];
 
            sprintf(msg,"Identificador %s ya utilizado",$3.NId);
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
        }
 
      AbreTag(xmlin,$3.NId,nivel);
 
      CierraTag(xmlin,$3.NId,nivel); 
 
    }
 
;
 
</source>
 
 
==variable_compuesta==
 
;Producción
 
[[imagen:variableCompuesta.png]]
 
 
*Esta producción es un poco complicada ya que puede darse dos casos en la variable compuesta
 
#Vector
 
#Matriz
 
*Esto lo detectaremos si hay un rango (vector) o si hay dos rangos (matriz)
 
*Vamos a crear la produccion '''resto_variable_compuesta''' la cual puede o no empeza por rango como veremos
 
*Ademas a la produccion '''resto_variable_compuesta''' le vamos a asignar el siguiente atributo atributo
 
;Atributo
 
'''ESTRUCTURA_VECTOR vector'''
 
'''%type <vector> variable_compuesta resto_variable_compuesta'''
 
<source lang=C>
 
typedef struct {
 
      int limiteInferior;
 
      int limiteSuperior;
 
TIPO_VARIABLE tipoIndice;
 
}RANGO_VECTOR;
 
typedef union{
 
        RANGO_VECTOR vector;
 
RANGO_VECTOR matriz[2];
 
}INDEX;
 
typedef struct{
 
TIPO_VARIABLE_COMPUESTA tipoCompuesto;//si es vector o matriz
 
TIPO_VARIABLE tipo;
 
      INDEX indice;
 
}ESTRUCTURA_VECTOR;
 
</source>
 
;Accion
 
*La acción '''{$$=$5;}''' preciamente pasa el valor de dicho atributo de la producción '''' resto_variable_compuesta''' a la producción '''variable_compuesta'''
 
;Código en yacc
 
variable_compuesta:
 
tVECTOR '[' rango']' resto_variable_compuesta{$$=$5;}
 
;
 
==Resto_variable_compuesta==
 
 
;Producción
 
[[imagen:RestoVariableCompuesta.png]]
 
;Atributos
 
*Vemos los mismos que en ''''variable_compuesta''''
 
  '''ESTRUCTURA_VECTOR vector'''
 
'''%type <vector> variable_compuesta resto_variable_compuesta'''
 
 
;Acción
 
*Aqui sabemos si en el ''''resto_variable_compuesta'''' tenemos uno o dos rangos de índices
 
*También sabemos  cuál es el tipo base de la estructura compuesta
 
*Y recogemos el /los rangos y los cargamos en el atributo de la producción
 
*No se detectan errores semánticos
 
;Código Yacc
 
<source lang=C>
 
resto_variable_compuesta:
 
tDE variable_simple
 
                        {
 
$$.tipo=$2;
 
$$.tipoCompuesto=VECTOR;
 
$$.indice.vector=$<indice>-1;
 
//Aqui introduzco la variable compuesta en la tabla de simbolos sabiendo que es vector
 
                        }
 
|'[' rango']'  tDE variable_simple
 
                        {
 
                        $<vector>-1.tipo=$5;
 
//Aqui introduzco la variable compuesta en la tabla de simbolos sabiendo que es matriz
 
$$.indice.matriz[0]=$<indice>-1;
 
$$.indice.matriz[1]=$2;
 
$$.tipoCompuesto=MATRIZ;
 
                        }
 
 
;
 
</source>
 
==rango==
 
;Producción
 
[[imagen:rango.png]]
 
 
*Esta producción va a aportar información de los valores del rango así como de qué tipo son
 
 
;Atributos
 
*Para ello hemos creado el atributo '''indice''' de tipo RANGO_VECTOR cuya composición podemos ver:
 
RANGO_VECTOR indice;
 
%type<indice> rango
 
 
<source lang=c>
 
typedef struct {
 
      int limiteInferior;
 
      int limiteSuperior;
 
TIPO_VARIABLE tipoIndice;
 
}RANGO_VECTOR;
 
</source>
 
 
tipoIndice puede ser '''ENTERO, CARACTER o BOOLEANO'''
 
 
 
;Acciones
 
#Comprobaciones
 
#Almacenar los valores para poderlos llevar a la tabja de símbolos
 
;Comprobaciones
 
*Como vemos el rango especifica dos valores
 
*Aquí hay que hacer comprobaciones, dando error semántico en caso de no ser respetadas
 
#Que los dos valores del rango no sean del mismo tipo  es un error sintáctico (no existe esa producción)
 
#Que el valor izquierdo sea estrictamente menor que el derecho hay que comprobarlo
 
#En caso de haber un sólo valor que sea entero en este caso el límite inferior lo tomaremos como 0 (DUDA A CONSULTAR)
 
;tabla de símbolos
 
*Necesitamos los valores de límite inferior y superior
 
*También necesitamos saber de qué tipo son los índices ('''ENTERO, BOOLEANO, CARACTER''') son los permitidos
 
;Código de yacc con las comprobaciones realizadas es el siguiente
 
<source lang=C>
 
 
rango:  tCONSTENTERA    tPTO tPTO  tCONSTENTERA
 
        {
 
        $$.tipoIndice=ENTERO;
 
          //verificar rangos correctos
 
            if ($1>$4){//Rango incorrecto
 
                char msg[100];
 
                sprintf(msg,"Rango incorrecto %d debe ser menor que %d",$1,$4);
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
                error_semantico(msg);
 
                CuentaErrores();
 
                $$.limiteInferior=$1;
 
                $$.limiteSuperior=$1+1;//Asigno un rango valido
 
          }else{
 
                $$.limiteInferior=$1;
 
                $$.limiteSuperior=$4;
 
          }
 
        }
 
         
 
        | tCONSTCHAR tPTO tPTO tCONSTCHAR
 
       
 
        {
 
          $$.tipoIndice=CHAR;
 
          //verificar rangos correctos
 
  //Verifico caracteres entre 32 y 126
 
  //primero verifico limite inferior
 
          if (($1<32)||($1>125){
 
              char msg[100];
 
      sprintf(msg,"Caracteres limite inferior no permitidos solo de a..z A..Z y no %c",$1);
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
            $$.limiteInferior=32; //Asigno el caracter  'a'  como limite inferior
 
          }else{
 
  $$.limiteInferior=$1;
 
  }
 
  //Ahora verificamos el limite superior
 
 
 
  if (($4<33)||($4>126){
 
              char msg[100];
 
      sprintf(msg,"Caracteres limite superior no permitidos solo de a..z A..Z y no %c",$4);
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
            $$.limiteSuperior=126; //Asigno el caracter  'z'  como limite inferior
 
          }else{
 
  $$.limiteInferior=$1;
 
  }
 
  //Ahora verifico los rangos que el inferior sea mayor que el superior
 
          if ($1>=$4){//Rango incorrecto
 
            char msg[100];
 
            sprintf(msg,"Rango de caracteres incorrecto %c debe ser menor que %c",$1,$4);
 
            /*/Aunque ya esté usado ese identificador, lo incyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
            $$.limiteInferior=$1;
 
            $$.limiteSuperior=$1+1;//Asigno un rango valido
 
          }
 
          else{
 
            $$.limiteInferior=$1;
 
            $$.limiteSuperior=$4;
 
          }
 
        }
 
        | cBooleana tPTO tPTO cBooleana
 
        { 
 
            $$.tipoIndice=BOOLEANO;
 
    if ($1==$4){
 
            char msg[100];
 
            sprintf(msg,"Rango incorrecto, los extremos no pueden tener el mismo valor");
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
            $$.limiteInferior=0;
 
            $$.limiteSuperior=1;//Asigno un rango valido
 
   
 
    }else{
 
                if ($1==tTRUE){
 
                  $$.limiteInferior=1;
 
  $$.limiteSuperior=0;
 
}
 
                else{
 
                  $$.limiteInferior=0;
 
  $$.limiteSuperior=1;
 
  }
 
    }
 
 
        }
 
|tCONSTENTERA{
 
 
$$.tipoIndice=ENTERO;
 
          //verificar rangos correctos
 
  if ($1==0){
 
            char msg[100];
 
                    sprintf(msg,"Indice no puede ser 0 (Cambiamos valor (+1))");
 
            /*Cambio el signo de este limite y continuo*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
                  $$.limiteInferior=0;
 
                    $$.limiteSuperior=1;//Asigno un rango valido
 
          }else{
 
              $$.limiteInferior=0;
 
                      $$.limiteSuperior=$1;
 
  }
 
          }
 
;
 
 
</source>
 
 
==cBooleano==
 
;Producción
 
[[imagen:cBooleano.png]]
 
;Atributos
 
 
'''VALOR_BOOLEANO bool;'''
 
'''%type<bool> cBooleana'''
 
 
<source lang=c>
 
 
#define TRUE            1
 
#define FALSE          0
 
 
typedef enum{
 
        FALSE,
 
TRUE
 
        } VALOR_BOOLEANO;
 
</source>
 
;Acción
 
Asignamos el valor al atributo (ver código yacc)
 
;Código Yacc
 
<source lang=C>
 
cBooleana:
 
        tFALSE
 
        {
 
          $$=tFALSE;
 
        }
 
        |tTRUE         
 
        {$$=tTRUE;
 
        }
 
;
 
</source>
 
 
 
==lista_identificadores_VC==
 
;Producción
 
[[imagen:ListaIdentificadoresVC.png]]
 
;Atributos
 
 
;Acción
 
:Analisis semántica: Verificar que el identificador no existe en este nivel  en la tabla de símbolos
 
;Tabla de simbolos : ''Dar de alta dicho identificador con todos los atributos heredados de Vector/Matriz y rangos correspondientes''
 
Código Yacc
 
<source lang=C>
 
lista_identificadores_VC:
 
    tIDENTIFICADOR{
 
        if (($1.PSimbolo==NULL)||$1.PSimbolo->nivel!=nivel){
 
    if ($<vector>0.tipoCompuesto==VECTOR)
 
                introducir_variable_vector(tabsim,$1.NId,$<vector>0,nivel,0);
 
    else
 
        introducir_variable_matriz(tabsim,$1.NId,$<vector>0,nivel,0);
 
        }
 
        else{
 
            char msg[100];
 
            sprintf(msg,"Identificador %s ya utilizado",$1.NId);
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
        }
 
      AbreTag(xmlin,$1.NId,nivel);
 
      CierraTag(xmlin,$1.NId,nivel); 
 
    }
 
|    lista_identificadores_VC ',' tIDENTIFICADOR{
 
        if (($3.PSimbolo==NULL)||$3.PSimbolo->nivel!=nivel){
 
if ($<dimension>0==VECTOR)
 
                introducir_variable_vector(tabsim,$3.NId,$<vector>0,nivel,0);
 
    else
 
        introducir_variable_matriz(tabsim,$3.NId,$<vector>0,nivel,0);
 
        }
 
        else{
 
            char msg[100];
 
            sprintf(msg,"Identificador %s ya utilizado",$3.NId);
 
            /*/Aunque ya esté usado ese identificador, lo incluyo en XML*/
 
            error_semantico(msg);
 
            CuentaErrores();
 
        }
 
      AbreTag(xmlin,$3.NId,nivel);
 
      CierraTag(xmlin,$3.NId,nivel); 
 
    }
 
;
 
</source>
 
 
==identificadores_variable_compuesta==
 
;Producción
 
[[imagen:IdentificadoresVariableCompuesta.png]]
 
 
== declaracion_acciones==
 
== bloque_instrucciones==
 

Última revisión de 21:40 23 abr 2013



OBJETIVO

  • Esta parte realizará el análisis sintáctico y semántico de nuestro programa
  • La forma de trabajar será interpretando diferentes producciones y en el momento adecuado validaremos la situación

PLANTILLA UTILIZADA PARA CADA PRODUCCIÓN




Icon summary.gif

Resumen

La estructura general de cada producción va a ser:
Producción
Atributos
Acción
Código Yacc
 


  • primera producción
  • Producción obligatoria
  • define de qué consta un programa
programa : tPROGRAMA tIDENTIFICADOR ';' declaracion_variables declaracion_acciones bloque_instrucciones