Gramatica Pascal

Descargar como odt, pdf o txt
Descargar como odt, pdf o txt
Está en la página 1de 13

Sintaxis de Pascal

El propósito de esta página es proporcionar un resumen de la sintaxis, expresada en BNF (Formas


de Backus-Naur), del subconjunto del lenguaje Pascal contemplado en la asignaturaProgramación I,
curso 99/00.
Debe quedar claro que estas definiciones tan sólo incorporan la sintaxis básica, y por lo tanto el que
un elemento cumpla una definición no significa necesariamente que sea una construcción correcta
en Pascal. Por ejemplo, la definición de sentencia de asignación, <Variable> := <Expresion> no
incorpora la información de que el resultado de la evaluación de la expresión debe ser de un tipo de
datos compatible con el tipo de la variable.
Ese tipo de información corresponde a la semántica del lenguaje, y sólo se incorpora de manera
parcial mediante construcciones del tipo Identificador de funcion, que restringen los elementos
permitidos en una parte de la definición.
Cuando aparezca el símbolo ‡ en la parte derecha de una definición, significa que existe un enlace a
una página donde se proporciona información adicional sobre ese elemento (significado,
restricciones, etc).
Para facilitar la búsqueda de una definición concreta, elija el término en la siguiente lista y pulse
"Ver Definicion", o comienze con un elemento de alto nivel como Programa , Unidad o Tipo de
dato.

Ver Definicion
Alternativa_doble
Definiciones:

• Alternativa doble ::= if <Condicion> then <Sentencia> else <Sentencia>


