Professional Documents
Culture Documents
10320978
11320155
10320918
10320896
Contenido
Introduccin.......................................................................................................... 2
0
INTRODUCCIN................................................................................................... 3
DESARROLLO...................................................................................................... 3
TIPOS DE ERRORES......................................................................................... 5
TRATAMIENTO DE LOS ERRORES LEXICOS.......................................................6
TRATAMIENTO DE ERRORES SINTCTICOS.......................................................7
IGNORAR EL PROBLEMA (PANICMODE)..........................................................7
RECUPERACIN A NIVEL DE FRASE...............................................................7
REGLAS DE PRODUCCIN ADICIONALES PARA EL CONTROL DE ERRORES....8
CORRECCIN GLOBAL..................................................................................8
TRATAMIENTO ERRORES SEMNTICOS............................................................8
COMPROBACIN DE TIPOS............................................................................8
ASPECTOS GENERALES................................................................................8
ESPECIFICACIN DE UN COMPROBADOR DE TIPOS BSICO..........................9
OTRAS COMPROBACIONES SEMNTICAS Y RECUPERACIN DE ERRORES SEMNTICOS
Introduccin
El proceso de la compilacin se desglosa en dos partes: la parte que depende solo del lenguaje fuente
(etapa inicial o front-end) y la parte que depende solo del lenguaje objeto (etapa final o back-end).
1
La etapa inicial traduce un programa fuente a una representacin intermedia s partir de la cual la etapa
final genera el cdigo objeto. De esta forma, los detalles que tienen que ver con las caractersticas del
lenguaje objeto (cdigo ensamblador, cdigo maquina absoluto o relocalizable,...), la arquitectura de la
maquina (nmero de registros, modos de direccionamiento, tamao de los tipos de datos, memoria
cache,...), el entorno de ejecucin (estructura de registros y memoria de la mquina donde se va a
ejecutar el programa...) y el sistema operativo se engloban en la etapa final y se aslan del resto.
El cdigo intermedio es un cdigo abstracto independiente de la mquina para la que se generar el
cdigo objeto. El cdigo intermedio ha de cumplir dos requisitos importantes: ser fcil de producir a partir
del anlisis sintctico, y ser fcil de traducir al lenguaje objeto.
Con una representacin intermedia bien definida, un compilador para el lenguaje i y la maquina j puede
ser construido combinando el front-end para el lenguaje i con el back-end de la maquina j. De esta
manera se pueden construir m*n compiladores escribiendo nicamente m front-ends y n back-ende.
Acciones posibles
Detectar errores
Informar de los errores
Recuperar de los errores
Corregir errores
DESARROLLO
A continuacin se muestra un fragmento de cdigo de un mtodo de la clase Errores escrito en C++, para
el tratamiento de errores sintcticos. En el caso que se presenta cada vez que se encuentra un error el
compilador se detiene, y finaliza el proceso.
errores provocarn un evento apropiado durante la ejecucin. El ms simple de tales eventos ser
detener la ejecucin del programa. Sin embargo, a menudo esto no es adecuado, y una definicin de
lenguaje puede requerir la presencia de mecanismos para el manejo de excepciones. stos pueden
complicar sustancialmente la administracin de un sistema de ejecucin, especialmente si un programa
puede continuar ejecutndose desde el punto donde ocurri el error.
Ejemplo
VAR
ch : CHAR; (* Un identificador no se puede utilizar si *)
ent: INTEGER; (* previamente no se ha definido. *)
...
ch := ent + 1; (* En Pascal no es vlido, en C s. *)
TIPOS DE ERRORES
Tipos de errores que suelen ocurrir (dependiendo de la fase):
Lxicos: No concuerda con ninguna ER.
Ejemplo: escribir mal una palabra
Sintcticos: La estructura que se ha seguido no es correcta.
Ejemplo: expresin con parntesis no emparejados.
Semnticos: La estructura est bien pero hay errores de significado
Ejemplo: operador y operando incompatibles.
Lgicos: Los comete el programador
Ejemplo: una llamada infinitamente recursiva
4
Algunos errores se pueden detectar en compilacin otros solo en ejecucin. El tratamiento de errores es
una parte importante que se suele descuidar.
TRATAMIENTO DE LOS ERRORES LEXICOS
Un traductor debe adoptar alguna estrategia para detectar, informar y recuperarse para seguir analizando
hasta el final.
Las respuestas ante el error pueden ser:
Inaceptables: Provocadas por fallos del traductor, entrada en lazos infinitos, producir resultados
errneos, y detectar slo el primer error y detenerse.
Aceptables: Evitarla avalancha de errores (mala recuperacin) y, aunque ms complejo, informar y
reparar el error de forma automtica. La conducta de un Analizador de Lxico es el de un
Autmata finito o scanner.
Deteccin del error: El analizador de Lxico detecta un error cuando no existe transicin desde el
estado que se encuentra con el smbolo de la entrada. El smbolo en la entrada no es el esperado.
Los errores lxicos se detectan cuando el analizador lxico intenta reconocer componentes lxicos y la
cadena de caracteres de la entrada no encaja con ningn patrn. Son situaciones en las que usa un
carcter invalido (@,$,",>,...), que no pertenece al vocabulario del lenguaje de programacin, al escribir
mal un identificador, palabra reservada u operador.
Errores lxicos tpicos son:
Nombre ilegales de identificadores: un nombre contiene caracteres invlidos.
Nmeros incorrectos: Un numero contiene caracteres invlidos o no est formado correctamente, por
ejemplo 3,14 en vez de 3.14 o 0.3.14.
Errores de ortografa en palabras reservadas: caracteres omitidos, adicionales o cambiados de sitio,
por ejemplo la palabra while en vez de hwile.
Fin de archivo: se detecta un fin de archivo a la mitad de un componente lxico.
Los errores lxicos se deben a descuidos del programador. En general, la recuperacin de errores lxicos
es sencilla y siempre se traduce en la generacin de un error de sintaxis que ser detectado ms tarde
por el analizador sintctico cuando el analizador lxico devuelve un componente lxico que el analizador
sintctico no espera en esa posicin.
Los mtodos de recuperacin de errores lxicos se basan bien en saltarse caracteres en la entrada hasta
que un patrn se ha podido reconocer; o bien usar otros mtodos ms sofisticados que incluyen la
insercin, borrado, sustitucin de un carcter en la entrada o intercambio de dos caracteres consecutivos.
Una buena estrategia para la recuperacin de errores lxicos:
Universidad Nacional del Santa Curso: Teora de Compiladores
Si en el momento de detectar el error ya hemos pasado por algn estado final ejecutamos la
accin correspondiente al ltimo estado final visitado con el lexema formado hasta que salimos
de l; el resto de caracteres ledos se devuelven al flujo de entrada y se vuelve al estado inicial;
Si no hemos pasado por ningn estado final, advertimos que el carcter encontrado no se
esperaba, lo eliminamos y proseguimos con el anlisis.
TRATAMIENTO DE LOS ERRORES SINTACTICOS
Indicar los errores de forma clara y precisa. Aclarar el tipo de error y su localizacin.
Recuperarse del error, para poder seguir examinando la entrada.
No ralentizar significativamente la compilacin.
Un buen compilador debe hacerse siempre teniendo tambin en mente los errores que se pueden
producir; con ello se consigue:
Parecida que s se pueda reconocer. Es decir, el analizador sintctico le pide toda la secuencia de tokens
al lxico, y lo que hace es devolver lo ms parecido a la cadena de entrada pero sin errores, as como el
rbol que lo reconoce.
Solo nos hemos centrado en las comprobaciones de tipo. Las otras son cierto modo rutinarias y se
pueden realizar fcilmente insertando acciones intercaladas en el cdigo para realizarlas, por eje.
Cuando se introduce un identificador en la Tabla de Smbolos.
ma forma que el de los identificadores ya que el mecanismo que hemos utilizado para registrar su tipo durante e
Llamadas a funcin
Externa
3._Lista de las reglas para la conversin de tipos (casting) en expresiones con tres ejemplos por
cada regla
ncillo an que en el caso de los literales ya que nos basaremos directamente en el tipo almacenado en la tabla
Una declaracin de operador de conversin introduce una conversin definida por el usuario que
aumenta las conversiones implcitas y explcitas predefinidas.
Una declaracin de operador de conversin que incluye la palabra clave implicit define una conversin
implcita definida por el usuario. Las conversiones implcitas pueden ocurrir en distintas situaciones,
incluyendo las invocaciones de miembros de funcin, las expresiones de conversin y las asignaciones.
Una declaracin de operador de conversin que incluye la palabra clave explicit define una conversin
explcita definida por el usuario. Las conversiones explcitas pueden ocurrir en las expresiones de
conversin.
Un operador de conversin convierte de un tipo origen, indicado por el tipo del parmetro del operador de
conversin, a un tipo destino, indicado por el tipo del valor devuelto del operador de conversin. Una
clase o estructura puede declarar una conversin de un tipo origen S a un tipo destino T si se cumple
Identificadores
todo lo siguiente:
De la segunda regla se deriva que un operador de conversin debe convertir a o del tipo de la clase o
estructura en la que se declara el operador. Por ejemplo, es posible que un tipo de clase o de estructura
C defina una conversin de C a int y de int a C, pero no de int a bool.
No es posible volver a definir una conversin predefinida. Por lo tanto, no est permitido utilizar
operadores de conversin para convertir de o a object porque ya existen conversiones implcitas y
explcitas entre object y el resto de tipos. Adems, ni el tipo de origen ni el de destino de una conversin
puede ser un tipo base del otro, porque entonces ya existira una conversin.
Las conversiones definidas por el usuario no pueden convertir de o a tipos-de-interfaz. Esta restriccin
impide, en particular, que se produzcan transformaciones definidas por el usuario cuando se convierte a
un tipo-de-interfaz, y asegura que una conversin a un tipo-de-interfaz se ejecute correctamente slo si el
objeto que se est convirtiendo implementa realmente el tipo-de-interfaz especificado.
La firma de un operador de conversin est formado por el tipo de origen y el tipo de destino (sta es la
nica forma de miembro en la que el tipo de valor devuelto participa en la firma). La clasificacin implicit o
explicit de un operador de conversin no forma parte de la firma del operador. Por lo tanto, una clase o
una estructura no puede declarar a la vez operadores de conversin implicit y explicit con los mismos
tipos de origen y destino.
10
En general, las conversiones implcitas definidas por el usuario deben disearse para que nunca
produzcan excepciones ni pierdan informacin. Si una conversin definida por el usuario puede dar lugar
a excepciones (por ejemplo, debido a que el argumento de origen est fuera del intervalo) o a prdida de
informacin (como descartar los bits de mayor orden), dicha conversin debera definirse como explcita.
En el ejemplo
usingSystem;
publicstruct Digit
{
byte value;
public Digit(byte value) {
if (value < 0 || value > 9) throw new ArgumentException();
this.value = value;
}
public static implicit operator byte(Digit d) {
returnd.value;
}
public static explicit operator Digit(byte b) {
return new Digit(b);
}
omo consultar
el tipo de token devuelto por el analizador sintctico y asignar directamente un tipo u otro en la
}
11
Literales
La conversin de Digit a byte es implcita porque nunca produce excepciones o pierde informacin, pero
la conversin de byte a Digites explcita ya que Digit slo puede representar un subconjunto de los
posibles valores de un byte.
Conversiones implcitas
La mayora de las conversiones, como la asignacin de un valor a una variable, se producen
automticamente. El tipo de datos de la variable determina el tipo de datos de destino de la conversin de
expresin.
En el ejemplo siguiente se muestra una conversin de datos implcita entre un valor int, un valor String y
un valor double.
vari : int;
var d : double;
var s : String;
i = 5;
s = i; // Widening: the int value 5 coverted to the String "5".
d = i; // Widening: the int value 5 coverted to the double 5.
s = d; // Widening: the double value 5 coverted to the String "5".
El clculo y chequeo de tipos de una expresin.
Cuando se compila este cdigo, pueden aparecer advertencias en tiempo de compilacin para informar
de que las conversiones de restriccin pueden producir errores o ser muy lentas.
Puede ocurrir que las conversiones de restriccin implcitas no funcionen si la conversin requiere una
prdida de informacin. Por ejemplo, las siguientes lneas no funcionarn:
var i : int;
asignar ste a su nodo del rbol.
var f : float;
var s : String;
f = 3.14;
Quizs te hayas preguntado qu pasa cuando escribimos expresiones numricas en las que no todos los
operandos son del mismo tipo. Por ejemplo:
char n;
int a, b, c, d;
float r, s, t;
...
a = 10;
b = 100;
r = 1000;
c = a + b;
s = r + a;
d = r + b;
d = n + a + r;
t = r + a - s + c;
...
En estos casos, cuando los operandos de cada operacin binaria asociados a un operador son de distinto
tipo, el compilador los convierte a un tipo comn. Existen reglas que rigen estas conversiones, y aunque
pueden cambiar ligeramente de un compilador a otro, en general sern ms o menos as:
1.
Cualquier tipo entero pequeo como char o short es convertido a int o unsignedint. En este punto
cualquier pareja de operandos ser int (con o sin signo), long, longlong,double, float o longdouble.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CONVERSIONES A BOOL
En C++ podemos hablar de otro tipo de conversin de tipo implcita, que se realiza cuando se usa
cualquier expresin entera en una condicin, y ms generalmente, cuando se usa cualquier expresin
donde se espera una expresin booleana.
El dominio del tipo bool es muy limitado, ya que slo puede tomar dos valores: true y false. Por convenio
se considera que el valor cero es false, y cualquier otro valor entero es true.
Por lo tanto, hay una conversin implcita entre cualquier entero y el tipo bool, y si aadimos esta regla a
las explicadas antes, cualquier valor double, longdouble, float o cualquiera de los enteros, inclusochar, se
puede convertir a bool.
Esto nos permite usar condiciones abreviadas en sentencias if, for, while o do..while, cuando el valor a
comparar es cero.
14
Conversiones explcitas
Para convertir explcitamente una expresin a un tipo de datos concreto, utilice el identificador de tipo de
datos seguido de la expresin que se va a convertir entre parntesis. Las conversiones explcitas
requieren ms escritura que las implcitas, pero proporcionan ms seguridad con respecto a los
resultados. Adems, las conversiones explcitas pueden controlar conversiones con prdida de
informacin.
En el ejemplo siguiente se muestra una conversin de datos explcita entre un valor int, un valor String y
un valor double.
vari : int;
var d : double;
var s : String;
i = 5;
s = String(i); // Widening: the int value 5 coverted to the String "5".
d = double(i); // Widening: the int value 5 coverted to the double 5.
15
i = int(s);
En C++ hay varios tipos diferentes de casting, pero de momento veremos slo el que existe tambin en
C.
Un casting tiene una de las siguientes sintaxis:
16
(<nombre de tipo>)<expresin>
<nombre de tipo>(<expresin>)
Esta ltima es conocida como notacin funcional, ya que tiene la forma de una llamada a funcin.
En el ejemplo anterior, las lneas 3 y 4 quedaran:
d = (int)(r + b);
d = (int)(n + a + r);
O bien:
d = int(r + b);
d = int(n + a + r);
Hacer un casting indica que sabemos que el resultado de estas operaciones no es un int, que la variable
receptora s lo es, y que lo que hacemos lo estamos haciendo a propsito. Veremos ms adelante,
cuando hablemos de punteros, ms situaciones donde tambin es obligatorio el uso de casting.
17
les pueda aplicar dicho operador. Si B y C son enteros o reales los sumar, si son cadenas las
concatenar y si son conjuntos calcular su unin.
Dependiendo del tipo de sentencias, las acciones semnticas pueden agruparse en:
Accin semntica
Sentencias de Declaracin
Descripcin
Completar la seccin de tipos de la
Tabla de Smbolos.
Sentencias ejecutables
Funciones y procedimientos
Identificacin de variables
Etiquetas
Constantes
Detectar y solventar.
18
Introduccin
Los campos de cada entrada en la tabla de smbolos corresponden a los atributos de cada identificador.
(Tipo, valor, direccin, parmetros, etc.).
Durante la compilacin de un programa, cada vez que se encuentra un identificador en la tabla de
smbolos, se puede realizar lo siguiente:
La tabla puede ser consultada para ver si es necesario dar de alta el nuevo identificador.
En la tabla se puede completar los atributos faltantes de un identificador ya existente.
Se puede recuperar los atributos de un identificador ya existente en la tabla de smbolos.
Un mecanismo de tabla de smbolos debe permitir aadir nuevas entradas y encontrar las entradas
existentes de un analizador lxico eficiente.
Los dos mecanismos para tablas de smbolos presentados a continuacin son listas lineales y tablas de
dispersin. Cada uno de estos mecanismos se evala basndose en el tiempo necesario para aadir n
entradas y realizar e consultas.
Una lista Lineal es lo ms fcil de implantar, pero su rendimiento es pobre cuando e y n se vuelven ms
grandes.
Las tablas de dispersin proporcionan un mayor rendimiento con esfuerzo algo mayor de programacin y
gasto de espacio.
Ambos mecanismos pueden adaptarse rpidamente para funcionar las reglas del anidamiento ms
cercano.
Un compilador debe ser capaz de aumentar dinmicamente la tabla de simbolos durante la complicacin.
Si la tabla de smbolos tiene tamao fijo al escribir el compilador, entonces el tamao debe ser lo
suficientemente grande como para almacenar cualquier programa fuente.
Es muy probable que dicho tamao sea demasiado grande para la mayora de los programas e
inadecuacin para algunos.
Para mantener uniformes los registros de la tabla de smbolos, es conveniente guardar una parte de la
informacin de un nombre fuera de la entrada de la tabla, almacenado en el registro solo un apuntador a
esta informacin, para hacer referencia a l.
Administracin de la Tabla de Smbolos.
Cada entrada de la tabla de smbolos corresponde a la declaracin de un nombre. El formato de las
entradas no tiene que ser uniforme porque la informacin de un nombre depende del uso de dicho
nombre.
Cada entrada se puede implantar como un registro que conste de una secuencia de palabras
consecutivas de memoria. No toda la informacin se introduce en la tabla de smbolos.
20
Las palabras clave se introducen, al inicio. El analizador lxico busca secuencias de letras y dgitos en la
tabla de smbolos para determinar si se ha encontrado una palabra clave o un nombre.
Una tabla de smbolos separada en dos partes, utilizando una parte como apuntador a dicha tabla para
hacer referencia a los nombres almacenados en ella.
Las palabras clave deben estar en la tabla de smbolos antes de que comience el anlisis lxico.
Si el analizador lxico reconoce las palabras clave, entonces no necesitan aparecer en la tabla de
smbolos.
Si el lenguaje no convierte en palabras reservadas entonces es indispensable que las palabras clave se
introduzcan en la tabla de smbolos advirtiendo su posible uso como palabras clave.
La entrada misma de la tabla de smbolos puede establecerse cuando se aclara el papel de un nombre, y
se llenan los valores de los atributos cuando se dispone de la informacin.
En algunos casos, el analizador lxico puede iniciar la entrada en cuanto aparezca un nombre en los
datos de entrada.
Operaciones con la Tabla de Smbolos.
En general en la Tabla de smbolos (TS a partir de ahora) se realizan dos operaciones: la insercin y la
bsqueda.
En C la operacin de insercin se realiza cuando se procesa una declaracin.
Hay dos posibilidades: que la TS est ordenada (o sea, nombres de variables por orden alfabtico) o que
no est ordenada.
Si est ordenada, entonces la operacin de insercin llama a un procedimiento de bsqueda para
encontrar el lugar donde colocar los atributos del identificador a insertar, por lo que en este caso la
insercin lleva tanto tiempo como la bsqueda. En cambio, si no est ordenada la TS, la insercin se
simplifica mucho aunque se complica la bsqueda, pues debe examinar toda la tabla.
En la bsqueda, se detectan los identificadores que no hayan sido declarados previamente, emitiendo un
mensaje de error.
ejemplo en lenguaje C: Undefined smbolo 'x', si es una variable que desea usarse pero no se
declar.
21
Un nombre puede indicar varios objetos distintos, quizs incluso en el mismo bloqueo o procedimiento.
Por ejemplo, las declaraciones en C.
Int x;
Struct x ( float y, z;);
Utilizan x como entero y como etiqueta de una estructura con dos campos.
En ambos casos, el analizador lxico solo puede devolver al analizador sintctico el nombre solo (o un
apuntador al lexema que forma dicho nombre), en lugar de un apuntador a la entrada en la tabla de
smbolos.
Analizador Sintctico(Parser)
Sintaxis: El orden correcto de las palabras
Ej. Programa Fuente: 34:= *x - 640;
Analex: NUM ASIGN POR ID MENOS NUM PTOCOMA
Parser: "Error Sintctico"
El Analizador semntico.
Semntica: Significado de las frases.
Estando una frase del programa fuente ya analizada sintcticamente ("parseada") pasa al analizador
semntico para verificar la intencin del programador con esa frase: "Pas por el parser y no present
errores".
Ejemplo:
22
byte b;
int v[3];
String s;//Error semntico
b = 4000; //out of range
s = 6000; //incompatible type's o "Type mismatch"
v[8]= 12; // out of range
Se crea el registro en la tabla de smbolos cuando se descubre el papel sintctico que desempea este
nombre.
Para las declaraciones de la expresin se crearan dos entradas en la tabla de smbolos para x; una con
x como entero y otra como estructura.
Los atributos de un nombre se introducen en respuesta a las declaraciones, que pueden ser implcitas.
Las etiquetas son identificadores seguidos de dos puntos, asi que una accin asociada con el
reconocimiento de dicho identificador puede ser introducir este hecho en la tabla de smbolos.
La sintaxis de las declaraciones de los procedimientos especifica que algunos identificadores son
parmetros formales.
23
24
CONCLUSIN:
Es mucho ms difcil introducir mtodos formales para la recuperacin de errores semnticos que para la
recuperacin de errores sintcticos, ya que a menudo la recuperacin de errores semnticos es ad hoc.
No obstante, puede requerirse que, por lo menos, el error semntico sea informado al programador, que
se le ignore y que, por tanto, se suprimir la generacin de cdigo.
25
Sin embargo, la mayora de los errores semnticos pueden ser detectados mediante la revisin de la
tabla de smbolos, suponiendo un tipo que se base en el contexto donde ocurra o un tipo universal que
permita al identificador ser un operando de cualquier operador del lenguaje. Al hacerlo, evitamos la
produccin de un mensaje de error cada vez que se use la variable no definida. Si el tipo de un operando
no concuerda con los requisitos de tipo del operador, tambin es conveniente reemplazar el operando
con una variable ficticia de tipo universal.
Bibliografa
Cidecame. (s.f.). Errores de compilacion. Obtenido de
http://cidecame.uaeh.edu.mx/lcc/mapa/PROYECTO/libro32/autocontenido/autocon/45__errores_se
mnticos.html
compiladores. (2011). Biblioteca uns. Obtenido de
http://biblioteca.uns.edu.pe/saladocentes/archivoz/publicacionez/sesion_v_3u___tratamiento_de_e
rrores.pdf
Louden., K. C. (noviembre de 2013). Construccin de compiladores Principios y prctica. Obtenido de Ed.
Thomson.
Microsoft. (febrero de 2014). Conversion de tipo de datos . Obtenido de https://msdn.microsoft.com/eses/library/vstudio/hdz2a0he(v=vs.100).aspx
Microsoft. (Marzo de 2014). Reconocimiento de datos . Obtenido de https://msdn.microsoft.com/eses/library/aa691370(v=vs.71).aspx
26