Sunteți pe pagina 1din 33

TECNOLGICO NACIONAL DE MXICO

INSTITUTO TECNOLGICO DE ACAPULCO

Educacin tecnolgica con compromiso social

INGENIERA EN SISTEMAS COMPUTACIONALES

ASIGNATURA

Lenguajes y autmatas II

UNIDAD 1 ANLISIS SEMNTICO

Disea mediante el uso de reglas


Competencia especfica de la semnticas dirigidas por sintaxis, un
unidad analizador semntico para un
compilador.

Profesor: Silvestre Bedolla Solano.

Equipo: 5

lvarez Rodrguez Jos Francisco 13320812


Cortes Chvez Ulises 13320845
Ramos Teconalapa Lidia Lorena 14320115
Nava Santana Rigoberto de Jesus
Master

1
ndice

INTRODUCCIN ................................................................................................................................... 3
REPORTE DE LA DETECCIN Y RECUPERACIN DE ERRORES SEMNTICOS ....................................... 4
CUADRO SINPTICO DONDE SE DESCRIBA EL MANEJO DE TIPOS EN LAS EXPRESIONES Y EL USO DE
OPERADORES..................................................................................................................................... 10
LISTA DE LAS REGLAS PARA LA CONVERSIN DE TIPOS (CASTING) EN EXPRESIONES, DONDE
EXPLIQUE TRES EJEMPLOS POR CADA REGLA ................................................................................... 12
TABLA DONDE SE DESCRIBAN LAS ACCIONES SEMNTICAS A LA ESTRUCTURA DE LA GRAMTICA 24
REPORTE DE LA MANIPULACIN DE LA TABLA DE CONVERSIN DE SMBOLOS Y DE DIRECCIONES26
PROPUESTA DE PROYECTO FINAL ..................................................................................................... 33
CONCLUSIN DE LA UNIDAD............................................................................................................. 33
BIBLIOGRAFA .................................................................................................................................... 33

Detectar errores semnticos.


Disear y seleccionar informacin sobre la
construccin de un analizador semntico.
Reconocer el manejo de tipos en las
expresiones y el uso de operadores.
Establecer las reglas para la conversin de
tipos (casting) en expresiones.
Agregar acciones semnticas a la estructura
de la gramtica.
Manipular la tabla de conversin de smbolos
y de errores y direcciones.
Integrar equipos de trabajo para la
construccin de un analizador semntico.

2
INTRODUCCIN

El Anlisis Semntico es aqul que estudia a las palabras en funcin de su


significado. Se trata de determinar el tipo de los resultados intermedios, comprobar
que los argumentos que tiene un operador pertenecen al conjunto de los operadores
posibles, y si son compatibles entre s, etc. En definitiva, comprobar que el
significado de lo que se va leyendo es vlido. Se compone de un conjunto de rutinas
independientes, llamadas por los analizadores morfolgico y sintctico.

El anlisis semntico utiliza como entrada el rbol sintctico detectado por el anlisis
sintctico para comprobar restricciones de tipo y otras limitaciones semnticas y
preparar la generacin de cdigo. En compiladores de un solo paso, las llamadas
a las rutinas semnticas se realizan directamente desde el analizador sintctico y
son dichas rutinas las que llaman al generador de cdigo. El instrumento ms
utilizado para conseguirlo es la gramtica de atributos.

En compiladores de dos o ms pasos, el anlisis semntico se realiza


independientemente de la generacin de cdigo, pasndose informacin a travs
de un archivo intermedio, que normalmente contiene informacin sobre el rbol
sintctico en forma linealizada (para facilitar su manejo y hacer posible su
almacenamiento en memoria auxiliar).

En cualquier caso, las rutinas semnticas suelen hacer uso de una pila (la pila
semntica) que contiene la informacin semntica asociada a los operandos (y a
veces a los operadores) en forma de registros semnticos.

3
REPORTE DE LA DETECCIN Y RECUPERACIN DE ERRORES
SEMNTICOS

INTRODUCCIN

Un error semntico se produce cuando la sintaxis del cdigo es correcta, pero la


semntica o significado no es el que se pretenda. La construccin obedece las
reglas del lenguaje, y por ello el compilador o intrprete no detectan los errores
semnticos. Los compiladores e intrpretes slo se ocupan de la estructura del
cdigo que se escribe, y no de su significado. Un error semntico puede hacer que
el programa termine de forma anormal, con o sin un mensaje de error. Hablando en
trminos coloquiales, puede hacer que el equipo se quede "colgado".

Este tipo de errores es muy frecuente en los alumnos. Su origen est en la


incomprensin de los trminos que se utilizan en las explicaciones o en las
instrucciones de las tareas, en la confusin entre las connotaciones de las palabras
que usamos, en uso de sinnimos que son interpretados como conceptos distintos,
en lo farragoso de algunas descripciones, en el exceso de sntesis de muchas
definiciones y explicaciones que, paradjicamente, incrementa la densidad del
mismo, etc.