• Alternativa multiple ::= case <Expresion de Tipo ordinal> of <Caso>{; <Caso>} end
Alternativa multiple ::= case <Expresion de Tipo
ordinal> of <Caso>{; <Caso>} else <Sentencia> end ‡
• Alternativa simple ::= if <Condicion> then <Sentencia>
• Bucle con numero fijo de iteraciones ::= for <Sentencia de asignacion> to <Expresion de Tipo
ordinal> do <Sentencia>
Bucle con numero fijo de iteraciones ::= for <Sentencia de
asignacion> downto <Expresion de Tipo ordinal> do <Sentencia> ‡
• Bucle con salida al final ::= repeat <Sentencia>{; <Sentencia>} until <Condicion>
• Bucle con salida al principio ::= while <Condicion> do <Sentencia>
• Cabecera de funcion ::= function <Identificador de funcion> : <Identificador de Tipo
elemental> ;
Cabecera de funcion ::= function <Identificador de funcion> ( <Parametros formales por
valor>{; <Parametros formales por valor>} ) : <Identificador de Tipo elemental> ;
• Cabecera de procedimiento ::= procedure <Identificador de procedimiento> ;
Cabecera de procedimiento ::= procedure <Identificador de procedimiento> ( <Parametros
formales>{; <Parametros formales>} ) ;
• Cabecera de programa ::= program <Identificador de programa> ;
Cabecera de programa ::= program <Identificador de programa> ( <Lista de dispositivos> );
• Cabecera de unidad ::= unit <Identificador de unidad> ;
• Caracter de subrayado ::= _
• Caso ::= <Rango de literales> : <Sentencia>
• Comentario ::= { {<Caracter>} }
Comentario ::= (* {<Caracter>} *)
• Condicion ::= <Expresion de tipo boolean>
• Conversion de tipo ::= <Identificador de Tipo ordinal> ( <Expresion de Tipo ordinal> )
• Cuerpo de funcion ::= <Sentencia compuesta>
• Cuerpo de procedimiento ::= <Sentencia compuesta>
• Cuerpo de programa ::= <Sentencia compuesta>
• Declaracion de campos ::= <Identificador de campo>{, <Identificador de
campo>} : <Identificador de Tipo de dato>
• Declaracion de constante ::= <Identificador de constante> = <Literal>
Declaracion de constante ::= <Identificador de constante> : <Identificador de Tipo
elemental> = <Literal>
• Declaracion de funcion ::= <Cabecera de funcion><Zona de declaraciones><Cuerpo de
funcion>
• Declaracion de interfaz ::= <Cabecera de funcion> | <Cabecera de procedimiento>
• Declaracion de procedimiento ::= <Cabecera de procedimiento><Zona de
declaraciones><Cuerpo de procedimiento>
• Declaracion de subprograma ::= <Declaracion de funcion> | <Declaracion de procedimiento>
• Declaracion de variables ::= <Identificador de variable>{, <Identificador de variable>} : <Tipo de
dato>
• Definicion de tipo ::= <Identificador de tipo> = <Tipo de dato>
• Digito ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
• Dispositivo ::= input | output | <Identificador de variable tipo fichero>
• Elemento de array ::= <Variable de Tipo array> [ <Expresion de Tipo
indice>{, <Expresion de Tipo indice>} ]
• Elemento de estructura ::= <Elemento de array> | <Elemento de registro>
• Elemento de registro ::= <Variable de Tipo registro> . <Identificador de campo>
• Estructura alternativa ::= <Alternativa simple> | <Alternativa doble> | <Alternativa multiple>
• Estructura de control ::= <Estructura alternativa> | <Estructura iterativa> | <Estructura with>
• Estructura iterativa ::= <Bucle con salida al principio> | <Bucle con salida al final> | <Bucle
con numero fijo de iteraciones>
• Estructura with ::= with <Variable de tipo registro> do <Sentencia>
• Expresion ::= <Literal> | <Identificador de constante> | <Variable> | <Expresion unaria> |
<Expresion binaria> | <Llamada a funcion> | <Conversion de tipo>
Expresion ::= ( <Expresion> )
• Expresion binaria ::= <Expresion><Operador binario><Expresion>
• Expresion unaria ::= <Operador unario><Expresion>
• Identificador ::= <Letra>{<Letra> | <Digito>}
• Letra ::= <Letra mayuscula> | <Letra minuscula> | <Caracter de subrayado>
• Letra
mayuscula ::= A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y |
Z
• Letra minuscula ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z
• Lista de dispositivos ::= <Dispositivo>{<Dispositivo>}
• Literal ::= <Literal de tipo entero> | <Literal de tipo real> | <Literal de tipo caracter> | <Literal
de tipo boolean> | <Literal de tipo string> | <Literal de tipo conjunto> | <Literal de tipo
puntero> | <Literal tipo enumerado>
• Literal de tipo boolean ::= true | false ‡
• Literal de tipo caracter ::= ' <Caracter> '
Literal de tipo caracter ::= # <Digito>{<Digito>} ‡
• Literal de tipo conjunto ::= [ ]
Literal de tipo conjunto ::= [ <Rango de valores> ]
• Literal de tipo entero ::= <Signo><Digito>{<Digito>}
• Literal de tipo puntero ::= nil ‡
• Literal de tipo real ::= <Signo><Digito>{<Digito>} . <Digito>{<Digito>}
Literal de tipo real ::= <Signo><Digito>{<Digito>} e <Signo><Digito>{<Digito>}
Literal de tipo real ::=
<Signo><Digito>{<Digito>} . <Digito>{<Digito>} e <Signo><Digito>{<Digito>}
• Literal de tipo string ::= ' {<Caracter>} '
• Literal tipo enumerado ::= <Identificador de valor enumerado>
• Llamada a funcion ::= <Identificador de funcion>
Llamada a funcion ::= <Identificador de funcion> ( <Parametros actuales por
valor>{; <Parametros actuales por valor>} )
• Llamada a procedimiento ::= <Identificador de procedimiento>
Llamada a procedimiento ::= <Identificador de procedimiento> ( <Parametros
actuales>{; <Parametros actuales>} )
• Operador aritmetico entero ::= + | - | * | div | mod ‡
• Operador aritmetico real ::= + | - | * | / ‡
• Operador binario ::= + | - | * | div | mod | / | and | or | = | <> | < | > | <= | >= | in
• Operador de conjunto ::= + | - | * | = | <> | <= | >= | in ‡
• Operador de string ::= + ‡
• Operador logico ::= not | and | or
• Operador relacional ::= = | <> | < | > | <= | >=
• Operador unario ::= - | not
• Parametros actuales ::= <Parametros actuales por valor> | <Parametros actuales por variable>
• Parametros actuales por valor ::= <Expresion>
• Parametros actuales por variable ::= <Variable>
• Parametros formales ::= <Parametros formales por valor> | <Parametros formales por
variable>
• Parametros formales por valor ::= <Identificador de variable>{, <Identificador de
variable>} : <Identificador de tipo>
• Parametros formales por variable ::= var <Identificador de variable>{, <Identificador de
variable>} : <Identificador de tipo>
• Programa ::= <Cabecera de programa><Zona de declaracion de unidades><Zona de
declaraciones><Cuerpo de programa> .
• Rango de literales ::= <Literal de Tipo ordinal>
Rango de literales ::= <Literal de Tipo ordinal> .. <Literal de Tipo ordinal> ‡
Rango de literales ::= <Rango de literales>{, <Rango de literales>}
• Rango de valores ::= <Expresion de Tipo ordinal>
Rango de valores ::= <Expresion de Tipo ordinal> .. <Expresion de Tipo ordinal> ‡
Rango de valores ::= <Rango de valores>{, <Rango de valores>}
• Sentencia ::= <Sentencia de asignacion> | <Sentencia compuesta> | <Llamada a
procedimiento> | <Estructura de control>
• Sentencia compuesta ::= begin <Sentencia>{; <Sentencia>} end
• Sentencia de asignacion ::= <Variable> := <Expresion> ‡
• Signo ::= | + | -
• Tipo array ::= <Identificador de tipo array>
Tipo array ::= array[ <Tipo indice>{, <Tipo indice>} ] of <Tipo de dato>
• Tipo conjunto ::= <Identificador de tipo conjunto>
Tipo conjunto ::= set of <Tipo ordinal> ‡
• Tipo de dato ::= <Tipo simple> | <Tipo estructurado> ‡
• Tipo elemental ::= <Tipo simple> | <Tipo string>
• Tipo entero ::= integer | longint ‡
• Tipo enumerado ::= <Identificador de tipo enumerado>
Tipo enumerado ::= ( <Literal tipo enumerado>{, <Literal tipo enumerado>} )
• Tipo estructurado ::= <Tipo array> | <Tipo registro> | <Tipo fichero> | <Tipo conjunto> | <Tipo
string>
• Tipo fichero ::= <Identificador de tipo fichero>
Tipo fichero ::= text
Tipo fichero ::= file of <Tipo de dato> ‡
• Tipo indice ::= <Tipo ordinal>
• Tipo ordinal ::= <Tipo ordinal predefinido> | <Tipo enumerado> | <Tipo subrango>
• Tipo ordinal predefinido ::= <Tipo entero> | char | boolean
• Tipo puntero ::= <Identificador de tipo puntero>
Tipo puntero ::= ^ <Identificador de Tipo de dato> ‡
• Tipo real ::= real ‡
• Tipo registro ::= <Identificador de tipo registro>
Tipo registro ::= record <Declaracion de campos>{; <Declaracion de campos>} end
• Tipo simple ::= <Tipo ordinal> | <Tipo real> | <Tipo puntero>
• Tipo string ::= <Identificador de tipo string>
Tipo string ::= string[ <Literal de tipo entero> ] ‡
• Tipo subrango ::= <Identificador de tipo subrango>
Tipo subrango ::= <Literal de Tipo ordinal> .. <Literal de Tipo ordinal>
• Unidad ::= <Cabecera de unidad><Zona de interfaz><Zona de implementacion> end.
• Variable ::= <Identificador de variable> | <Elemento de estructura> | <Variable dinamica>
• Variable dinamica ::= <Variable de Tipo puntero> ^ ‡
• Zona de declaracion de constantes ::=
Zona de declaracion de constantes ::= const <Declaracion de constante>{; <Declaracion de
constante>} ;
• Zona de declaracion de interfaces ::= <Declaracion de interfaz>{; <Declaracion de interfaz>} ;
• Zona de declaracion de subprogramas ::=
Zona de declaracion de subprogramas ::= <Declaracion de subprograma>{; <Declaracion de
subprograma>} ;
• Zona de declaracion de unidades ::=
Zona de declaracion de unidades ::= unit <Identificador de unidad>{, <Identificador de unidad>} ;
• Zona de declaracion de variables ::=
Zona de declaracion de variables ::= var <Declaracion de variables>{; <Declaracion de
variables>} ; ‡
• Zona de declaraciones ::= <Zona de declaracion de constantes><Zona de definicion de
tipos><Zona de declaracion de subprogramas><Zona de declaracion de variables> ‡
• Zona de definicion de tipos ::=
Zona de definicion de tipos ::= type <Definicion de tipo>{; <Definicion de tipo>} ;
• Zona de implementacion ::= implementation <Zona de declaracion de subprogramas>
• Zona de interfaz ::= interface <Zona de declaracion de unidades><Zona de declaracion de
constantes><Zona de definicion de tipos><Zona de declaracion de interfaces>

