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…')
 
Línea 1: Línea 1:
{{:Usuario:ManuelRomero/compiladores/nav}}
+
{{:Usuario:ManuelRomero/compiladores/AS/nav}}
 
<br>  
 
<br>  
 
==PROGRAMA==
 
==PROGRAMA==
Línea 45: Línea 45:
 
;
 
;
 
</source>
 
</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==
 

Revisión de 11:40 19 ago 2012



PROGRAMA




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
  • Acciones a realizar
  1. Dar de alta el identificador del programa para no volver a usarlo
  2. Después de la última instrucción eliminamos items de la tabla de símbolos
  3. 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
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);
    }
;