Bueno esto quiere decir que los Errores semnticos son ms que nada errores que
cometen las personas, al momento de trabajar ya que la computadora no tiene
pensamiento propio solo acata las reglas por las que fue diseo y su protocolo. El
computador trabaja revisando la sintaxis y la estructura del programa mas no la
lgica.

La fase de anlisis semntico de un procesador de lenguaje es aqulla que computa


la informacin adicional necesaria para el procesamiento de un lenguaje, una vez
que la estructura sintctica de un programa haya sido obtenida. Es por tanto la fase
posterior a la de anlisis sintctico y la ltima dentro del proceso de sntesis de un
lenguaje de programacin.

4
MARCO TEORICO

El trmino semntica se refiere a los aspectos del significado, sentido o


interpretacin de signos lingsticos como smbolos, palabras, expresiones o
representaciones formales. En principio cualquier medio de expresin (lenguaje
formal o natural) admite una correspondencia entre expresiones de smbolos o
palabras y situaciones o conjuntos de cosas que se encuentran en el mundo fsico
o abstracto que puede ser descrito por dicho medio de expresin.

La semntica puede estudiarse desde diferentes puntos de vista:

Semntica lingstica, trata de la codificacin y decodificacin de los


contenidos semnticos en las estructuras lingsticas.
Semntica lgica, desarrolla una serie de problemas lgicos de significacin,
estudia la relacin entre el signo lingstico y la realidad. Las condiciones
necesarias para que un signo pueda aplicarse a un objeto, y las reglas que
aseguran una significacin exacta.
Semntica en ciencias cognitivas, intenta explicar por qu nos comunicamos,
y cul es el mecanismo psquico que se establece entre hablante y oyente
durante este proceso.

Un error de software, comnmente conocido como bug (bicho), es un error o fallo


en un programa de computador o sistema de software que desencadena un
resultado indeseado. Los programas que ayudan a la deteccin y eliminacin de
errores de programacin de software son denominados depuradores (debuggers).

El anlisis semntico determina el tipo de los resultados intermedios, comprueba


los argumentos que tiene un operador pertenece al conjunto de los operadores
posibles y si son compatibles entre s, etc. En definitiva, comprueba que el
significado de lo que se va leyendo es vlido.

Los errores semnticos corresponden a la semntica del lenguaje de programacin,


la cual normalmente no est descrita por la gramtica. Los errores semnticos ms
comunes son la omisin de declaraciones.

5
DESARROLLO

Los errores que puede detectar el analizador sintctico son aquellos que violan las
reglas de una gramtica independiente del contexto. Ya hemos mencionado que
algunas de las caractersticas de un lenguaje de programacin no pueden
enunciarse con reglas independientes del contexto, ya que dependen de l; por
ejemplo, la restriccin de que los identificadores deben declararse previamente. Por
lo tanto, los principales errores semnticos son:

Conversiones de tipos no permitidas

int x;

x = 4.32;

Error: Ej1.java [6:1] possible loss of precision

Variables usadas y no definidas


Operandos de tipos no compatibles

if (x || 5) x = 0;

Error: Ej2.java [7:1] operator || cannot be applied to int,int

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.

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.

En cierto modo, este tipo de error es el ms difcil de depurar, ya que ni el compilador


ni el sistema proporcionan informacin sobre qu est fallando. Lo nico cierto es
que el programa no se est comportando como debera. Un error semntico se
produce cuando la sintaxis del cdigo es correcta, pero la semntica o significado
no es el que se pretenda. La construccin obedece las reglas del lenguaje, y por
ello el compilador o intrprete no detectan los errores semnticos. Los compiladores
e intrpretes slo se ocupan de la estructura del cdigo que se escribe, y no de su
significado.

6
Los errores que puede detectar el analizador sintctico son aquellos que violan las
reglas de una gramtica independiente del contexto. Ya hemos mencionado que
algunas de las caractersticas de un lenguaje de programacin no pueden
enunciarse con reglas independientes del contexto, ya que dependen de l; por
ejemplo, la restriccin de que los identificadores deben declararse previamente. Por
lo tanto, los principales errores semnticos son:

1. Identificadores no definidos;
2. Operadores y operandos incompatibles.

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.

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.

Recuperacin de Errores PL/0

A continuacin, ejemplificaremos algunos de los mtodos antes mencionados para


la recuperacin de errores sintcticos. Para ellos expandiremos fragmentos del
programa del analizador sintctico descendente recursivo de PL/0 que vimos en el
captulo 4.

Recuperacin de Emergencia

La idea del anlisis sintctico descendente recursivo es que un problema de anlisis


sintctico se divida en subproblemas que se resuelven en forma recursiva. Ahora
bien, la ocurrencia de un error en un subproblema significa que no slo hay que
informar del error al procedimiento que llama. Ms bien, hay que garantizar que el
procedimiento del subproblema se recupere del error de modo que el procedimiento
invocador pueda continuar con el proceso de anlisis sintctico, es decir, que
termine de forma normal.

