Versión PostScript | Versión PDF |
<dígito> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <letra mayúscula> ::= 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 minúscula> ::= 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
En la descripción pueden usarse términos ya descritos:
<letra> ::= <letra mayúscula> | <letra minúscula>
Los símbolos de llave { y } encierran en la parte de descripción elementos que pueden aparecer una serie de veces o ninguna:
<entero positivo> ::= <dígito>{<dígito>}
Los gráficos de Conway realizan la descripción mediante el recorrido de un grafo:
Con los símbolos del alfabeto se construyen palabras (también llamadas componentes léxicos o ``token''). El conjunto de palabras constituye el léxico del lenguaje.
El léxico del Pascal está constituído por:
and array begin case const div do downto else end file for function goto if in label mod nil not of or packed procedure program record repeat set then to type until var while withademás de las 24 siguientes, formadas por uno o varios caracteres especiales
+ - * / := . , ; : ' = <> < <= >= > ( ) [ ] { } ^ ..
<identificador>::= <letra> {<letra>|<letra>|<dígito>}
En teoría pueden ser de cualquier longitud, aunque en la práctica, normalmente los sistemas la limitan a un número, que será igual o superior a 8 si se respeta el ``estándar''.
Por ejemplo: integer, real, boolean, read, readln, sin, cos, TRUE
...
<dígitos> ::= <dígito>{<digito>} <fracción opt.> ::= .<dígitos> | <signo opt.> ::= + | - | <parte exp. opt.> ::= e <signo opt> <dígitos> | E <signo opt> <dígitos> | <número sin signo>::= <dígitos><fracción opt.><parte exp. opt.>Por ejemplo: 123 123.23 1.2312E-2
'Resolver ecuación ax^2
+ bx + c = 0 con a no nulo'
'Esto es un ejemplo de cadena con una comilla '' simple'
Salvo para el caso de las cadenas literales, no se distingue entre mayúsculas y minúsculas.
Con estos elementos se contruyen las frases (sentencias o intrucciones), constituyendo la sintaxis. El símbolo ; separa una sentencia de la siguiente. Normalmente, para facilitar la legibilidad, se escribe cada sentencia en una línea, pero esto no es obligatorio.
La sintaxis completa del Pascal puede encontrarse en varias referencias (por ejemplo en la página web de la asignatura).
El Pascal que se definió inicialmente se conoce como Pascal estándar, y puede encontrarse en el documento ``PASCAL. Manual del usuario e informe'' de Jensen y Wirth (1975). Las implantaciones prácticas (compiladores) pueden ampliar el léxico y la sintaxis pero deben respetar las especificaciones de dicho estándar.
Por ejemplo: un programa se define cuando se codifica, y se usa cuando se ejecuta.
program PrimerEjemplo (output); (* Área de un círculo de radio 2'5 *) const PI = 3.141592; var radio, area : real ; BEGIN writeln ('Considerando el valor de PI como ', PI); radio = 2.5 ; area := PI * radio * radio; writeln ('el área de un círculo de radio', radio, ' es ', area) END.
En la primera línea se declara el programa, dando su nombre (PrimerEjemplo) y su tipo (program (output): programa que tiene salidas pero no entradas). A continuación, se describen los datos y las acciones, constituyendo el contenido (o valor) del programa (Algoritmos + estructuras de datos = programas).
Esta primera línea consta de una frase de 7 palabras separadas entre sí por espacios, y el punto y coma que separa la frase de la siguiente, que está en la siguiente línea. Las 7 palabras son la palabra reservada program, el identificador que le da nombre, los identificadores predefinidos input y output, los paréntesis y la coma.
<declaración de programa> ::= program <identificador> | program <identificador> (<lista de dispositivos>)La segunda línea es un comentario que el compilador ignorará, pero que el lector del programa agradecerá.
La tercera línea define una constante de nombre PI, valor 3.141592 y tipo real (lo determina el valor en este caso).
La cuarta línea declara dos variables de nombres respectivos radio y area y tipo real.
Las acciones a realizar se encuadran en una única sentencia compuesta enmarcada entre las palabras reservadas BEGIN y END, siendo el punto la marca de fin de programa. Como PI ya está definida, puede usarse para mostrar su valor (en la línea 6). La definición de la variable radio se realiza mediante asignación (a 2'5, en la línea 7), y entonces puede usarse para asignar valor a la variable area (línea 8). Finalmente ambas se usan en una nueva sentencia de escritura (línea 9).
<declaración de variables> ::= var <lista de identificadores> : <tipo> { ; <lista de identificadores> : <tipo>}La asignación se realiza bien mediante una sentencia de asignación:
<sentencia de asignación> ::= <identificador> := <expresión>bien mediante una lectura del valor que proporcione en ese momento el usuario:
<sentencia de lectura> ::= readln (<lista de identificadores de variable>)(hay algunos otros modos, que se verán más adelante).
En el primer caso, la expresión está compuesta por constantes y variables previamente definidas, ligadas por operadores adecuados. En el segundo, el usuario debe proporcionar valores de los tipos de las variables a las que se asignarán. El valor de una variable puede cambiar a lo largo de la ejecución (de ahí el nombre de variable).
Una variable se usa en general para formar parte de una expresión (cuyo valor pro-ba-blemente se asignará a otra variable). Cuando se usa, significa el valor que tiene en ese momento. Una expresión tiene un tipo (determinado por sus operadores y operandos) y un valor (es una excepción de la necesidad de nombre, tipo y valor).
Una constante es un valor, que también se almacena en algún lugar. Puede tener nombre (como el caso de PI en el ejemplo) o no tenerlo (como el caso del 2.5 del ejemplo, otra excepción de la necesidad de nombre, tipo y valor). Pero tal valor no cambia en la ejecución (de ahí el llamarla constante).
Las constantes sin nombre pueden usarse sin declarar, puesto que el valor es lo que se usa directamente, y el tipo está determinado por dicho valor.
La definición de constantes con nombre se realiza mediante una sentencia
<definición de constantes> ::= const <identificador> = <valor constante> { , <identificador> = <valor constante>}
En el uso, al igual que en el de las variables, significan su valor. Existen
a veces constantes predefinidas. En Pascal, por ejemplo, MAXINT es una
constante entera cuyo valor depende de la implantación y es el del mayor número
entero positivo representable (al menos
).
En este segundo ejemplo, el programa es algo más útil: se le pide al usuario el valor del radio.
program SegundoEjemplo (input, output); (* Área de un círculo de radio dado por el usuario*) const PI = 3.141592; var radio, area : real ; BEGIN writeln ('Escriba un valor para el radio de un círculo'); readln (radio); writeln ('Considerando el valor de PI como ', PI); area := PI * radio * radio; writeln ('el área de un círculo de radio', radio, ' es ', area) END.
De algún modo, un tipo es una forma del lugar de almacenamiento, que determina las operaciones realizables con los datos que pueda contener. Por ejemplo, se pueden sumar enteros, pero no se pueden sumar caracteres.
En los lenguajes existe una serie de tipos predefinidos, y normalmente una forma de permitir que el programador defina los suyos propios. Entre los tipos predefinidos habrá números enteros, reales, caracteres, cadenas de caracteres, etc.
Por ejemplo, en Pascal, el tipo entero está predefinido, caracterizado por su nombre: integer, el conjunto de valores posibles: los números enteros de un intervalo dado, normalmente [-(MAXINT+1), MAXINT], y un conjunto de operaciones que incluyen la suma (+), la diferencia y cambio de signo (-), el producto (*), la división entera (DIV) y el resto de dicha división (MOD).
<sentencia de lectura> ::= read (<fichero>, <lista de identificadores de variable>) | readln (<fichero>, <lista de identificadores de variable>) | readln (<fichero>)
Si la vía de entrada es el fichero input, éste puede omitirse, y la sintaxis se reduce a:
<sentencia de lectura> ::= read (<lista de identificadores de variable>) | readln (<lista de identificadores de variable>) | readln
El programa esperará a que el usuario escriba valores suficientes para asignarlos a las variables según el orden. La separación entre los valores se hace mediante espacios en blanco o avances de línea (return). El control de la ejecución está en manos del usuario hasta que éste pulse la tecla de avance de línea.
Si hay más valores en la entrada de los requeridos, quedarán almacenados en una zona de memoria intermedia para posteriores lecturas.
Es responsabilidad del usuario proporcionar datos de los tipos que se esperan. En caso contrario, no está especificado en el estándar qué se hará. Por ello es siempre recomendable que antes de las lecturas, se informe al usuario claramente de lo que se espera.
En el caso de la instrucción readln, una vez satisfechas las asignaciones, se omiten todos los datos que aparezcan en la línea de entrada, de forma que los siguientes accesos para lectura se harán en la línea siguiente.
La instrucción readln sin lista de variables esperará hasta que el usuario pulse un avance de línea (si es que no estaba almacenada tal pulsación en la zona de memoria intermedia de entrada). Suele usarse para forzar una pausa controlada por el usuario.
<sentencia de escritura> ::= write (<fichero>, <lista de expresiones>) | writeln (<fichero>, <lista de expresiones>) | writeln (<fichero>)
<sentencia de escritura> ::= write (<lista de expresiones>) | writeln (<lista de expresiones>) | writeln
La forma en la que se imprimen los valores calculados depende del tipo de la expresión, según lo predefine el sistema. Por ejemplo, los enteros se mostrarán siempre en una cantidad fija de posiciones; los reales también, lo que forzará en algunos casos a utilizar la notación de punto flotante, formada por un coeficiente y un factor de escala (notación ``científica''). Este comportamiento puede modificarse especificando después de la expresión uno o dos parámetros de ancho de campo, que son expresiones de tipo entero, en la forma:
<expresión para imprimir>::= <expresión> | <expresión>:<m> | <expresión>:<m>:<n>
Si aparece el primer parámetro (m), y la representación del dato a escribir ocupa menos de m posiciones, se añaden espacios hasta llegar a m. El segundo, n, se emplea para especificar el número de cifras decimales de los números reales. Si no se especifica, se elegirá una representación de punto flotante o no, según el valor a representar. Las implantaciones concretas de Pascal pueden ampliar el significado de estos parámetros.
Aunque no sea documentación propiamente dicha, es importante mantener una disposición de código clara, con indentaciones que respeten la estructura de acciones y líneas en blanco que faciliten la visión global, así como elegir nombres significativos para nombrar elementos. Esta adecuada elección de nombres en muchas ocasiones hará innecesaria la explicación del significado de dichos elementos (por ejemplo: si una variable se llama VelocidadInicial no habrá que explicar para qué se usa, y siempre que se use en el código se recordará su significado; pero la situación cambia si se llama x).