Elementos de semántica de Pascal


Alternativa Múltiple
case <Expresion de Tipo ordinal> of <Caso>{; <Caso>} else <Sentencia> end
Este tipo de estructura tiene las siguientes características:
• La expresión se evalúa una única vez, antes de comenzar la estructura
• Los casos deben ser excluyentes entre sí, y por lo tanto no es posible que un valor pertenezca a
más de un caso.
• Cuando se ejecuta la sentencia asociada a un caso, la estructura termina.
• La sentencia asociada a la parte opcional else sólo se ejecuta si el resultado de la expresión no
pertenece a ningún caso. En esta última situación, si no existiera la parte else, la estructura
terminaría sin ejecutar ninguna sentencia.

Bucle con número fijo de iteraciones


for <Variable de control del bucle> := <Expresion 1> to <Expresion 2> do <Sentencia>
Este tipo de estructura tiene las siguientes características:
• La variable de control del bucle no puede ser modificada en la(s) sentencia(s) que forman parte del
bucle.
• Las expresiones 1 y 2 se evaluan una única vez, antes de comenzar el bucle.
• Los resultados de las expresiones 1 y 2 deben garantizar como mínimo una ejecución del bucle. En
concreto, el valor de la expresión 1 debe ser menor o igual que el de la expresión 2 en un bucle to, y
mayor o igual en un bucle downto.
• La variable de control del bucle toma todos los valores comprendidos entre entre el valor inicial (el
resultado de la evaluacion de la expresion 1) y el valor final (el resultado de la evaluacion de la
expresion 2), ambos inclusive.
• Tras la ejecución del bucle, el valor almacenado en la variable de control del bucle es desconocido.
• Si N1 y N2 representan los resultados de la evaluación de las expresiones 1 y 2, respectivamente,
entonces el bucle se repite (N2 - N1 + 1) veces en el caso de un bucle to, y (N1 - N2 + 1) veces en el
caso de un bucle downto.