7
Por ello, adems de generar un mensaje de error, hay que ir saltndose la entrada
hasta llegar a un smbolo de sincronizacin. Esto implica que cada procedimiento
de un analizador sintctico descendente recursivo debe conocer cules son los
smbolos

PROCEDURE Prueba(Siguiente, detencin: conjsm; n:


INTEGER);
(*siguiente, detencin: smbolos de sincronizacin*)
(*n: nmero de error *)
VAR smsinc : conjsm;
BEJN
IF NOT (smbolo IN siguiente) THEN
Error (n);
Smsinc := siguiente + detencin;
WHILE NOT (smbolo IN smsinc) DO Leer_Smbolo END
END
END Prueba;

Tratamiento errores semnticos

Comprobacin de tipos

Aspectos generales

Un lenguaje con comprobacin fuerte de tipos es capaz de garantizar que los


programas se pueden ejecutar sin errores de tipo, por lo que los errores de tipo se
detectarn siempre en tiempo de compilacin.
Como mnimo, ante un error, un comprobador de tipos debe informar de la
naturaleza y posicin del error y recuperarse para continuar con la comprobacin
del resto del programa a analizar.

Veamos algunas de las operaciones a tener en cuenta en una comprobacin de


tipos:
Conversin de tipos: A veces es necesario transformar el tipo de una expresin
para utilizar correctamente un operador o para pasar de forma adecuada un
parmetro a una funcin.
Coercin: Es una conversin de tipos que realiza de forma implcita el propio
compilador. Si es el programador el que realiza la conversin se tratar entonces
de una conversin explcita.
Sobrecarga de operadores: La sobrecarga se resuelve determinando el tipo de
cada una de las expresiones intervinientes en la sobrecarga.
Funciones polimrficas: Son aquellas que trabajan con argumentos cuyo tipo
puede cambiaren distintas llamadas a la funcin.

8
Especificacin de un comprobador de tipos bsico

Bsicamente se debern realizar dos tareas:


a) Asignacin de tipos: en las declaraciones.
b) Evaluacin y comprobacin de tipos: En las expresiones y en las funciones, as
como en las sentencias.

Otras comprobaciones semnticas y recuperacin de errores semnticos

Dentro de las comprobaciones estticas (en el momento de la compilacin),


tenemos la deteccin e informacin de errores como:

Comprobaciones de tipos: operadores aplicados a operandos incompatibles,


asignacin de tipos incompatibles, llamadas a funciones con tipos no
adecuados, etc.
Comprobaciones de flujo de control: las sentencias que hacen que el flujo de
control abandone una construccin debe tener alg un lugar a donde transmitir
el control. Por ejemplo: Unbreak debe estar dentro de una proposicin while, for
o switch en C.
Comprobaciones de unicidad: situaciones en las que solo se puede definir un
objeto una vez exactamente. Por ejemplo: Un identificador, la etiqueta case
dentro de un switch.

CONCLUSIONES

Si un compilador tuviera que procesar slo programas correctos, su diseo e


implantacin se simplificaran mucho. Pero los programadores a menudo escriben
programas incorrectos, y un buen compilador debera ayudar al programador a
identificar y localizar errores. Es sorprendente que, aunque los errores sean tan
frecuentes, pocos lenguajes han sido diseados teniendo en cuenta el manejo de
errores. Se sabe que los programas pueden contener errores de muy diverso tipo.
Por ejemplo, los errores Semnticos. como un operador aplicado a un operando
incompatible.

BIBLIOGRAFA

http://ocwus.us.es/didactica-y-organizacion-escolar/procesos-de-ensenanza-
aprendizaje/asigpea/apartados/apartado5-2-2.asp.html/

9
CUADRO SINPTICO DONDE SE DESCRIBA EL MANEJO DE TIPOS EN LAS EXPRESIONES Y EL USO DE
OPERADORES.

Literal
Las expresiones primarias son los
bloques de creacin de expresiones ms this
Expresiones primarias complejas. Son literales, nombres, y :: name
nombres calificados por el operador de name
resolucin de mbito (::).
( expression )

Notacin de operador
Las expresiones de postfijo constan de []
expresiones primarias o expresiones en ()
las que los operadores de postfijo siguen
Expresiones de postfijo. type-name ( )
una expresin primaria. Los operadores
de postfijo se enumeran en la tabla . o >
siguiente. ++

Operadores Unarios y Binarios


Los operadores unarios actan solo *, &
TIPOS EN LAS EXPRESIONES sobre un operando en una expresin. -
Expresiones formadas con operadores !
Los operadores binarios actan sobre
dos operandos de una expresin. ++, --
()

El operador condicional (? :) es un operador


ternario (toma tres operandos). sintaxis
Expresiones con el operador El resultado del operador condicional es el expression ?
condicional. resultado de cualquier operando que se
expression :
evale, el segundo o el tercero.Solo uno de
los dos ltimos operandos se evala en una expression
expresin condicional.

Un valor constante valor es un valor que


