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 asignatura Programació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.

Definiciones:


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:

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:

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:

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:

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:

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:

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:

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:

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

Evaluación de expresiones

El orden de evaluación de los elementos de una expresión sigue las siguientes normas:

Para que una expresión pueda evaluarse se deben dar las siguientes condiciones:

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:

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:

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: Uso de ficheros:

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:

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>

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

Subprogramas predefinidos relativos a ficheros

 Subprograma   Tipo   Parámetros   Resultado 
 assign(f,c  Procedimiento   f de tipo fichero
c de tipo string 
 Asigna un fichero físico a un fichero lógico 
 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 
 eof(f  Función   f de tipo fichero de datos   false si quedan datos por leer
true si no quedan datos por leer 
 eof(f  Función   f de tipo fichero de texto   false si quedan lineas
true si no quedan lineas 
 eoln(f  Función   f de tipo fichero de texto   false si quedan caracteres en la linea actual
 true si no quedan caracteres en la linea actual 
 read(f,v  Procedimiento   f de tipo fichero de datos
 v variable de tipo base 
 Lee un dato del fichero y lo asigna a la variable 
 read(f,v  Procedimiento   f de tipo fichero de texto
 v variable de tipo imprimible 
 Lee caracteres, los traduce a un valor
 del tipo de la variable y se lo asigna 
 readln(f,v  Procedimiento   f de tipo fichero de texto
 v variable de tipo imprimible 
 Igual que read, y además pasa a la siguiente linea
 ignorando los caracteres que quedan en la linea actual 
 readln(f  Procedimiento   f de tipo fichero de texto   Pasa a la siguiente linea ignorando los
 caracteres que quedan en la linea actual 
 write(f,v  Procedimiento   f de tipo fichero de datos
 v variable de tipo base 
 Escribe en el fichero el dato 
 almacenado en la variable 
 write(f,e  Procedimiento   f de tipo fichero de texto
 e expresión de tipo imprimible 
 Traduce el valor resultante de la expresión a una 
 secuencia de caracteres y la escribe en el fichero 
 writeln(f,e  Procedimiento   f de tipo fichero de texto
 e expresión de tipo imprimible 
 Igual que write, y además escribe los 
 caracteres que indican el final de linea 
 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