Literal de tipo boolean


El valor false tiene asociado un valor ordinal de 0, y el valor true un valor ordinal de 1. Al comparar valores
de tipo boolean se cumple que false < true.

Literal de tipo carácter


La notación #<Número> representa al carácter que se encuentra en esa posición de la tabla de caracteres.
Es equivalente, por tanto, a chr(Número).
Comparar caracteres es comparar las posiciones que ocupan en la tabla de caracteres del sistema. No
existe (todavía) una tabla de caracteres universal, por lo que sólo podemos suponer las siguientes
características, comunes a la mayoria de tablas existentes:
• Los caracteres correspondientes a dígitos se encuentran antes que los correspondientes a letras
mayúsculas, que a su vez son anteriores a las letras minúsculas. Cuando se habla de letras se debe
entender que nos referimos al alfabeto anglosajón, y por lo tanto no se incluyen la letra eñe, las
vocales acentuadas, ni otros símbolos particulares de nuestro alfabeto.
• Los grupos de caracteres 0..9, A..Z, a..z ocupan posiciones consecutivas, y siguen el orden
alfabetico normal. Nota: Los grupos generalmente no son consecutivos, es decir al carácter 9 no le
sigue el caráter A.

Literal de tipo puntero


El literal nil es compatible con todos los tipos puntero. Como la dirección representada por nil no puede
corresponder a la de ninguna variable dinámica, asignar a un puntero este valor sirve para indicar que el
puntero no almacena una dirección válida.
Tipos enteros
Los tipos enteros sirven para representar valores numéricos sin parte decimal. Tienen una limitación de
rango, es decir sólo pueden representar valores dentro de unos límites determinados. Si alguna operación
aritmetica produce un valor fuera de esos limites, se produce un error de desbordamiento. Los límites, para
la versión de Turbo-Pascal que utilizamos, son:
• Tipo integer: -(Maxint+1) .. Maxint
• Tipo longint: -231 .. (231-1)
Maxint es una constante predefinida que indica el valor máximo que se puede representar en un valor de
tipo integer.
Nota: Maxint = 215-1 = 32.767, 231 = 2.147.483.648. Los valores se codifican internamente en complemento
a dos.

Operadores aritméticos enteros


Los operadores aritmeticos enteros operan sobre valores de tipo integer y longint. Si un operando es de
tipo integer y el otro de tipo longint, el operando de tipo integer se convierte automáticamente a un valor
de tipo longint y se pasa a calcular el resultado, que será de tipo longint.
En el caso de los operadores cociente (div) y resto (mod), se cumplen las siguientes relaciones: Dados c :=
a div b, r := a mod b, se tiene que:
• (1) a = c*b + r
• (2) |r| < |b|
• (3) |c| = |a| div |b|
• (4) |r| = |a| mod |b|
Las ecuaciones (3) y (4) indican que cuando el dividendo y/o el divisor son negativos, los valores absolutos
del cociente y el resto proporcionados son iguales a los obtenidos cuando el dividendo y el divisor son
positivos, y los signos del cociente y el resto se eligen de manera que se cumpla la ecuación (1).

Tipos reales
Los tipos reales sirven para representar valores numéricos con parte decimal. La representación de valores
tiene las siguientes limitaciones:
• El desbordamiento superior sucede cuando el valor a representar es mayor, en terminos
absolutos (sin tener en cuenta el signo), que el valor máximo representable. En Turbo-Pascal este
máximo vale aproximadamente 1,7*1038. Cualquier operación en la que se obtenga un resultado
absoluto mayor da un error.
• El desbordamiento inferior sucede cuando el valor a representar esta más cerca de cero que un
determinado límite. En Turbo-Pascal este límite vale aproximadamente 2,9*10-38. Cualquier
operación en la que se obtenga un resultado absoluto menor da como resultado cero (no se produce
error).
• La perdida de precisión sucede cuando se necesita representar un valor con más dígitos
significativos (precisión) de la que es capaz el método de codificación. En Turbo-Pascal los valores
de tipo real almacenan los 11 dígitos decimales más significativos (es decir, sin tener en cuenta los
ceros iniciales y/o finales).
Esta última limitación indica que, salvo casos especiales, los valores de tipo real no son una representación
exacta del valor real, sino tan solo una aproximación. Por lo tanto, es necesario evitar en lo posible
comparaciones de igualdad y desigualdad con valores de tipo real, ya que pueden dar lugar a resultados
inesperados. Por ejemplo, la comparación 3*(1/3) = 1.0 da como resultado false.