no cambia++ proporciona dos palabras Sintaxis
clave para que pueda expresar la
Expresiones de constante const double Size = 11.0;
intencin de que un objeto no est
pensado para ser modificado y aplicar char chArray[(int)Size];
dicha intencin.

10
Suma +
ARITMETICOS Resta -
Operan sobre valores de tipo entero o real. Multiplicacion *
Division /
Modulo %

Por ejemplo:
ASIGNACION var x,y,z: real;
El operador de asignacin se representa por la begin
secuencia de caracteres := . Permite asignar a x:=12.5;
una variable el valor de una expresin.
y:=-5.7;
z:=2*x+3*y;

OPERADORES
Los operadores son smbolos especiales que por lo
comn se utilizan en expresiones.
Igualdad ==
RELACIONALES
Distinto !=
son operadores binarios en los que los operandos
son ordinales, reales o de cadena. Los dos primeros Menor que <
operadores sirven tambin para operandos de tipo Mayor que >
record y punteros. Todos ellos dan lugar a Menor o igual que <=
resultados de tipo booleano.
Mayor o igual que >=

LOGICOS O BOOLEANOS negacion not


Los operadores lgicos o boolenos realizan Suma logica or
operaciones con operandos de tipo lgico o
Producto logico and
booleano y tiene como resultado un dato tambin
del mismo tipo. Suma logica exclusiva xor

11
LISTA DE LAS REGLAS PARA LA CONVERSIN DE TIPOS (CASTING) EN
EXPRESIONES, DONDE EXPLIQUE TRES EJEMPLOS POR CADA REGLA

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 todo lo siguiente:

S y T son tipos diferentes

S o T es el tipo de clase o estructura en el que tiene lugar la declaracin del


operador.

Ni S ni T son de tipo object ni un tipo-de-interfaz.

T no es una clase base de S, y S tampoco lo es de T.

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.

12
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.

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

using System;
public struct 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) {
return d.value;
}
public static explicit operator Digit(byte b) {
return new Digit(b);
}
}

13
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.

var i : 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".

i = d; // Narrowing: the double value 5 coverted to the int 5.

i = s; // Narrowing: the String value "5" coverted to the int 5.

d = s; // Narrowing: the String value "5" coverted to the double 5.

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;

var f : float;

var s : String;

14
f = 3.14;

i = f; // Run-time error. The number 3.14 cannot be represented with an int.

s = "apple";

i = s; // Run-time error. The string "apple" cannot be converted to an int.

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:

15
1. Cualquier tipo entero pequeo como char o short es convertido a int o
unsigned int. En este punto cualquier pareja de operandos ser int (con o sin signo),
long, long long,double, float o long double.

2. Si un operando es de tipo long double, el otro se convertir a long double.

3. Si un operando es de tipo double, el otro se convertir a double.

4. Si un operando es de tipo float, el otro se convertir a float.

5. Si un operando es de tipo unsigned long long, el otro se convertir a unsigned


long long.

6. Si un operando es de tipo long long, el otro se convertir a long long.

7. Si un operando es de tipo unsigned long, el otro se convertir a unsigned


long.

8. Si un operando es de tipo long, el otro se convertir a long.

9. Si un operando es de tipo unsigned int, el otro se convertir a unsigned int.

10. Llegados a este punto ambos operandos son int.

Veamos ahora el ejemplo:

c = a + b; caso 10, ambas son int.

s = r + a; caso 4, a se convierte a float.

d = r + b; caso 4, b se convierte a float.

d = n + a + r; caso 1, n se convierte a int, la operacin resultante corresponde al


caso 4, el resultado (n+a) se convierte a float.

t = r + a - s + c; caso 4, a se convierte a float, caso 4 (r+a) y s son float, caso 4, c se


convierte a float.

Tambin se aplica conversin de tipos en las asignaciones, cuando la variable


receptora es de distinto tipo que el resultado de la expresin de la derecha.

En el caso de las asignaciones, cuando la conversin no implica prdida de


precisin, se aplican las mismas reglas que para los operandos, estas conversiones
se conocen tambin como promocin de tipos. Cuando hay prdida de precisin,
las conversiones se conocen como democin de tipos. El compilador normalmente
emite un aviso o warning, cuando se hace una democin implcita, es decir cuando
hay una democin automtica.

16
En el caso de los ejemplos 3 y 4, es eso precisamente lo que ocurre, ya que estamos
asignando expresiones de tipo float a variables de tipo int.

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, long double,
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.

Por ejemplo

Las siguientes expresiones booleanas son equivalentes:

0 == x equivale a !x.

0 != x equivale a x.

En el primer caso, usamos el operador == para comparar el valor de x con cero,


pero al aplicar el operador ! directamente a x obligamos al compilador a reinterpretar
su valor como un bool, de modo que si x vale 0 el valor es false, y !false es true. De
forma simtrica, si x es distinto de cero, se interpretar como true, y !true es false.
El resultado es el mismo que usando la expresin 0 == x.

