Usuario:ManuelRomero/preferencias/compiladores/analisisSemático
De WikiEducator
< Usuario:ManuelRomero | preferencias/compiladores
Revisión a fecha de 13:00 18 ago 2012; ManuelRomero (Discusión | contribuciones)
Contenido
PROGRAMA
- primera producción
- Producción obligatoria
- define de qué consta un programa
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
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); } ;
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
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
- 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
lista_declaraciones ';' declaracion | declaracion ;
declaracion
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
- codigo en yacc
variable_simple lista_identificadores |variable_compuesta identificadores_variable_compuesta ;
variable_simple
identificadores
variable_compuesta
- Producción
- 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
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;
- 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
- 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
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; } ;
rango
- Producción
- 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 INDEX:
RANGO_VECTOR indice; %type<indice> rango
typedef struct { int limiteInferior; int limiteSuperior; TIPO_VARIABLE tipoIndice; }RANGO_VECTOR;
INDEX indice
tipoIndice puede ser ENTERO, CARACTER o BOOLEANO
typedef struct { int limiteInferior; int limiteSuperior; TIPO_VARIABLE tipoIndice; }RANGO; typedef union{ RANGO vector; RANGO matriz[2]; }INDEX;
- 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 sean del mismo tipo
- Que el valor izquierdo sea estrictamente menor que el derecho
- 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
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; } } ;
identificadores_variable_compuesta
- Producción
Archivo:IdentificadoresVariableCompuesta.png