Operadores aritméticos reales


Los operadores suma, resta y multiplicación proporcionan un resultado de tipo real cuando alguno de sus
operandos es de ese tipo. Si un operando es de tipo integer o longint, se convierte automáticamente a un
valor de tipo real y se pasa a calcular el resultado.
El operador de división (/), sin embargo, proporciona siempre un resultado de tipo real, incluso cuando
ambos operandos son enteros y la división tiene un resultado exacto.
Operadores de conjuntos
En la siguiente tabla se muestran los operadores de conjuntos, el tipo de sus argumentos y de su resultado:

Operador Significado Operando 1 Operando 2 Resultado

+ Unión Conjunto tipo base T1 Conjunto tipo base T2 Conjunto tipo base T3

* Intersección Conjunto tipo base T1 Conjunto tipo base T2 Conjunto tipo base T3

- Diferencia Conjunto tipo base T1 Conjunto tipo base T2 Conjunto tipo base T3

= Igualdad Conjunto tipo base T1 Conjunto tipo base T2 Boolean

<> Desigualdad Conjunto tipo base T1 Conjunto tipo base T2 Boolean

<= Subconjunto de Conjunto tipo base T1 Conjunto tipo base T2 Boolean

in Pertenencia Valor de tipo T1 Conjunto tipo base T2 Boolean


Los tipos de datos T1 y T2 deben cumplir alguna de las siguientes condiciones:

• Ser el mismo tipo. En este caso el tipo T3 será el mismo que T1 y T2.
• Que T1 sea un subrango de T2. El tipo resultado T3 será igual a T2.
• Que T2 sea un subrango de T1. El tipo resultado T3 será igual a T1.
• Que T1 y T2 sean subrangos del mismo tipo, posiblemente con límites distintos. En este caso
T3 será el menor subrango cuyos límites incluyen a los de T1 y T2. Por ejemplo, si T1 = 1..5 y T2 =
4..10, T3sería 1..10.

Operadores de string (concatenación)


El operador de concatenación de cadenas de caracteres (+) tiene la siguiente sintaxis:
<Expresión de tipo T1> + <Expresión de tipo T2>

Los tipos de datos T1 y T2 pueden ser cualquier tipo string (independientemente de su número máximo de
caracteres) o char. El resultado es un valor de tipo string[n], donde n es el tamaño mínimo del string que
puede almacenar la cadena resultante.
En Turbo-Pascal, si la cadena resultante tiene más de 255 caracteres, no se tienen en cuenta aquellos
situados tras la posición 255.

Rango de valores
La definición de un rango de valores se utiliza en la sentencia case (los límites son literales) y en el
constructor de conjuntos (los limites son expresiones). Suponiendo la siguiente definición común a ambos
casos:
<Valor N1>..<Valor N2>

Se deben cumplir las siguientes condiciones:


• N1 debe ser del mismo tipo que N2.
• N1 debe ser menor o igual que N2.
• En Turbo-Pascal, en el caso de construcción de conjuntos, se tiene la limitación de que los valores
no pueden ser negativos.
Nota: Los valores N1 y N2 pertenecen al rango resultante.

Sentencia de asignación
<Variable de tipo T1> := <Expresión de tipo T2>

La ejecución de una sentencia de asignación comprende los siguientes pasos:


1. Se evalua la expresión, obteniendose, si no se producen errores, un valor de tipo T2. (Para mas
detalles, ver Evaluación de expresiones)
2. Se comprueba que es posible asignar a la variable de tipo T1 un valor de tipo T2. Para que sea
posible, el valor de tipo T2 debe estar dentro del rango de valores del tipo T1, y se debe cumplir
alguna de las siguientes condiciones:
• T1 y T2 son el mismo tipo, el cual no es fichero o un tipo estructurado donde algun elemento
sea de tipo fichero.
• T1 es longint y T2 es integer.
• T1 es real y T2 es integer o longint.
• T1 y T2 son cadena de caracteres.
• T1 es cadena de caracteres y T2 es char.
• T1 y T2 son conjuntos cuyos tipos base son compatibles.
• T1 es puntero y el resultado de la expresión es el valor nil.
3. Se asigna el valor a la variable.
Para ampliar información, vease Tipos de datos compatibles.

Tipos de datos compatibles


Todos los tipos de datos son compatibles consigo mismos. Dos tipos distintos son compatibles entre sí
cuando cumplen alguna de las siguientes condiciones:
• Un tipo es integer y el otro longint.
• Un tipo es un subrango del otro.
• Ambos son subrangos del mismo tipo.
• Ambos son conjuntos cuyos tipos base son compatibles entre sí.
• Ambos son cadenas de caracteres (string).
• Un tipo es cadena de caracteres y el otro es char.