En el segundo caso pasa algo anlogo. Ahora usamos el operador != para comparar
el valor de x tambin con cero, pero ahora interpretamos directamente x como bool,
de modo que si x vale 0 el valor es false, y si x es distinto de cero, se interpretar
como true. El resultado es el mismo que usando la expresin 0 != x.

No est claro cul de las dos opciones es ms eficaz, a la hora de compilar el


programa. Probablemente, la segunda requiera menos instrucciones del
procesador, ya que existen instrucciones de ensamblador especficas para

17
comparar un entero con cero. Del otro modo estaremos comparando con un valor
literal, y salvo que el compilador optimice este cdigo, generalmente se requerirn
ms instrucciones de este modo.

Aadir que los ejemplos anteriores funcionan, aunque el tipo de x no sea un entero.
Si se trata de un valor en coma flotante se realizar una conversin implcita a entero
antes de evaluar la expresin.

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.

var i : 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.

s = String(d); // Widening: the double value 5 coverted to the String "5".

i = int(d); // Narrowing: the double value 5 coverted to the int 5.

i = int(s); // Narrowing: the String value "5" coverted to the int 5.

d = double(s); // Narrowing: the String value "5" coverted to the double 5.

Las conversiones de restriccin explcitas suelen funcionar correctamente, aunque


la conversin requiera una prdida de informacin. La conversin explcita no se
puede utilizar para convertir tipos de datos incompatibles. Por ejemplo, no se
pueden convertir datos Date a datos RegExp, y viceversa. Adems, algunos valores
no se pueden convertir porque no existe ningn valor razonable al que se puedan
convertir. Por ejemplo, se genera un error si se intenta convertir explcitamente el

18
valor NaN de tipo double a un valor decimal. Esto es as porque no hay un valor
decimal natural que se pueda identificar con NaN.

En este ejemplo, se convierte un nmero que tiene una parte decimal y una cadena
en nmeros enteros:

var i : int;

var d : double;

var s : String;

d = 3.14;

i = int(d);

print(i);

s = "apple";

i = int(s);

print(i);

El resultado es:

El comportamiento de la conversin explcita depende del tipo de datos originales y


del tipo de datos de destino.

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:

