4.4 Tipos de Datos y Verificación de Tipos
Un compilador debe comprobar si el programa fuente sigue tanto las convenciones sintácticas como las semánticas del lenguaje fuente. Esta comprobación, llamada comprobación estática (para distinguirla de la comprobación dinámica que se realiza durante la ejecución del programa objeto), garantiza la detección y comunicación de algunas clases de errores de programación. Los ejemplos de comprobación estática incluyen:
Un comprobador de tipos se asegura de que el tipo de una construcción coincida con el previsto en su contexto. Por ejemplo, el operador aritmético predefinido mod en Pascal exige operandos de tipo entero, de modo que un comprobador de tipos debe asegurarse de que Los operandos de mod tengan tipo entero. De igual manera, el comprobador de tipos debe asegurarse de que la desreferenciación se aplique sólo a un apuntador, de que la indización se haga sólo sobre una matriz, de que una función definida por el usuario se aplique al número y tipo correctos de argumentos, etcétera. |
![]() |
Puede necesitarse la información sobre los tipos reunida por un comprobador de tipos cuando se genera el código. Por ejemplo, los operadores aritméticos como + normalmente se aplican tanto a enteros como a reales, tal vez a otros tipos, y se debe examinar el contexto de + para determinar el sentido que se pretende dar. Se dice que un símbolo que puede representar diferentes operaciones en diferentes contextos está "sobrecargado". La sobrecarga puede ir acompañada de coacción de tipos, donde un compilador proporciona un operador para convertir un operando en el tipo esperado por el contexto. Una noción diferente de la de sobrecarga es la de "polimorfismo". El cuerpo de una función polimórfica puede ejecutarse con argumentos de varios tipos. SISTEMAS DE TIPOS El diseño de un comprobador de tipos para un lenguaje se basa en información acerca de las construcciones sintácticas del lenguaje, la noción de tipos y las reglas para asignar tipos a las construcciones de lenguaje. Los siguientes extractos del informe de Pascal y del manual de referencia de C, respectivamente, son ejemplos de la información con la que el diseñador de un compilador podría verse obligado a comenzar.
En los anteriores extractos se encuentra implícita la idea de que cada expresión tiene asociado un tipo. Además, los tipos tienen estructura; el tipo "apuntador a ... " se construye a partir del tipo al que se refiere " ... ". En Pascal y en C, los tipos son básicos o construidos. Los tipos básicos son los tipos atómicos sin estructura interna por lo que concierne al programador. En Pascal, los tipos básicos son boolean, character, integer y real. Los tipos de subrango, como 1 .. 10, y los tipos enumerados, como (violeta, índigo, azul, verde, amarillo, naranja, rojo) se pueden considerar como tipos básicos. Pascal admite que un programador construya tipos a partir de tipos básicos y otros tipos construidos, como matrices (array), registros (record) y conjuntos (set). Además, los apuntadores y las funciones también pueden considerar~ como tipos construidos. Verificación de tipos Un componente importante del análisis semántico es la verificación de tipos. aqui , el compilador verifica si cada operador tiene operandos permitidos por la especificación del lenguaje fuente. Por ejemplo, las definiciones de muchos lenguajes de programación requieren que el compilador indique un error cada vez que se use un número real como indice de una matriz. Sin embargo, la especificación del lenguaje puede permitir ciertas coerciones a los operandos, por ejemplo, cuando un operador aritmético binario se aplica a un número entero y a un número real. En este caso, el compilador puede necesitar convertir el número entero a real. Expresiones de tipos El tipo de una construcción de un lenguaje se denotará mediante una “expresión de tipo”. De manera informal, una expresión de tipo es, o bien un tipo básico o se forma aplicando un operador llamado constructor de tipos a otras expresiones de tipos. Los conjuntos de tipos y constructores básicos dependen del lenguaje que deba comprobarse. Cada lenguaje de programación requerirá unas expresiones de tipos adecuadas a sus características. A continuación, a modo de ejemplo, se definen las expresiones de tipos más comunes: Tipos simples: Son expresiones de tipos los tipos simples del lenguaje, y algunos tipos especiales:
Los cuatro primeros son los tipos de datos simples más comunes en los lenguajes de programación, los dos últimos son tipos simples especiales que usaremos para su atribución a diversas partes de un programa, a fin de homogeneizar el tratamiento de todo el conjunto mediante el método de las expresiones de tipos.
Tomando el lenguaje C como ejemplo, el segmento de código al que está asociada la expresión de tipos integer es aquella en que aparece la palabra reservada int, etc.
Las expresiones de tipo pueden contener variables cuyos valores son expresiones de tipos. CONVERSIONES DE TIPOS, SOBRECARGA DE FUNCIONES Y OPERADORES, FUNCIONES POLIMÓRFICASConversiones de tipos Considérense expresiones como x + i donde x es de tipo real e i es de tipo entero. Como representación de enteros y reales es distinta dentro de un computador, y se utilizan instrucciones de máquina distintas para las operaciones sobre enteros y reales, puede que el compilador tenga que convertir primero uno de los operandos de + para garantizar que ambos operandos sean del mismo tipo cuando tenga lugar la suma. La definición del lenguaje especifica las conversiones necesarias. Cuando un entero se asigna a un real, o viceversa, la conversión es al tipo del lado izquierdo de la asignación. En expresiones, la transformación más común es la de convertir el entero en un número real y después realizar una operación real con el par de operandos reales obtenidos. Se puede utilizar el comprobador de tipos en un compilador para insertar estas operaciones de conversión en la representación intermedia del programa fuente. CoercionesLa definición del lenguaje especifica las conversiones necesarias. Cuando un entero se asigna a un real, o viceversa, la conversión es al tipo del lado izquierdo de la asignación. En expresiones, la transformación más común es la de convertir el entero en un número real y después realizar una operación real con el par de operandos reales obtenidos. Se puede utilizar el comprobador de tipos en un compilador para insertar estas operaciones de conversión en la representación intermedia del programa fuente. Sobrecarga de funciones y operadores Un símbolo sobrecargado es el que tiene distintos significados dependiendo de su contexto. La sobrecarga se resuelve cuando se determina un significado único para un caso de un símbolo sobrecargado. La resolución de la sobrecarga a menudo aparece referida comoidentificación de operadores porque determina la operación que denota un símbolo de operador. Los operadores aritméticos están sobrecargados en la mayoría de los lenguajes. Sin embargo, la sobrecarga que afecta a los operadores aritméticos como + se puede resolver observando únicamente los argumentos del operador. Funciones polimórficas El término “polimórfico” se aplica a cualquier parte de código que pueda ejecutarse con argumentos de tipos distintos, de modo que se puede hablar de funciones, así como de operadores polimórficos. Los operadores predefinidos para indicar matrices, aplicar funciones y manipular apuntadores son generalmente polimórficos porque no se limitan a una determinada clase de matriz, función o apuntador.
|