Evaluación de expresiones
El orden de evaluación de los elementos de una expresión sigue las siguientes normas:
• Cualquier elemento encerrado entre paréntesis se evalúa primero.
• Si la expresión es una llamada a función, se evaluan los parámetros actuales por valor, se asignan
esos valores a las variables parámetros formales de la función, se ejecuta la funcíon y la expresión
se resuelve con el ultimo valor asignado a la variable asociada a la función.
• Si en la expresión aparecen varios operadores, se ejecuta primero el operador con
mayor precedencia. En el caso de operadores con la misma precedencia, se ejecuta primero el
operador situado más a la izquierda en la expresión.
Para que una expresión pueda evaluarse se deben dar las siguientes condiciones:

• En el caso de operadores, los operandos deben ser del tipo requerido y/o cumplir las reglas
de compatibilidad entre tipos.
• En el caso de llamadas a funciones, el tipo de los parametros actuales (valores que se envián)
deben ser compatibles según las normas de la asignación con el tipo de los parámetros formales
(variables de la función que reciben los valores).
• No se produzcan problemas de desbordamiento u operaciones no permitidas (dividir por cero, por
ejemplo).
Nota: En el caso de parámetros por variable, el tipo de datos de la variable parámetro actual y el tipo de
datos de la variable parámetro formal debe ser exactamente el mismo.

Precedencia de operadores
Los niveles de precedencia de los operadores de Pascal son los siguientes:

Nivel Tipo de operador Operadores


4 Operadores unarios not, -
3 Operadores multiplicativos *, /, div, mod, and
2 Operadores aditivos +, -, or
1 Operadores relacionales =, <>, <, >, <=, >=, in

Tipo conjunto
El tipo de datos conjunto tiene las siguientes características especiales:
• El tipo base debe ser un ordinal, y en Turbo-Pascal existe la limitación de que su cardinalidad
(número de valores distintos que pertenecen al tipo) debe ser menor de 256, y en el caso de tipos
base numéricos no están permitidos los valores negativos.
• Existen literales de tipo conjunto (ver Literal de tipo conjunto).
• Existen operadores que se aplican a conjuntos (ver Operadores de conjuntos).
• Son compatibles los valores conjunto cuyo tipo base sea compatible, aunque su definición de tipo
sea distinta.
• A diferencia del resto de tipos estructurados, los conjuntos no almacenan valores del tipo base, sino
la información sobre si un valor, en un momento determinado, pertenece o no al conjunto.

Tipo cadena de caracteres (string)


El tipo de datos cadena de caracteres (string) es una especialización basada en los arrays unidimensionales
de caracteres a la que se añade funcionalidad para facilitar la representación de texto. Entre sus
características especiales destacan:
• Comparte las características de un array de caracteres indexado desde 1 hasta el tamaño máximo
indicado en su definición.
• No todos los elementos (caracteres) de un string se considera que forman parte de la cadena de
caracteres en un momento dado: Sólamente aquellos cuyo índice esté comprendido entre 1 y
la longitudactual del string. La información referente a la longitud se obtiene mediante la función
predefinida length, y no puede cambiarse directamente, sino que se adapta automaticamente en las
operaciones de asignación entre cadenas de caracteres y al usar los operadores, funciones y
procedimientos predefinidos que actuan sobre cadenas de caracteres.
• Sólo puede accederse, en un momento dado, a aquellos elementos (caracteres) de un string cuyo
índice se encuentre comprendido entre 1 y la longitud actual del string (es decir, a aquellos
caracteres que forman parte de la cadena). Se debe tener en cuenta, además, que una cadena de
caracteres puede estar vacía (su longitud sea igual a cero).
• Existen literales de tipo cadena de caracteres.
• Se pueden definir funciones que devuelvan un valor de tipo cadena de caracteres.
• Existen operadores, funciones y procedimientos predefinidos que se aplican a cadenas de
caracteres (ver Operadores de string y Subprogramas predefinidos que se aplican a string).
• Se pueden leer y escribir directamente en dispositivos de tipo texto.
• En la versión de Turbo-Pascal que estamos usando no se pueden definir tipos string cuyo tamaño
máximo supere los 255 caracteres.

Tipo fichero
Los ficheros, al representar datos externos al programa y tener un acceso secuencial, tienen un tratamiento
distinto al de los otros tipos estructurados. Algunas de esas características especiales son:
Definición de ficheros:
• Las variables tipo fichero (denominadas ficheros lógicos, en contraposición con los ficheros físicos,
los ficheros reales) no almacenan los datos del fichero, sino que sirven de intermediario para poder
acceder a un determinado fichero físico.
• El tipo base de un fichero no puede ser a su vez un tipo fichero, puesto que no tiene sentido
almacenar ficheros lógicos.
• No se puede asignar a una variable tipo fichero el contenido de otra variable tipo fichero. No tiene
sentido el tener dos variables con la misma información de acceso a un fichero físico.
Consecuentemente, tampoco es posible que varias variables tipo fichero tengan asignado y abierto,
simultaneamente, el mismo fichero físico.
• Debido a lo anterior, al pasar un fichero como parámetro a un subprograma siempre es necesario
hacerlo por variable (un paso por valor es equivalente a una asignación).
Uso de ficheros:

