Diferencia entre revisiones de «Usuario:ManuelRomero/preferencias/compiladores/analisisSemático»
Línea 132: | Línea 132: | ||
;Código de yacc con las comprobaciones realizadas es el siguiente | ;Código de yacc con las comprobaciones realizadas es el siguiente | ||
<source lango=CPP> | <source lango=CPP> | ||
+ | rango: tCONSTENTERA tPTO tPTO tCONSTENTERA | ||
+ | |||
+ | { | ||
+ | //Verifico que sean positivas | ||
+ | if ($1<0){ | ||
+ | char msg[100]; | ||
+ | sprintf(msg,"Indice incorrecto %d debe ser positivo (Cambiamos signo)",$1); | ||
+ | /*Cambio el signo de este limite y continuo*/ | ||
+ | error_semantico(msg); | ||
+ | $1=-$1; | ||
+ | CuentaErrores(); | ||
+ | } | ||
+ | if ($4<0){ | ||
+ | char msg[100]; | ||
+ | sprintf(msg,"Indice incorrecto %d debe ser positivo(Cambiamos signo)",$4); | ||
+ | /*Cambio el signo de este limite y continuo*/ | ||
+ | error_semantico(msg); | ||
+ | $4=-$4; | ||
+ | CuentaErrores(); | ||
+ | } | ||
+ | $$.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 | ||
+ | $$.tipoIndice=ENTERO; | ||
+ | }else{ | ||
+ | $$.limiteInferior=$1; | ||
+ | $$.limiteSuperior=$4; | ||
+ | $$.tipoIndice=ENTERO; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | | tCONSTCHAR tPTO tPTO tCONSTCHAR | ||
+ | |||
+ | { | ||
+ | $$.tipoIndice=CHAR; | ||
+ | //verificar rangos correctos | ||
+ | if (($1<32)||($4>126)){//Verifico caracteres entre 32 y 126 | ||
+ | char msg[100]; | ||
+ | |||
+ | } | ||
+ | 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 incluyo 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 incorrecto %d debe ser positivo (Cambiamos signo)",$1); | ||
+ | /*Cambio el signo de este limite y continuo*/ | ||
+ | error_semantico(msg); | ||
+ | $1=-$1; | ||
+ | CuentaErrores(); | ||
+ | $$.limiteInferior=0; | ||
+ | $$.limiteSuperior=$1;//Asigno un rango valido | ||
+ | }else{ | ||
+ | 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> | </source> | ||
Revisión de 13:47 17 ago 2012
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
- 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)
- Producción
- codigo en yacc
variable_compuesta: tVECTOR '[' rango']' resto_variable_compuesta{$$=$5;} ;
- Vamos a crear la produuccion resto_variable_compuesta la cual puede o no empeza por rango como veremos
- Ademas a la produccion resto_variable_compuesta le vamos a asignar un atributo TIPO_VARIABLE_COMPUESTA
typedef enum{ VECTOR, MATRIZ };TIPO_VARIABLE_COMPUESTA
- para poder saber si es VECTOR O MATRIZ necesitamos propagar dicho atributo de TIPO_VARIABLE_COMPUESTA, por lo que la proudccuín variable_compuesta también tiene dicho atributo
- 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
rango
- Esta producción va a aportar información que debemos almacenar en la tabla de simbolos,
- El problema que ya conocemos es que hasta que no tengamos el identificador de la variable que va a tener este rango no lo podemos hacer, así que hay que porpagar esto con atributos heredados.
- Producción
- 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
- Para ello hemos creado el atributo indice de tipo INDEX:
typedef struct { int limiteInferior; int limiteSuperior; TIPO_VARIABLE tipoIndice; }RANGO; typedef union{ RANGO vector; RANGO matriz[2]; }INDEX;
- Código de yacc con las comprobaciones realizadas es el siguiente
Idioma no válido.
Necesita especificar un idioma como esto: <source lang="html4strict">...</source>
lenguajes soportados para sintaxis remarcada:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, arm, asm, asp, asymptote, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcl, dcpu16, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, nagios, netrexx, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, octave, oobas, oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, pys60, python, q, qbasic, rails, rebol, reg, rexx, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, spark, sparql, sql, stonescript, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vedit, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic
rango: tCONSTENTERA tPTO tPTO tCONSTENTERA { //Verifico que sean positivas if ($1<0){ char msg[100]; sprintf(msg,"Indice incorrecto %d debe ser positivo (Cambiamos signo)",$1); /*Cambio el signo de este limite y continuo*/ error_semantico(msg); $1=-$1; CuentaErrores(); } if ($4<0){ char msg[100]; sprintf(msg,"Indice incorrecto %d debe ser positivo(Cambiamos signo)",$4); /*Cambio el signo de este limite y continuo*/ error_semantico(msg); $4=-$4; CuentaErrores(); } $$.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 $$.tipoIndice=ENTERO; }else{ $$.limiteInferior=$1; $$.limiteSuperior=$4; $$.tipoIndice=ENTERO; } } | tCONSTCHAR tPTO tPTO tCONSTCHAR { $$.tipoIndice=CHAR; //verificar rangos correctos if (($1<32)||($4>126)){//Verifico caracteres entre 32 y 126 char msg[100]; } 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 incluyo 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 incorrecto %d debe ser positivo (Cambiamos signo)",$1); /*Cambio el signo de este limite y continuo*/ error_semantico(msg); $1=-$1; CuentaErrores(); $$.limiteInferior=0; $$.limiteSuperior=$1;//Asigno un rango valido }else{ 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