(<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:

19
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.

Cdigo
Module Module1

Structure token
Dim expr As String
Dim op As String
Dim num As String
Dim par As String

End Structure

Sub Main()

Console.WriteLine("Analizador Lxico y Sintctico")

Console.WriteLine("Formas para utilizar")


Console.WriteLine("1.- <expr>=<expr><op><expr>")
Console.WriteLine("2.- (<expr>)")
Console.WriteLine("3.- -<expr>")
Console.WriteLine("4.- <expr>=<num>")
Console.WriteLine("5.- <num>=1,2,3,4,5,6,7,8,9")
Console.WriteLine("6.- <expr>=<op>")
Console.WriteLine("7.- <op>=+,*,/,^,-")
Console.WriteLine("8.- <letra>=a|b|...|z ")
Console.WriteLine("Ingrese la expresin a Analizar :")

Dim k As Integer
Dim h As Integer
Dim myString As String = Console.ReadLine
Dim myChar As String
Dim TestLen As Integer = Len(myString)
Dim exp(TestLen) As token
Dim i As Integer

For i = 0 To (TestLen - 1)

20
myChar = myString.Chars(i)

If myChar = "+" Or myChar = "-" Or myChar = "/" Or myChar = "*" Or myChar = "=" Or myChar
= "^" Then

exp(i).op = "op"
Console.WriteLine("<" & exp(i).op & "," & myChar & ">")
ElseIf myChar = "a" Or myChar = "b" Or myChar = "c" Or myChar = "d" Or myChar = "e" Or
myChar = "f" Or myChar = "g" Or myChar = "h" Or myChar = "i" Or myChar = "j" Or myChar = "k" Or myChar
= "l" Or myChar = "m" Or myChar = "n" Or myChar = "o" Or myChar = "p" Or myChar = "q" Or myChar = "r"
Or myChar = "s" Or myChar = "t" Or myChar = "v" Or myChar = "w" Or myChar = "x" Or myChar = "y" Or
myChar = "z" Then

exp(i).expr = "expr"
Console.WriteLine("<" & exp(i).expr & "," & myChar & ">")
ElseIf myChar = "1" Or myChar = "2" Or myChar = "3" Or myChar = "4" Or myChar = "5" Or
myChar = "6" Or myChar = "7" Or myChar = "8" Or myChar = "9" Or myChar = "10" Then
exp(i).num = "num"
Console.WriteLine("<" & exp(i).num & "," & myChar & ">")

ElseIf myChar = "(" Then


exp(i).par = "pari"
Console.WriteLine("<" & exp(i).par & "," & myChar & ">")
ElseIf myChar = ")" Then
exp(i).par = "parf"
Console.WriteLine("<" & exp(i).par & "," & myChar & ">")
Else
Console.WriteLine(myChar & " token no reconocido ")
End If
Next

'sintactico

k = 0
h = TestLen + 1000
While k <= TestLen - 1
If exp(k).par = "pari" Then
While exp(k).par <> "parf"
k = k + 1
If exp(k).expr = "expr" Then
k = k + 1
If exp(k).par = "parf" Then

Else
If exp(k).op = "op" Then

Else
Console.WriteLine(" Error en la expresin, se esperaba un <op>, no
cumple con la regla 1 o 4")
k = h
End If
End If
Else
Console.WriteLine(" Error en la expresin, se esperaba una <expr>, no cumple
con al regla 1")
k = h
End If

End While
k = k + 1
Else
If exp(k).op = "op" Then
k = k + 1
If exp(k).par = "pari" Then
While exp(k).par <> "parf"
k = k + 1
If exp(k).expr = "expr" Then
k = k + 1
If exp(k).par = "parf" Then

21
Else
If exp(k).op = "op" Then
Else
Console.WriteLine(" Error en la expresin, se esperaba un
<op>, no cumple con la regla 1 o 4 ")
k = h
End If
End If
Else
Console.WriteLine(" Error en la expresin, se esperaba una <expr>, no
cumple con al regla 1")
k = h
End If
End While
k = k + 1
Else
If exp(k).expr = "expr" Then
k = k + 1
Else
Console.WriteLine(" Error en la expresin, se esperaba una <expr>, no
cumple con al regla 1 o 4 ")
k = h
End If
End If
Else
If exp(k).expr = "expr" Then
k = k + 1
Else
Console.WriteLine(" Error en la expresin, se esperaba una <expr>, no cumple
con al regla 1 o 4 ")
k = h
End If

End If
End If

End While
If k > TestLen - 1 And k <> h Then
Console.WriteLine(" Expresin ingresada correctamente ")
End If

Dim expresion As String = Console.ReadLine

End Sub

End Module

22
Resultado Final

23
TABLA DONDE SE DESCRIBAN LAS ACCIONES SEMNTICAS A LA
ESTRUCTURA DE LA GRAMTICA

Acciones Semnticas A La Estructura De La Gramtica

Es posible calcular con este mtodo (LR) atributos heredados de hermanos


previamente calculados.

Es necesario introducir una produccin adicional.

El valor del atributo se almacena en una variable auxiliar y se calcula en funcin del
valor en la cima de la pila antes del reconocimiento de C.

En Yacc/CUP:

A: B {aux = 2 * B.atr} C

El clculo de los atributos depende de la estructura de la gramtica.


Es posible simplificar el clculo mediante una modificacin de las reglas
gramaticales.

24
Dada una gramtica con atributos, todos
los atributos heredados se pueden
convertir en sintetizados modificando
adecuadamente la gramtica, sin cambiar
Teorema de Knuth el lenguaje. (En la prctica no se utiliza
demasiado, pues puede generar
gramticas y reglas semnticas ms
complejas que las originales.)

25
REPORTE DE LA MANIPULACIN DE LA TABLA DE CONVERSIN DE
SMBOLOS Y DE DIRECCIONES

INTRODUCCIN

Tabla de smbolos y direcciones

Una tabla de smbolos es una estructura de datos que usa el proceso de traduccin
de un lenguaje de programacin, por un compilador o un intrprete, donde cada
smbolo en el cdigo fuente de un programa est asociado con informacin tal como
la ubicacin, el tipo de datos y el mbito de cada variable, constante o
procedimiento.

Una implementacin comn de una tabla de smbolos puede ser una tabla hash, la
cual ser mantenida a lo largo de todas las fases del proceso de compilacin de
tics.

Puede tratarse como una estructura transitoria o voltil, que sea utilizada
nicamente en el proceso de traduccin de un lenguaje de programacin, para luego
ser descartada, o integrada en la salida del proceso de compilacin para una
explotacin posterior, como puede ser, por ejemplo, durante una sesin de
depuracin, o como recurso para obtener un informe de diagnstico durante o
despus la ejecucin de un programa.

Los smbolos en la tabla de smbolos pueden referirse a constantes, a funciones o


a tipos de datos en el cdigo fuente de un programa.

La tabla de smbolos forma parte de cada fichero que contiene el cdigo objeto
durante el enlazado o linking de los diferentes ficheros; recae en la responsabilidad
del linker o enlazador resolver cualquier referencia no resuelta.

Tabla de smbolos en lenguaje C

Como ya se dijo en el esbozo la tabla de smbolos es una estructura de datos que


se crea en tiempo de traduccin del programa fuente. Es como un diccionario
variable, debe darle apoyo a la insercin, bsqueda y cancelacin de nombres
(identificadores) con sus atributos asociados, representando las vinculaciones con
las declaraciones. Debe aclararse que no necesariamente deber estar
representada en una tabla como su nombre indica ya que tambin se emplean
rboles, pilas, etc.

26
Los smbolos se guardan en la tabla con su nombre y una serie de atributos
opcionales que dependern del lenguaje y de los objetivos del procesador, este
conjunto de atributos almacenados se denomina registro de la tabla de smbolos.

La siguiente representa una serie de atributos que no es necesaria para todos los
compiladores, sin embargo, cada uno de ellos se puede utilizar en la
implementacin de un compilador particular.

Nombre del identificador.

Direccin en tiempo de ejecucin a partir del cual se almacenar el identificador si


es una variable.

Tipo del identificador. Si es una funcin, el tipo que devuelve la funcin.

Nmero de dimensiones del array (arreglo), o nmero de miembros de una


estructura o clase, o nmeros de parmetros si se trata de una funcin.

Tamao mximo o rango de cada una de las dimensiones de los array, si tiene
dimensin esttica. etc.

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.

27
En la insercin, se detectan identificadores que ya han sido declarados previamente,
emitiendo un mensaje de error

Ejemplo en C: mltiple declaration for 'x' si x ya estaba en TS.

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".

1. Para explicar cmo funciona la tabla de errores en funcin de la declaracin


de variables se realiz un cdigo en c++, donde se muestra que datos se
guardan en la tabla de smbolos al declarar una variable. Nos arroja los
siguientes resultados:

Se ingresa el nombre de la variable a declarar

Se ingresa el tipo de variable que se est declarando, nos devuelve tambin el


tamao de la variable en funcin al tipo.

Al final nos muestra la gramtica para declararla en un compilador de c++:

Y nos pregunta si deseamos seguir en el programa:

28
El cdigo del programa anterior es el siguiente:
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <cstring>
using namespace std;

int main()
{
string nombre;
string tipo;
int tamano;
string resp;
do{
cout << "ingrese el nombre de su variable: ";
cin>>nombre;
cout<<"si uso espacios solo se tomara la primer palabra antes del espacio. el nombre de su variable
es: "<<nombre<<"\n";
system("pause");
system("cls");
cout<<"ingrese el tipo de variable: ";
cin>>tipo;
if(tipo=="int"||tipo=="char"||tipo=="float"||tipo=="bool"||tipo=="string"||tipo=="double")
{
cout<<"su tipo de dato es: "<<tipo;
}else{
cout<<"el tipo de dato no es correcto\n";
}

switch(tipo[0])
{
case 'i': tamano = 16; cout<<"\ntamanio= "<<tamano<<" bytes\n";
system("pause");
system("cls");
cout<<"su variable es la siguiente: "<<tipo<<" "<<nombre;
break;
case 'c': tamano = 8; cout<<"\ntamanio= "<<tamano<<" bytes\n";
system("pause");
system("cls");
cout<<"su variable es la siguiente: "<<tipo<<" "<<nombre;
break;
case 'f': tamano = 32; cout<<"\ntamanio= "<<tamano<<" bytes\n";
system("pause");
system("cls");
cout<<"su variable es la siguiente: "<<tipo<<" "<<nombre;
break;
case 'b': tamano = 1; cout<<"\ntamanio= "<<tamano<<" byte\n";
system("pause");
system("cls");
cout<<"su variable es la siguiente: "<<tipo<<" "<<nombre;
break;
case 's': tamano = 65535; cout<<"\ntamanio= "<<tamano<<" caracteres\n";
system("pause");
system("cls");
cout<<"su variable es la siguiente: "<<tipo<<" "<<nombre;
break;
case 'd': tamano = 64; cout<<"\ntamanio= "<<tamano<<" bytes\n";
system("pause");
system("cls");
cout<<"su variable es la siguiente: "<<tipo<<" "<<nombre;
break;
}
cout<<"\n";
system("pause");
system("cls");

29
cout<<"\ndesea quedarse? [s/n]";
cin>>resp;
system("cls");
}while(resp == "s" || resp == "S");

return 0;
}

2. La generacin de cdigo intermedio tiene que ver con un lenguaje que la


maquina pueda entender un nivel antes de los registros, razn por la cual
tiene que hacer una conversin de caracteres del cdigo fuente a cdigo
ASCII, el siguiente cdigo realiza dicha conversin y pide al usuario un
carcter y lo muestra en pantalla en cdigo ASCII.
Para empezar, nos pedir un carcter para poder transformarlo a su cdigo ASCII:

Para posteriormente mostrarnos el cdigo ascii del carcter que hayamos


ingresado:

Se anexa la tabla de cdigo ascii de caracteres:

30
El cdigo del programa anterior es el siguiente:
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <cstring>
using namespace std;
int main()
{
int cod;
char car;
char resp;
do
{
cout<<"ingrese el caracter a transformar: ";
cin>>car;
cod=car;
cout<<"el codigo ascii de su caracter es: "<<cod<<"\n";
system("pause");
system("cls");
cout<<"desea continuar? [s/n]";
cin>>resp;
}while(resp=='s'||resp=='S');
return 0;
}

3. El prximo programa ser de efecto ilustrativo, le enseara al usuario como


se declara una variable, adems de mostrar cules son sus posibles estados,
as como el tamao que alcanzara su variable y el rango de operacin de la
misma.

Esto sucede con cada tipo de variable soportado por c++, esto le dar al usuario la
habilidad de declarar variables en la tabla de smbolos sin detectar errores, adems
de que sabr cuanta memoria est utilizando en la declaracin de variables.
El cdigo del programa anterior es el siguiente:
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <cstring>

using namespace std;

int main()
{
string tipo;
int tamano;
string nombre;
char resp;

do{
cout<<"ingrese el tipo de variable: ";
cin>>tipo;
if(tipo=="int"||tipo=="char"||tipo=="float"||tipo=="bool"||tipo=="string"||tipo=="double")

31
{
switch(tipo[0])
{
case 'i': tamano = 16;
cout<<"\nla declaracion de esta variable es: int 'nombre de la variable' ";
cout<<"\nel tamanio es = "<<tamano<<" bytes\n";
cout<<"rango de operacion de -2147483648 a +2147483647\n";
system("pause");
system("cls");
break;

case 'c': tamano = 1;


cout<<"\nla declaracion de esta variable es: char 'nombre de la variable' ";
cout<<"\nel tamanio es = "<<tamano<<" bytes\n";
cout<<"rango de operacion de -128 a 127\n";
system("pause");
system("cls");
break;

case 'f': tamano = 32;


cout<<"\nla declaracion de esta variable es: char 'nombre de la variable' ";
cout<<"\nel tamanio es = "<<tamano<<" bytes\n";
cout<<"rango de operacion de -128 a 127\n";
system("pause");
system("cls");
break;

case 'b': tamano = 1;


cout<<"\nla declaracion de esta variable es: bool 'nombre de la variable' ";
cout<<"\nel tamanio es = "<<tamano<<" bytes\n";
cout<<"rango de operacion 0,1\n";
system("pause");
system("cls");
break;

case 's': tamano = 65535;


cout<<"\nla declaracion de esta variable es: string 'nombre de la variable' ";
cout<<"\nel tamanio es = "<<tamano<<" bytes\n";
cout<<"rango de operacion depende del tamao de la memoria\n";
system("pause");
system("cls");
break;

case 'd': tamano = 8;


cout<<"\nla declaracion de esta variable es: double 'nombre de la variable' ";
cout<<"\nel tamanio es = "<<tamano<<" bytes\n";
cout<<"rango de operacion Positivos: 1.7E-308 a 1.7E308 \nNegativos: -1.7E-308 a -1.7E308\n";
system("pause");
system("cls");
break;
}
}else{
cout<<"el tipo de dato no es correcto\n";
}
cout<<"\ndesea quedarse en el programa?[s/n] ";
cin>>resp;
system("pause");
system("cls");
}while(resp=='s');
return 0;
}

32
PROPUESTA DE PROYECTO FINAL

Realizaremos un analizador lxico sintctico con el cual revisaremos nuestros


programas realizados durante la unidad para observar. El cual es un programa que
recibe como entrada el cdigo fuente de otro programa (secuencia de caracteres) y
produce una salida compuesta de tokens (componentes lxicos o smbolos). Estos
tokens sirve para una posterior etapa del proceso de traduccin, siendo la entrada
para le analizador sintctico.

El analizador sintctico convierte el texto en otras estructuras comnmente rboles,


que son ms tiles para el posterior anlisis, y captura la jerarqua implcita de la
entrada. En este los que son procesados son los tokens para construir la estructura
de datos por ejemplo un rbol de anlisis o arboles de sintaxis abstracta.

CONCLUSIN DE LA UNIDAD
Teniendo conocimientos previos bsicos acerca del funcionamiento de un
compilador se puede apreciar un mejor funcionamiento de parte de este, en
especfico, su analizador semntico. En resumen, podemos decir que un analizador
semntico tiene dos tareas: Una es la de hacer comprobaciones que no se hagan
durante el anlisis lxico o sintctico, y la otra la de crear una representacin
adecuada de sus expresiones para fases posteriores. Un esquema de traduccin
dirigido por la sintaxis aade a las gramticas:

Acciones intercaladas en las partes derechas de las reglas.


Atributos asociados a los no terminales.

Las acciones deben garantizar que se evalan correctamente los atributos, los
cuales pueden ser heredados y sintetizados.
En fin, como podemos observar el proceso que sigue el analizador semntico no es
muy complicado, simplemente est basado en reglas de sintaxis y comprobaciones
de tokens. Una gran ventaja que se tuvo para comprender el tema fue que tras haber
cursado la materia de Lenguajes y Autmatas 1 se pudo entender mejor cmo
funcionan las reglas sintcticas y los sistemas de smbolos que no slo sirven para
entender las funciones de un compilador, sino para cualquier sistema que se maneja
con alfabetos. (Autmatas)

BIBLIOGRAFA
1. Aho, Sethi, Ullman. Compiladores Principios, tcnicas y herramientasEd.
Addison Wesley.

33

S-ar putea să vă placă și