• El acceso a los datos de un fichero se debe hacer mediante una serie fija de etapas (asignación de
un fichero físico a un fichero lógico, apertura del fichero para lectura o creación-escritura,
comprobación de fin de fichero-lectura de datos o escritura de datos, y cierre del fichero) que
requieren la utilizacion de subprogramas predefinidos para acceso a ficheros.
• Un fichero sólo se puede abrir o bien para lectura o bien para creación-escritura. No se puede leer y
escribir simultaneamente en un fichero.
• Abrir un fichero para escritura supone crear un fichero físico nuevo y vacío. Si previamente existía
un fichero físico con el mismo nombre, los datos que contenía se pierden al abrirlo para escritura.
Por lo tanto no es posible añadir datos nuevos al final de un fichero abriendolo para escritura, es
necesario usar otros medios (usar ficheros auxiliares, por ejemplo).
• No es posible conocer anticipadamente el número de elementos de un fichero físico. Por lo tanto,
antes de cualquier lectura de un dato es necesario haber comprobado que realmente quedan datos
por leer en el fichero (mediante la fúncion eof).
• Cualquier fichero puede estar vacío, por lo tanto no es posible aplicar directamente tecnicas de
lectura adelantada sobre ficheros.
• Cualquier modificación del contenido de un fichero físico requiere la utilización de ficheros auxiliares.

Tipos de datos
La tabla siguiente muestra características de los tipos de datos predefinidos de Turbo-Pascal:

Tipo de dato Simple Ordinal Elemental Imprimible Literales Acceso


Entero Si Si Si Si Si -
Real Si No Si Si Si -
Carácter Si Si Si Si Si -
Lógico Si Si Si No Si -
Enumerado Si Si Si No Si -
Subrango Si Si Si (1) Si -
Puntero Si No Si No No -
Array No No No No No Por índice
Registro No No No No No Por campo
Fichero No No No No No Secuencial
Conjunto No No No No Si (2)
String No No Si Si Si Por índice
1. Igual que el tipo de datos del que es subrango.
2. Un conjunto tan solo permite preguntar si un valor pertenece o no en un momento dado al conjunto.
Significado de las columnas:
• Elemental: Se pueden definir funciones que devuelvan este tipo de datos.
• Imprimible: Se puede leer o escribir valores de este tipo de datos directamente en dispositivos de
tipo texto (usando read, readln, write o writeln).
• Literales: Se pueden especificar directamente valores de este tipo de datos.
• Acceso: Para tipos estructurados, la estrategia de acceso a sus elementos.
Variables dinámicas
A la hora de trabajar con variables dinámicas es necesario asegurarse de que la dirección almacenada en la
variable puntero corresponde realmente a la de una variable dinámica, puesto que Pascal no verifica que
sea así: Si usamos una dirección incorrecta, podemos inadvertidamente estar cambiando el valor de otras
variables dinámicas, estáticas o incluso el propio código de nuestro programa o el de cualquier otro que se
esté ejecutando en el ordenador.
Para que esto no ocurra, es necesario asegurarse de que al puntero usado para acceder a la variable
dinámica le ha sido asignado una dirección válida mediante una llamada al procedimiento new o por una
asignación de un puntero que almacenaba una dirección válida.
Tras la llamada al procedimiento dispose, la dirección que almacena el puntero proporcionado deja de ser
válida (la memoria que ocupaba la variable dinámica situada en esa dirección se libera y pasa a estar
disponible para otros usos).

Tipo puntero
La definición de un tipo puntero tiene dos partes diferenciadas:
Tipo puntero ::= ^ <Tipo de dato asociado>
• El acento circumflejo (^) significa que las variables de este tipo de datos son punteros, y por lo tanto
almacenarán direcciones de memoria.
• El tipo de datos asociado no tiene nada que ver el tipo puntero que se esta definiendo: Tan sólo
sirve para indicar el tipo de datos que almacenaría una hipotetica variable dinámica cuya dirección
estuviera almacenada en una variable de este tipo puntero.
Las variables de tipo puntero almacenan direcciones de memoria. No es necesario que conozcamos qué
es exactamente una dirección de memoria, sino tan solo que mediante esos valores es posible hacer
referencia a variables dinámicas.
La dirección almacenada en un puntero puede ser, en un momento dado, válida o no válida. Es válida
cuando represente la dirección de una variable dinámica existente.
Una variable dinámica existe cuando ha sido creada mediante una llamada al procedimiento new, y todavia
no ha sido destruida mediante una llamada al procedimiento dispose.
Es necesario tener en cuenta que los valores de tipo puntero son un mero intermediario para permitir el
trabajar con variables dinámicas, y que no guardan más relación con ellas que las de almacenar su
dirección.

Orden de las zonas de declaraciones


Turbo-Pascal permite que escribamos las zonas de declaraciones en cualquier orden, e incluso repitamos
zonas en sitios distintos. Para los programas desarrollados en el marco de la asignatura se va a imponer, sin
embargo, la siguiente restricción: Sólo debe existir una zona de declaración de variables y debe estar
situada despues de cualquier declaración de subprogramas.
De esta forma se garantiza que ningún subprograma puede hacer uso de variables globales a él,
cumpliendo la regla de la programación modular que establece que los módulos deben ser independientes
(respecto a los datos que manejan) entre sí.

Subprogramas predefinidos de propósito general


Operaciones matemáticas:

Subprograma Tipo Parámetros Resultado


abs(x) Función x de tipo entero o real El valor absoluto de x
odd(x) Función x de tipo entero true si x es impar, false si es par
random(x) Función x de tipo entero Un entero entre 0 y x - 1, escogido al azar
sin(x) Función x de tipo real El seno de x (x son radianes)
cos(x) Función x de tipo real El coseno de x (x son radianes)
arctan(x) Función x de tipo real El arcotangente de x, expresado en radianes
ln(x) Función x de tipo real El logaritmo neperiano de x
exp(x) Función x de tipo real La exponencial de x (ex)
Operaciones de conversión entre tipos:

Subprograma Tipo Parámetros Resultado


chr(x) Función x de tipo entero El carácter en la posición x de la tabla de caracteres
trunc(x) Función x de tipo real La parte entera de x
round(x) Función x de tipo real El valor entero más cercano a x
Operaciones ordinales:

Subprograma Tipo Parámetros Resultado


ord(x) Función x de tipo ordinal La posición del valor x en su tipo de datos (1)
succ(x) Función x de tipo ordinal El valor siguiente de su mismo tipo
pred(x) Función x de tipo ordinal El valor anterior de su mismo tipo
(1) En el caso de argumentos enteros, ord devuelve su mismo valor. En el resto de casos, devuelve la
posición del valor comenzando a contar por cero. Nota: La función ord no tiene en cuenta si el argumento
proviene o no de una variable de tipo subrango.

Subprogramas predefinidos relativos a strings

Subprograma Tipo Parámetros Resultado


length(c) Función c valor de tipo string Longitud de la cadena
c valor de tipo string La subcadena de c que comienza a partir
copy(c,i,n) Función
i,n de tipo entero de la posición i y tiene longitud n
s valor de tipo string
Inserta la subcadena s en la cadena c
insert(s,c,i) Procedimiento c variable de tipo string
a partir de la posición i
i de tipo entero
c variable de tipo string Elimina de c la subcadena que comienza
delete(c,i,n) Procedimiento
i,n de tipo entero a partir de la posición i y tiene longitud n
La primera posición de c donde aparece
pos(s,c) Función s, c valor de tipo string
la subcadena s, o cero si no aparece

Subprogramas predefinidos relativos a ficheros

Subprograma Tipo Parámetros Resultado


f de tipo fichero
assign(f,c) Procedimiento Asigna un fichero físico a un fichero lógico
c de tipo string
reset(f) Procedimiento f de tipo fichero Abre un fichero para lectura
rewrite(f) Procedimiento f de tipo fichero Abre un fichero para creación-escritura
false si quedan datos por leer
eof(f) Función f de tipo fichero de datos
true si no quedan datos por leer
false si quedan lineas
eof(f) Función f de tipo fichero de texto
true si no quedan lineas
false si quedan caracteres en la linea actual
eoln(f) Función f de tipo fichero de texto
true si no quedan caracteres en la linea actual
f de tipo fichero de datos
read(f,v) Procedimiento Lee un dato del fichero y lo asigna a la variable
v variable de tipo base
f de tipo fichero de texto Lee caracteres, los traduce a un valor
read(f,v) Procedimiento
v variable de tipo imprimible del tipo de la variable y se lo asigna
Igual que read, y además pasa a la siguiente linea
f de tipo fichero de texto
readln(f,v) Procedimiento ignorando los caracteres que quedan en la linea
v variable de tipo imprimible
actual
Pasa a la siguiente linea ignorando los
readln(f) Procedimiento f de tipo fichero de texto
caracteres que quedan en la linea actual
f de tipo fichero de datos Escribe en el fichero el dato
write(f,v) Procedimiento
v variable de tipo base almacenado en la variable
f de tipo fichero de texto
Traduce el valor resultante de la expresión a una
write(f,e) Procedimiento e expresión de tipo
secuencia de caracteres y la escribe en el fichero
imprimible
f de tipo fichero de texto
Igual que write, y además escribe los
writeln(f,e) Procedimiento e expresión de tipo
caracteres que indican el final de linea
imprimible
writeln(f) Procedimiento f de tipo fichero de texto Escribe los caracteres que indican el final de linea
close(f) Procedimiento f de tipo fichero Cierra un fichero

También podría gustarte