enunciado

Anuncio
PRÁCTICA DE PROCESADORES DE LENGUAJE
EVALUACIÓN CONTINUA
CURSO 2009/2010
OBJETIVO DE LA PRÁCTICA
El objetivo de la práctica es desarrollar un compilador utilizando las herramientas flex y bison y
el leguaje de programación C. El lenguaje fuente que se compila es diseñado por el alumno y
debe cumplir las especificaciones que el profesor le haya comunicado y el lenguaje destino es el
ensamblador NASM. Dado que se van a describir varias versiones del lenguaje, a lo largo de
este enunciado vamos a llamar ALFAi, de forma genérica, a cada una de ellas.
PARTE 1: DISEÑO DEL LENGUAJE
En cada grupo de prácticas, el profesor asignará a cada equipo de alumnos uno de los lenguajes
ALFAi descritos en este enunciado.
En esta primera parte de la práctica debe diseñar una gramática independiente del contexto
completa para un lenguaje ALFAi que cumpla con la descripción que se le proporcione.
Para entregar la gramática al profesor debe escribir un fichero de texto plano con el siguiente
formato:
[TERMINALES]
Una línea para cada terminal
[NO TERMINALES]
Una línea para cada no terminal
[AXIOMA]
Una línea para el axioma
[REGLAS]
Una línea para cada regla. Cada regla se representará con el no terminal de su parte izquierda,
seguido de dos puntos, y a continuación los símbolos (terminales y no terminales) de la parte
derecha separados entre ellos por un espacio en blanco. Para las reglas lamba, la parte derecha
se dejará vacía.
En la tabla adjunta se muestra un ejemplo de gramática y su correspondiente fichero de
especificación.
Gramática
<exp> →<exp> + <exp>
<exp> →<exp> - <exp>
<exp> → <cte>
<cte> → <digito>
<cte> → <digito> <cte>
<digito> → 0 1
Fichero de especificación
[TERMINALES]
+
0
1
[NO TERMINALES]
exp
cte
digito
[AXIOMA]
exp
[REGLAS]
exp : exp + exp
exp : exp - exp
Gramática
Fichero de especificación
exp : cte
cte : digito
cte : digito cte
digito :0
digito :1
NORMAS DE ENTREGA
Debe entregar mediante la web de entregas de prácticas de la escuela un fichero
empaquetado (.zip) que deberá cumplir los siguientes requisitos:
•
•
El fichero zip deberá contener la plantilla anteriormente descrita para la
gramática del lenguaje que se le ha asignado.
El nombre del fichero zip será gr_gg_pp.zip, donde gg corresponde al grupo de
prácticas y pp al número del equipo. Por ejemplo, el fichero comprimido del
equipo 5 del grupo Ma se llamará gr_ma_05.zip
PARTE 2: ANÁLISIS MORFOLÓGICO Y CASOS DE PRUEBA
Tras comprobar con su profesor en el laboratorio que su gramática es adecuada, debe completar
en esta segunda parte de la práctica el analizador morfológico que utilizará el compilador final y
el diseño y codificación de los casos de prueba necesarios.
CASOS DE PRUEBA
Sus casos de prueba son un conjunto de programas que sigan la sintaxis descrita en su gramática
y la semántica habitual en los lenguajes de programación completada por la descripción que se
proporciona más adelante en este enunciado.
Los casos de prueba están divididos en dos partes:
• Los comunes a todos los compiladores (7 casos)
• Los específicos para cada uno de ellos (3 casos)
Casos de prueba comunes
En la tabla adjunta se describen los 7 casos de prueba comunes a todos los compiladores junto
con un ejemplo en ALFA. Es muy importante respetar los nombres que aparecen en la tabla de
los ficheros que contienen los programas de prueba.
Descripción del caso de prueba
Ejemplo en ALFA
Fichero: ej_aritmeticas1.alf
// Tratamiento de operaciones aritmeticas
Comentario con el siguiente texto: Tratamiento
de operaciones aritméticas.
main
{
Declaración de 2 variables enteras o reales
(dependiendo del compilador): x, y.
int x, y;
Lectura de los valores de dichas variables.
Impresión de resultado de sumar, restar,
multiplicar y dividir dichas variables.
Impresión de resultado de negar la variable x.
Fichero: ej_aritmeticas2.alf
Comentario con el siguiente texto: Tratamiento
de operaciones aritmeticas, comprobando la
precedencia de operandos
Declaración de 3 variables enteras o reales
(dependiendo del compilador): x, y, z.
Lectura de los valores de dichas variables.
Impresión de: x+y*z
Impresión de: (x+y)*z
Impresión de: -x*y*-z
scanf x;
scanf y;
printf x+y;
printf x-y;
printf x*y;
printf x/y;
printf -x;
}
// Tratamiento de operaciones aritmeticas,
// comprobando la precedencia de operandos
main
{
int x, y, z;
scanf x;
scanf y;
scanf z;
printf x+y*z;
printf (x+y)*z;
printf -x*y*-z;
}
Descripción del caso de prueba
Ejemplo en ALFA
Fichero: ej_funciones1.alf
// Tratamiento de funciones: suma
Comentario con el siguiente texto: Tratamiento
de funciones: suma
main
{
int z;
Declaración de 1 variable entera o real
(dependiendo del compilador): z.
Una función llamada "suma" que lea 2
argumentos de entrada, los sume y devuelva el
resultado.
En el programa principal llamada a esa función,
siendo sus argumentos 2 constantes.
function int suma(int x ; int y)
{
int s;
s=x+y;
return s;
}
En el programa principal impresión del resultado
de esa función.
z=suma(2,3);
printf z;
}
Fichero: ej_funciones2.alf
// Tratamiento de funciones: factorial
Comentario con el siguiente texto: Tratamiento
de funciones: factorial
main
{
int z;
Declaración de 1 variable entera o real
(dependiendo del compilador): z.
Una función llamada "factorial" que lea 1
argumento de entrada y calcule su factorial de
forma recursiva.
En el programa principal llamada a esa función,
siendo su argumento una constante.
En el programa principal impresión del resultado
de esa función.
function int factorial (int n)
{
if (n==0) {
return 1;
} else {
return (n*factorial(n-1));
}
}
z=factorial(6);
printf z;
}
Descripción del caso de prueba
Fichero: ej_ifs1.alf
Comentario con el siguiente texto: Tratamiento
de sentencias condionales (if). Ubica un punto
(x, y) en un cuadrante (1, 2, 3, 4) o en los ejes (0)
Declaración de 2 variables enteras o reales
(dependiendo del compilador): x, y.
Ejemplo en ALFA
// Tratamiento de sentencias condionales (if)
// Tratamiento de sentencias condionales (if).
// Ubica un punto (x, y) en un cuadrante (1, 2, 3,
4)
// o en los ejes (0)
main
{
int x, y;
Lectura de los valores de dichas variables.
Serie de sentencias que permitan realizar los ifs
para identificar el cuadrante:
x>0, y>0 --> cuadrante 1
x>0, y<0 --> cuadrante 2
x<0, y<0 --> cuadrante 3
x<0, y>0 --> cuadrante 4
x==0 --> eje 0
y==0 --> eje 0
scanf x;
scanf y;
if (x>0) {
if (y>0) {
printf 1;
} else {
if (y==0) {
printf 0;
} else {
printf 2;
}
}
} else {
if (x==0) {
printf 0;
} else {
if (y>0) {
printf 4;
} else {
if (y==0) {
printf 0;
} else {
printf 3;
}
}
}
}
}
Descripción del caso de prueba
Fichero: ej_logicas1.alf
Comentario con el siguiente texto: Tratamiento
de sentencias logicas. Salida: false true false
Ejemplo en ALFA
// Tratamiento de sentencias logicas
// Salida: false true false
main
{
Declaración de 3 variables lógicas: a, b,
resultado.
boolean a, b, resultado;
Asignación de los siguientes valores: a <- true, b
<- false.
a=true;
b=false;
Asignación: resultado <- a and b.
resultado=(a && b);
printf resultado;
Impresión de resultado.
Asignación: resultado <- a or b.
Impresión de resultado.
Asignación: resultado <- not a.
Impresión de resultado.
Fichero: ej_logicas2.alf
Comentarios con el siguiente texto: Tratamiento
de sentencias logicas, comprobando la
precedencia de operandos. Salida: true false false
true
Declaración de 4 variables lógicas: a, b, c,
resultado.
Asignación de los siguientes valores: a <- true, b
<- false, c <- false.
resultado=(a || b);
printf resultado;
resultado=(!a);
printf resultado;
}
// Tratamiento de sentencias logicas,
comprobando
// la precedencia de operandos
// Salida: true false false true
main
{
boolean a, b, c, resultado;
a=true;
b=false;
c=false;
Asignación: resultado <- a or b and c.
Impresión de resultado.
Asignación: resultado <- a and b or c.
resultado=(a || b && c);
printf resultado;
resultado=(a && b || c);
printf resultado;
Impresión de resultado.
Asignación: resultado <- not a and b.
Impresión de resultado.
Asignación: resultado <- not (a and b).
resultado=(!a && b);
printf resultado;
resultado=(!(a && b));
printf resultado;
}
Impresión de resultado.
Casos de prueba específicos
En las tablas adjunta se describen los 3 casos de prueba específicos para cada uno de los 5
compiladores distintos. Es muy importante respetar los nombres que aparecen en la tablas de los
ficheros que contienen los programas de prueba.
Casos de prueba específicos del compilador ALFA1
Fichero: alfa1_especifico1.alf
Implementar un programa que imprima por pantalla los números que sean menores o iguales que 64,
que sean múltiplos de 4 y que sean múltiplos de 7. Para ello se deberán utilizar tres variables de tipo
conjunto. En la primera se introducirán los múltiplos de 4. En la segunda se introducirán los múltiplos
de 7 y en la tercera variable se almacenará la intersección de las dos primeras. Para la elaboración de
este programa deberán utilizarse una función que determine cuando un número es múltiplo de otro. La
salida del programa deberá ser:
28
56
Fichero: alfa1_especifico2.alf
Implementar un programa que imprima por pantalla los números menores o iguales que 64 y que sean
primos o que pertenezcan a la sucesión de Fibonacci. Para ello se utilizarán tres variables de tipo
conjunto. La primera almacenará los números primos. La segunda almacenará los números de la
sucesión de Fibonacci. La tercera variable almacenará la unión de las dos anteriores. Para la
elaboración de este programa deberán utilizarse una función que determine cuando un número es
primo. Además los números de la sucesión de Fibonacci deberán de ser generados por el propio
programa. La salida será:
0
1
2
...
55
59
61
Fichero: alfa1_especifico3.alf
Implementar un programa que lea diez números por la entrada estándar y luego imprima cuantos
números (sin repetición) han sido introducidos. Para elaborar dicho programa habrá que utilizar una
variable de tipo conjunto donde se irán almacenando los números. Una vez leídos los 10 números se
imprimirá el tamaño de la variable conjunto resultante. Por ejemplo, si se introducen los números 1, 2,
3, 4, 3, 6, 2, 1, 2 , 8, el programa imprimirá:
6
Casos de prueba específicos del compilador ALFA2
Fichero: alfa2_especifico1.alf
Implementar un programa que lea por la entrada estándar los elementos de una matriz cuadrada de
dimensión 3x3. Los elementos se introducirán en líneas distintas uno por uno y en el orden e11, e12,
e13, e21, e22, e23, e31, e32, e33 donde eij denota el elemento de la fila i y la columna j. El programa
pondrá la diagonal de dicha matriz a cero, multiplicará los elementos de la matriz por 2 y finalmente
imprimirá la fila y la columna de aquellos elementos que sean iguales a 7. Por ejemplo si e23 y e31
son los únicos elementos iguales a 7 tras la operación, el programa deberá imprimir:
2.000000
3.000000
3.000000
1.000000
Casos de prueba específicos del compilador ALFA2
Fichero: alfa2_especifico2.alf
Implementar un programa que lea por la entrada estándar las coordenadas de dos vectores de
dimensión 10 y luego calcule la distancia en el espacio euclídio de los dos puntos que representan
dichos vectores en el espacio 10-dimensional. Las coordenadas se introducirán de una en una en líneas
diferentes. Para calcular la raíz cuadrada de un número dado S se recomienda utilizar el método de
aproximación babilónico:
1 – Empezar con un valor positivo cualquiera x_0, por ejemplo 10.
2 – Fijar x_(n+1) al promedio de x_n y de S / x_n, es decir: x_(n+1) = 0.5 * (x_n + S / x_n).
3 – Repetir pasos 2,3 hasta que x_(n+1)^2 esté lo suficientemente cerca de S.
La salida del programa deberá ser una línea donde se imprima la distancia requerida.
Fichero: alfa2_especifico3.alf
Implementar un programa que lea por la entrada estándar las coordenadas de 4 vectores v1, v2, v3, y
v4 de dimensión 3. El programa deberá de calcular en primer lugar dos vectores v5 y v6, donde v5 es
el producto vectorial de v1 y v2 y v6 es el producto vectorial de v3 y v4. Finalmente el programa
imprimirá el resultado de calcular el producto escalar entre v5 y v6.
Casos de prueba específicos del compilador ALFA3
Fichero: alfa3_especifico1.alf
Implementar un programa que lea por la entrada estándar 20 números enteros, los almacene en una
lista y los ordene de menor a mayor mediante el algoritmo insert sort. La salida del programa serán los
20 números introducidos y ordenados, cada uno en una línea diferente. Para la ordenación se
recomienda utilizar listas auxiliares.
Fichero: alfa3_especifico2.alf
Implementar un programa que lea por la entrada estándar 10 números enteros y los almacene en una
lista. El proceso de almacenamiento deberá ser como se describe a continuación. Si el número es par,
el número se introducirá al principio de la lista. Si el número es impar, se almacenará al final de la
lista. La salida del programa serán los elementos de dicha lista imprimidos en un orden determinado
por otros 10 números enteros que se procederán a leer por la entrada estándar. Si el primero de este
segundo bloque de 10 números es múltiplo de 3, el primer elemento a imprimir será el que se
encuentre al principio de la lista. Si dicho número no es múltiplo de 3, el primer elemento a imprimir
será el que se encuentre al final de la lista, y así sucesivamente teniendo en cuenta que cada vez que se
imprima un elemento de la lista, éste se eliminará de dicha lista. Para la entrada de números 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 la salida seŕa la secuencia 9, 7, 10, 5, 3, 8, 1, 2, 6, 4, donde
los números se introducirán en líneas separadas y se imprimirán también en líneas separadas.
Fichero: alfa3_especifico3.alf
Implementar un programa que lea 10 números por la entrada estándar, los almacene al final de una
lista y luego se proceda a imprimir los elementos de dicha lista, empezando por el último y
terminando por el primero.
Casos de prueba específicos del compilador ALFA4
Fichero: alfa4_especifico1.alf
Implementar un programa que lea por la entrada estándar 20 números enteros donde el número 0 será
el equivalente al símbolo de paréntesis izquierdo “(“ y el número 1 será el equivalente al símbolo de
paréntesis derecho “)”. Utilizando una pila, el programa deberá determinar si los símbolos de
paréntesis codificados por 0 y 1 se encuentran balanceados. La salida del programa será el número 1 si
los paréntesis están balanceados y el número 0 en caso contrario.
Casos de prueba específicos del compilador ALFA4
Fichero: alfa4_especifico2.alf
Implementar un programa que utilizando una estructura de tipo pila evalúe una serie de operaciones
aritméticas introducidas en formato postfijo. La entrada será una lista de 19 números que
representarán bien operadores (número 0 y 1) u operandos (resto de números). Los números 0 y 1
corresponderán a los operadores de suma y multiplicación respectivamente, así la cadena de números
3 4 1 5 0 representará la cadena en postfijo 3 4 * 5 +. Los 19 números de entrada se introducirán en
líneas diferentes y la salida será el número resultado de evaluar la operación que dichos números
codifican en formato postfijo. Deberá utilizarse una pila para la evaluación de dicha operación. Así si
la entrada es la secuencia de números 2, 2, 1, 4, 3, 0, 7, 1, 9, 10, 1, 1, 13, 14, 0, 16, 1, 0, 1, la salida del
programa será el número 19368.
Fichero: alfa4_especifico3.alf
Implementar un programa que lea 20 números por la entrada estándar. Para cada número, se realizarán
las siguientes operaciones. Si el número es par, se introducirá el número 1 en la cima de una pila
inicialmente vacía. Si el número es impar se introducirá el número 0 en la cima de la pila. Una vez
procesados los 10 primeros números se volverán a leer otros diez números por la entrada estándar.
Para cada uno de las números pertenecientes a este segundo bloque de diez cifras se realizarán las
siguientes operaciones. Si el número es múltiplo de 5 y en la cima de la pila hay un 0 se eliminará
dicho 0 de la cima de la pila. Si por el contrario en la cima hay un 1 no se realizará ninguna operación.
Si el número no es múltiplo de 5 y en la cima de la pila hay un 0 o un 1 se eliminará de la pila el
contenido que este en la cima. Finalmente se imprimirá el contenido de la pila. Los números
proporcionados como entrada al programa requerido se introducirán de uno en uno en líneas
separadas. Para la entrada 2, 2, 1, 4, 3, 4, 7, 1, 9, 10, 1, 1, 13, 14, 3, 20, 1, 10, 1, 5 la salida del
programa será 1.
Casos de prueba específicos del compilador ALFA5
Fichero: alfa5_especifico1.alf
Implementar un programa que lea por la entrada estándar 20 números. Los almacene en una cola y
que cree una nueva cola cuyo contenido sea igual a la primera cola, pero con los elementos pares y los
impares intercambiados. Finalmente, se imprimirá el contenido de la segunda cola. Si la entrada al
programa es la secuencia de números 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
la salida será la secuencia de números 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15, 18, 17, 20, 19.
Los números proporcionados como entrada al programa requerido se introducirán de uno en uno en
líneas separadas. La salida será también en una línea por cada número.
Fichero: alfa5_especifico2.alf
Implementar un programa que lea por la entrada estándar 20 números enteros, los almacene en una
cola y los ordene de menor a mayor mediante el algoritmo insert sort. La salida del programa serán los
20 números introducidos y ordenados, cada uno en una línea diferente. Para la ordenación se
recomienda utilizar colas auxiliares. Los números proporcionados como entrada al programa
requerido se introducirán de uno en uno en líneas separadas.
Fichero: alfa5_especifico3.alf
Implementar un programa que lea por la entrada estándar 10 números. Y los almacene en una cola. A
continuación el programa volverá a leer otra serie de 10 números que representarán una permutación
sobre los primeros 10 números leídos. La salida del programa deberá de ser el resultado de aplicar
dicha permutación a la entrada original. Por ejemplo, si la entrada al programa es la cadena de
números 10, 1, 7, 9, 8, 3, 2, 4, 6, 5, 8, 5, 3, 1, 9, 6, 5, 7, 10, 2, 4. La salida deberá de ser la cadena de
números 4, 8, 7, 10, 6, 3, 8, 2, 5, 1, 9. Tanto la entrada como la salida se realizarán en lineas diferentes
para cada número.
ANALIZADOR MORFOLÓGICO
Para completar el analizador morfológico de su compilador debe seguir las indicaciones que se
describen a continuación.
Estudio de la Gramática
• Inicialmente se tratará de identificar en la gramática completa del lenguaje el conjunto
de unidades sintácticas o tokens existentes.
Codificación de una Especificación para flex
• El alumno deberá diseñar el conjunto de expresiones regulares que representa cada
unidad sintáctica.
• Observación muy importante: Recuerde que algunas tareas que el analizador léxico
puede y suele realizar son:
o Ignorar los espacios en blanco y tabuladores, que actúan como separadores
entre unidades sintácticas.
o Ignorar los comentarios, que no aportan código ejecutable al programa.
o Gestionar errores morfológicos.
• Se deberá escribir un fichero de nombre alfa.l que sea una especificación correcta para
la entrada de la herramienta flex.
• Se recomienda al alumno que se familiarice primero con flex mediante las explicaciones
que su profesor de prácticas realizará en su laboratorio y posteriormente diseñe el
conjunto final de expresiones regulares.
Codificación de un Programa de Prueba para el analizador morfológico
• Se deberá escribir (en C) un programa de prueba del analizador léxico generado con
flex, con los siguientes requisitos:
o Nombre del programa fuente: prueba_lexico.c
o Al ejecutable correspondiente se le invocará de la siguiente manera:
prueba_lexico [<nombre_fichero_entrada> [<nombre_fichero_salida>]]
o Es decir, el programa se puede ejecutar:
Con 0 argumentos: se utilizan la entrada y la salida estándares.
Con 1 argumento: se utiliza la salida estándar y el argumento como
nombre del fichero de entrada.
Con 2 argumentos: el primer argumento se interpreta como el nombre
del fichero de entrada y el segundo como el nombre del fichero de
salida.
o La estructura de los ficheros de entrada/salida se explican a continuación.
Descripción del Fichero de Entrada
• El fichero de entrada contiene un programa escrito en lenguaje ALFAi (no
necesariamente correcto).
Funcionalidad del Programa
• El programa de prueba, haciendo uso del analizador léxico construido con flex, deberá
identificar en el fichero de entrada las siguientes unidades sintácticas:
o Palabras reservadas: cualquier palabra reservada ALFAi correcta.
o Símbolos: cualquier símbolo ALFAi correcto.
o Identificadores: que sigan la sintaxis descrita en su gramática para la unidad
sintáctica asociada con los identificadores de variables.
o Constantes: cualquier número o dato constante de los tipos permitidos en
ALFAi.
o Cualquier otra cosa, se considerará errónea.
• Por cada unidad sintáctica identificada en el fichero de entrada, el programa de prueba
debe generar una línea en el fichero de salida según se describe a continuación.
Descripción del Fichero de Salida
• El fichero de salida se compone de un conjunto de líneas, una por cada unidad sintáctica
del fichero de entrada. La estructura de la línea es la siguiente:
o El primer elemento de la línea será, según corresponda
TOK_PALABRA_RESERVADA: para las palabras reservadas.
TOK_SIMBOLO: para los símbolos.
TOK_IDENTIFICADOR: para los identificadores.
TOK_CONSTANTE: para todas las constantes.
TOK_ERROR: para los errores. Será suficiente controlar la aparición
de caracteres no permitidos por el lenguaje e identificadores de longitud
no válida.
o El segundo elemento será un número entero, que identificará la unidad
sintáctica (debe ser distinto para cada unidad sintáctica). Debe codificar un
fichero tokens.h para contener los valores numéricos de los tokens de la
gramática de ALFAi.
o El tercer elemento será el lexema (el fragmento del programa fuente) analizado
como la unidad sintáctica correspondiente.
o Muy importante: cada elemento de la línea estará separado por un
tabulador y ningún otro carácter más.
Ejemplos
A continuación se muestran algunos ejemplos para algunos fuentes escritos en ALFA. Los
números asociados con cada token son también un ejemplo de posible numeración.
•
Ejemplo 1: Si el fichero de entrada es el siguiente:
// Programa que eleva un número entero al cuadrado
main {
int x, resultado;
scanf x;
resultado=x*x;
printf resultado;
}
El fichero de salida es el siguiente:
TOK_PALABRA_RESERVADA
TOK_SIMBOLO 300
{
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 306
,
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 309
=
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 303
*
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
200
main
201
x
int
resultado
213
x
scanf
resultado
x
x
214
printf
resultado
TOK_SIMBOLO 301
•
}
Ejemplo 2: Si el fichero de entrada es el siguiente:
// Programa que eleva un número x a la potencia y.
main {
int x, y;
int i, total;
scanf x;
scanf y;
i=1;
total=1;
while (i<=y) {
total=total*x;
i=i+1;
}
printf total;
}
El fichero de salida es el siguiente:
TOK_PALABRA_RESERVADA
TOK_SIMBOLO 300
{
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 306
,
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 306
,
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 309
=
TOK_CONSTANTE
501
TOK_SIMBOLO 302
;
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 309
=
TOK_CONSTANTE
501
TOK_SIMBOLO 302
;
TOK_PALABRA_RESERVADA
TOK_SIMBOLO 307
(
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 404
<=
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 308
)
TOK_SIMBOLO 300
{
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 309
=
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 303
*
200
main
201
x
int
y
201
i
int
total
213
x
scanf
213
y
scanf
i
1
total
1
211
i
y
total
total
while
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 309
=
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 312
+
TOK_CONSTANTE
501
TOK_SIMBOLO 302
;
TOK_SIMBOLO 301
}
TOK_PALABRA_RESERVADA
TOK_IDENTIFICADOR 500
TOK_SIMBOLO 302
;
TOK_SIMBOLO 301
}
x
i
i
1
214
total
printf
PARTE 3: ANÁLISIS SINTÁCTICO
Esta parte tiene como primer objetivo la codificación de un analizador sintáctico mediante el
uso del lenguaje de programación C y la herramienta de ayuda a la generación de analizadores
sintácticos bison.
Este analizador será utilizado por el compilador del lenguaje ALFAi que va a desarrollarse
durante el curso.
Para ello debe seguir las indicaciones que se describen a continuación.
Codificación de una especificación para bison
El alumno deberá escribir un fichero con nombre alfa.y que sea una especificación correcta para
la entrada de la herramienta bison. Se recomienda al alumno que se familiarice primero con
bison mediante las explicaciones que su profesor de prácticas realizará en su laboratorio.
Resolución de conflictos
Cuando se compile el fichero alfa.y pueden aparecer mensajes de conflictos. Estos conflictos se
refieren a los que encuentra el autómata a pila generado por la herramienta bison. Para obtener
información acerca de ellos, se debe compilar el fichero alfa.y de la siguiente manera:
bison -d -y -v alfa.y
con el flag -v se genera el fichero y.output que contiene la descripción completa del autómata y
de los conflictos (si existieran).
El alumno debe asegurarse de eliminar los conflictos siguiendo las indicaciones de su profesor
de prácticas.
Modificación de la especificación para flex
El alumno deberá modificar el fichero alfa.l de la primera parte para poder ser enlazado
con el fichero alfa.y. Para ello, utilizará como guía las explicaciones que su profesor de
prácticas realizará en su laboratorio.
Codificación de un programa de prueba
El alumno deberá escribir (en C) un programa de prueba del analizador sintáctico generado con
bison, con los siguientes requisitos:
• Nombre del programa fuente: prueba_sintactico.c
• Al ejecutable correspondiente, se le invocará de la siguiente manera:
prueba_sintactico [<nombre fichero entrada> [<nombre fichero salida>]]
• Es decir, el programa se puede ejecutar:
o Con 0 argumentos, entonces se utilizan la entrada y la salida estándares.
o Con 1 argumento, entonces se utiliza la salida estándar y el argumento como
nombre del fichero de entrada.
o Con 2 argumentos, entonces el primero se interpreta como el nombre del
fichero de entrada y el segundo como el nombre del fichero de salida.
• La estructura de los ficheros de entrada/salida se explica a continuación.
Descripción del fichero de entrada
El fichero de entrada contiene un programa escrito en lenguaje ALFAi (no necesariamente
correcto).
Descripción del fichero de salida
El fichero de salida se compone de un conjunto de líneas de dos tipos. En concreto:
• Una línea por cada TOKEN deplazado (reconocido) por el analizador léxico.
• Una línea por cada PRODUCCIÓN reducida en el proceso de análisis sintáctico.
Cada línea correspondiente a un TOKEN desplazado debe contener la siguiente información y
formato:
;D:
<token>
donde
• ; debe escribirse literalmente para que le sea cómodo gestionar la impresión de estos
textos en el compilador completo (corresponde con el símbolo de inicio de los
comentarios de línea en NASM)
• <token> es el fragmento de entrada reconocido por el analizador léxico
• D: y <token> van separados por un tabulador.
Cada línea correspondiente a una regla reducida tendrá el formato siguiente:
;R<nº regla>: <regla>
donde
• <nº regla> es el número que identifica la regla que se reduce en la gramática de ALFAi
diseñada en la primera parte por el alumno
• <regla> es el texto de la regla reducida según aparece en la gramática.
• R<nº regla> y <regla> van separados por un tabulador.
• Los elementos que forman <regla> irán separados por espacios.
Gestión de errores
Cuando se produzca un error sintáctico el analizador creado mediante bison deberá de imprimir
una línea por la salida estándar de error con el siguiente formato:
ERROR SINTACTICO:<nº linea>:<nº carácter>
donde
• <nº linea> es la línea en el fichero de entrada donde aparece el último TOKEN
reconocido por el analizador léxico y
• <nº carácter> es el carácter en la correspondiente línea donde empieza el último
TOKEN reconocido por el analizador léxico.
Cuando se produzca un error léxico, el analizador léxico implementado en la práctica 1 deberá
imprimir la siguiente línea por la salida estándar de error:
ERROR LEXICO:<nº linea>:<nº carácter>
donde
• <nº linea> es la línea en el fichero de entrada donde aparece donde aparece el TOKEN
erróneo y
• <nº carácter> es el carácter en la correspondiente línea donde empieza el TOKEN
erróneo.
En el caso de que se imprima un mensaje de error léxico, no deberá de imprimirse otro mensaje
de error sintáctico.
Ejemplo
Suponga que el siguiente programa está escrito en uno de los lenguajes de programación ALFAi
main {
int x, resultado;
scanf x;
resultado = x * x + 1.5 * 2;
printf resultado;
}
Una posible salida para su programa es la que se muestra a continuación (se supone que los
números de regla, etc. corresponden a una gramática correcta)
;D:
main
;D:
{
;D:
int
;R10: <tipo> ::= int
;D:
x
;R9: <clase_escalar> ::= <tipo>
;R5: <clase> ::= <clase_escalar>
;R106: <identificador> ::= TOK_IDENTIFICADOR
;D:
,
;D:
resultado
;R106: <identificador > ::= TOK_IDENTIFICADOR
;D:
;
;R18: <identificadores> ::= <identificador >
;R19: <identificadores> ::= <identificador> , <identificadores>
;R4: <declaracion> ::= <clase> <identificadores> ;
;D:
scanf
;R2: <declaraciones> ::= <declaracion>
;R21: <funciones> ::=
;D:
x
;R106: <identificador> ::= TOK_IDENTIFICADOR
;D:
;
;R54: <lectura> ::= scanf <identificador>
;R35: <sentencia_simple> ::= <lectura>
;R32: <sentencia> ::= <sentencia_simple> ;
;D:
resultado
;R106: <identificador > ::= TOK_IDENTIFICADOR
;D:
=
;D:
x
;R106: <identificador > ::= TOK_IDENTIFICADOR
;D:
*
;R80: <exp> ::= <identificador>
;D:
x
;R106: <identificador> ::= TOK_IDENTIFICADOR
;D:
+
;R80: <exp> ::= <identificador>
;R75: <exp> ::= <exp> * <exp>
;D:
1.5
;R105: <constante_real > ::= TOK_CONSTANTE_REAL
;R101: <constante> ::= <constante_real >
;R81: <exp> ::= <constante>
;D:
*
;D:
2
;R104: <constante_entera > ::= TOK_CONSTANTE_ENTERA
;R100: <constante> ::= <constante_entera>
;R81: <exp> ::= <constante>
;D:
;
;R75: <exp> ::= <exp> * <exp>
;R72: <exp> ::= <exp> + <exp>
;R43: <asignacion> ::= <identificador > = <exp>
;R34: <sentencia_simple> ::= <asignacion>
;R32: <sentencia> ::= <sentencia_simple> ;
;D:
printf
;D:
resultado
;R106: <identificador > ::= TOK_IDENTIFICADOR
;D:
;
;R80: <exp> ::= <identificador >
;R56: <escritura> ::= printf <exp>
;R36: <sentencia_simple> ::= <escritura>
;R32: <sentencia> ::= <sentencia_simple> ;
;D:
}
;R30: <sentencias> ::= <sentencia>
;R31: <sentencias> ::= <sentencia> <sentencias>
;R31: <sentencias> ::= <sentencia> <sentencias>
;R1: <programa> ::= main { <declaraciones> <funciones> <sentencias> }
PARTE 4: TABLA DE SÍMBOLOS
Esta parte tiene como objetivo la implementación de la tabla de símbolos de su compilador.
El alumno debe escribir los ficheros y módulos C que considere necesarios para la definición e
implementación de la tabla de símbolos. Para todas sus decisiones de diseño utilizará como
referencia las indicaciones que conoce de la parte de teoría y las explicaciones que su profesor
de prácticas realizará en su laboratorio.
Observaciones
•
•
Todos los lenguajes ALFAi tienen estructura de bloques
Observe que en ninguno de ellos pueden definirse funciones (ni otro tipo de bloques sin
nombre) dentro de una función por lo que como mucho se necesitará
o La tabla de símbolos del ámbito principal.
o La tabla de símbolos de la función activa.
Codificación de un programa de prueba
El alumno deberá escribir (en C) un programa de prueba del analizador sintáctico generado con
bison al que se incorpora la tabla de símbolos, con los siguientes requisitos:
• Nombre del programa fuente: prueba_tabla_simbolos.c
• Al ejecutable correspondiente, se le invocará de la siguiente manera:
prueba_tabla_simbolos [<nombre fichero entrada> [<nombre fichero salida>]]
• Los argumentos tienen el mismo significado de la parte anterior.
• La estructura de los ficheros de entrada/salida se explica a continuación.
Descripción del fichero de entrada
El fichero de entrada contiene un programa correcto escrito en lenguaje ALFAi.
Descripción del fichero de salida
A la salida de la parte 3 puede añadir, justo al término del proceso de las partes declarativas del
programa considerado el código NASM correspondiente a la declaración de las variables
contenidas en la tabla de símbolos.
Si se está escribiendo la tabla de símbolos del ámbito principal, la primera línea debe ser
; TABLA SÍMBOLOS PRINCIAL
Si se está escribiendo la tabla de símbolos de una función, la primera línea debe ser
; TABLA SÍMBOLOS FUNCIÓN
Debe asegurarse de comenzar cada una de las líneas con el símbolo “;” para que sean
comentarios NASM válidos. Esto le facilitará la construcción del compilador completo.
Debe seguir las indicaciones de su profesor de laboratorio respecto al formato de las
instrucciones NASM necesarias para esta tarea.
Ejemplo
Para el mismo fuente, y en los mismos supuestos del ejemplo de la parte anterior. La tabla de
símbolos del ámbito principal aparecería en la parte resaltada. Observe que la mayoría de las
líneas del fichero de salida han sido omitidas por claridad.
;D:
main
;D:
{
·
·
·
;R2: <declaraciones> ::= <declaracion>
; TABLA SÍMBOLOS PRINCIPAL
·
·
·
;
;D:
scanf
·
·
·
;R1: <programa> ::= main { <declaraciones> <funciones> <sentencias> }
PARTE 5: ANALIZADOR SEMÁNTICO Y GENERADOR DE CÓDIGO
El objetivo de esta práctica es finalizar la construcción del compilador para el lenguaje de
programación ALFAi. Para ello, se debe tomar como punto de partida el resultado de la parte 4.
El compilador final requerido deberá traducir programas escritos en lenguaje ALFAi a sus
equivalentes en ensamblador, es decir la entrada al compilador será texto que contenga un
programa ALFAi y la salida del compilador será texto que contenga instrucciones en lenguaje
ensamblador (NASM).
DESCRIPCIÓN DE LA SEMÁNTICA DE LOS LENGUAJES ALFAi
En esta descripción sólo se mencionarán los aspectos en los que los lenguajes ALFAi puedan
diferir de otros lenguajes de programación de alto nivel. Se sobreentienden por tanto reglas
semánticas como que las variables deben ser definidas antes de ser utilizadas, o que deben ser
únicas dentro de su ámbito de aplicación.
A continuación se muestran las descripciones correspondientes a todas las versiones del
lenguaje ALFAi de este año. Cada alumno sabe qué parte de las siguientes descripciones debe
tener en cuenta para su lenguaje concreto.
Cualquier duda respecto a la resolución de algún aspecto de la semántica del lenguaje ALFAi,
será resuelta por el profesor de prácticas.
Expresiones lógicas
Las restricciones semánticas relativas a las expresiones lógicas son las siguientes:
• En las expresiones lógicas sólo pueden aparecer datos de tipo lógico. Por lo tanto, todas
las subexpresiones, variables y constantes empleadas en una expresión lógica tienen que
ser de ese tipo.
• Debe incorporar los siguientes operadores:
o disyunción
o conjunción
o negación
Expresiones aritméticas
Las restricciones semánticas relativas a las expresiones aritméticas son las siguientes:
•
•
•
En las expresiones aritméticas sólo pueden aparecer datos de tipo numérico del
permitido en ALFAi. Por lo tanto, todas las subexpresiones, variables y constantes
empleadas en una expresión aritmética tienen que ser de esos tipos.
Los operadores binarios disponibles para operaciones aritméticas son los siguientes:
o suma,
o resta
o multiplicación
o división
El operador monádico (unario) disponible para operaciones aritméticas es el cambio de
signo.
Expresiones de comparación
Las expresiones de comparación están sujetas a las siguientes restricciones:
• Las comparaciones sólo pueden operar con datos de tipo numérico y el resultado de la
comparación es de tipo lógico.
•
Debe incorporar los siguientes operadores
o igualdad
o desigualdad (distinto)
o el primer operando menor o igual que el segundo
o el primer operando mayor o igual que el segundo
o el primer operando menor que el segundo
o el primer operando mayor que el segundo
Asignaciones
Las asignaciones válidas son aquellas en las que la parte izquierda y la derecha son del mismo
tipo, y no son tipos de datos estructurados (vectores, conjuntos, pilas, etc).
Semántica de los vectores
Las variables de tipo vector tienen la semántica habitual de los lenguajes de programación con
las siguientes peculiaridades:
• Sólo pueden contener datos de tipo básico.
• Sólo son de una o dos dimensiones.
• El tamaño de los vectores de una dimensión no podrá exceder nunca el valor de 64. Esta
misma restricción se aplica a cada una de las dimensiones de los vectores de dos
dimensiones.
• Para acceder a los elementos de los vectores (para cada una de sus dimensiones) se
utilizará cualquier expresión de tipo entero. Esta expresión debe tener un valor entre 0 y
el tamaño definido para el vector menos 1 (ambos incluidos).
• Tras la declaración de una variable de tipo vector, ésta aparecerá siempre indexada, y se
utilizará de la misma manera que cualquier otro objeto que pueda ocupar su misma
posición.
Semántica de los conjuntos
Un conjunto es una colección de elementos que tiene las siguientes propiedades:
• Todos los elementos son de tipo entero.
• Los elementos no mantienen una relación de orden.
• No hay elementos repetidos.
• Inicialmente un conjunto está vacío (tiene 0 elementos)
• El tamaño mínimo de un conjunto es 1, y el tamaño máximo es 64 elementos.
Se definen las siguientes operaciones sobre conjuntos:
• Unión
• Intersección
• Inserción
• Vaciado
• Tamaño
• Pertenencia
La unión y la intersección de conjuntos están sujetos a las siguientes restricciones:
• Estas operaciones deben especificar tres identificadores, uno almacenará el resultado de
la operación, y los otros dos son, los operandos.
• Los tres identificadores tienen que haber sido declarados como conjuntos.
• Respecto a las capacidades máximas de los tres conjuntos deben comprobarse las
siguientes restricciones semánticas:
Para la unión, el conjunto resultado debe tener una capacidad máxima mayor o
igual que la suma de las capacidades máximas de los operandos.
o Para la intersección, el conjunto resultado debe tener una capacidad máxima
mayor o igual que el mínimo de las capacidades máximas de los operandos.
El resto de la semántica de las operaciones es la de la unión e intersección de conjuntos
habitual en matemáticas.
o
•
La inserción de una expresión en un conjunto está sujeta a las siguientes restricciones:
• La expresión tiene que ser de tipo entero.
• El conjunto tiene que estar declarado.
• Si el conjunto no tiene espacio suficiente (está lleno antes de la inserción) debe
detectarse en tiempo de ejecución y salir del programa de manera controlada.
• Se insertará el valor de la expresión teniendo en cuenta la semántica de la operación de
conjuntos habitual en matemáticas: si la expresión ya está en el conjunto, tras la
inserción el conjunto realmente no cambia.
Vaciar un conjunto significa asignar 0 como el número de elementos que contiene.
• El tamaño de un conjunto se refiere al número de elementos que contenga (y no a la
capacidad máxima especificada en su declaración) y, por tanto, es de tipo entero.
La condición de pertenencia de una expresión a un conjunto está sujeta a las siguientes
restricciones:
• La expresión tiene que ser de tipo entero.
• El conjunto tiene que estar declarado.
• La condición de pertenencia de una expresión a un conjunto es de tipo lógico.
• El resto de la semántica de esta operación es la habitual en matemáticas.
Semántica de las listas, colas y pilas
Estas estructuras se refieren a las habituales que ya conoce de otras asignaturas. La tabla de
descripción de los lenguajes ALFAi contiene la lista de operaciones y el tipo de dato que las
estructuras tienen que soportar.
Estas estructuras deben poder contener (sin mezclar) los tipos de datos que en la tabla aparecen
como básicos.
Semántica de las estructuras de control de flujo de programa iterativas y
condicionales
La tabla de descripción de los lenguajes ALFAi contiene las estructuras que deben ser
implementadas en cada caso. Todas ellas son las habituales en otros lenguajes de programación
de alto nivel.
Semántica de las operaciones de entrada/salida
La operación de entrada lee datos escalares sobre elementos identificadores o elementos de
vectores.
Se distinguen dos tipos de operaciones de salida, las que operan sobre escalares, y las que
operan sobre colecciones. Se deben proporcionar dos operaciones distintas una para cada tipo de
salida
• La operación de escritura de datos de tipo escalar trabaja con expresiones de tipo lógico
o numérico.
• La escritura de un conjunto, lista, cola o pila, se realizará ubicando todos lo elementos
en la misma línea separados por un espacio en blanco. En el caso de las colas y las
•
listas, el primer elemento corresponderá al primer elemento de la estructura. Y en el
caso de las pilas, el primer elemento corresponderá a la cima de la estructura.
La escritura de un vector depende de la dimensión del mismo. Los vectores de una
dimensión se escribirán en una línea separando los elementos por un espacio en blanco.
Los vectores de dos dimensiones se escribirán en forma de tabla, con cada fila en una
línea diferente con los elementos separados por un espacio en blanco.
Semántica de las funciones
Las funciones tienen las siguientes características:
• Sólo se permiten funciones con retorno de tipos básicos (lógico o numérico)
• Los parámetros de las funciones sólo pueden ser de tipos básicos (lógico o numérico)
• Las variables locales de las funciones sólo pueden ser de tipo básico (lógico o
numérico)
• En las sentencias de llamadas a funciones, sólo es necesario comprobar la corrección
del número de argumentos. No es necesario realizar ninguna comprobación de la
correspondencia de tipos.
• En las llamadas a funciones, los parámetros actuales no pueden ser llamadas a otras
funciones.
Gestión de errores semánticos
Los errores semánticos se informarán en la salida estándar de error con el siguiente formato:
ERROR SEMÁNTICO:<nº linea>:<nº carácter>:<descripción del error>
A continuación se presenta un programa de ejemplo cuyo error semántico no depende del
lenguaje concreto utilizado (variable sin declarar)
main
{
int x;
printf y;
}
En la línea 4 aparece una referencia a la variable “y”, que no está declarada en la sección
declarativa. El compilador debe informar de este error semántico con un mensaje de error
similar al siguiente:
ERROR SEMÁNTICO:4:10: Intento de acceso a una variable no declarada (y)
GENERACIÓN DE CÓDIGO
El compilador debe traducir los programas válidos escritos en ALFAi a los correspondientes
programas en ensamblador NASM directamente, es decir, no se utilizará en la práctica ninguna
representación intermedia.
Esta generación de código se realizará mediante la asociación de acciones a la reducción de las
reglas de la gramática, descrita previamente en el analizador sintáctico.
En el laboratorio, se explicarán conceptos básicos de NASM para la realización de la práctica.
La gestión de la entrada y salida se realizará mediante la librería auxiliar (alfalib) disponible en
la página web de prácticas. El profesor de prácticas indicará el procedimiento a seguir para
utilizar dichas librerías.
INVOCACIÓN DEL COMPILADOR
El compilador deberá cumplir los siguientes requisitos:
•
•
Nombre del programa fuente que contenga la rutina principal (main) del compilador:
alfa.c
El ejecutable se invocará de la siguiente manera:
alfa [ <nombre fichero entrada> [<nombre fichero salida>] ]
•
Es decir, el programa se puede llamar:
o Con 0 argumentos, entonces se utilizan la entrada y la salida estándares.
o Con 1 argumento, entonces se utiliza la salida estándar y el argumento como
nombre del fichero de entrada.
o Con 2 argumentos, entonces el primero se interpreta como el nombre del
fichero de entrada y el segundo como el nombre del fichero de salida.
•
Descripción del fichero de entrada y de salida:
o
o
El fichero de entrada contiene un programa escrito en lenguaje ALFA.
El fichero de salida contiene un programa escrito en lenguaje ensamblador
NASM.
NORMAS DE ENTREGA
Debe entregar mediante la web de entregas de prácticas de la escuela un fichero
empaquetado (.zip) que deberá cumplir los siguientes requisitos:
•
•
•
•
•
El fichero zip deberá contener todos los fuentes (ficheros .h y .c) necesarios para
resolver el problema.
El fichero zip deberá contener las librerías auxiliares disponibles en la web de
prácticas.
El fichero zip también deberá contener los casos de prueba descritos en la parte
2 de este enunciado. Para el fichero de cada caso utilice los nombres indicados
en esa parte.
El fichero zip deberá contener un fichero Makefile compatible con la
herramienta make que para el objetivo all genere el ejecutable de nombre alfa.
El nombre del fichero zip será alfa_gg_pp.zip, donde gg corresponde al grupo
de prácticas y pp al número de pareja. Por ejemplo, el fichero comprimido de la
pareja 5 del grupo Ma se llamará alfa_ma_05.zip
OBSERVACIÓN MUY IMPORTANTE:
Las prácticas que, tras eliminar cualquier fichero con extensión .o así como el propio
ejecutable alfa (en el caso de que dichos ficheros aparezcan en la entrega), no compilen
mediante el comando make all, no generen el ejecutable alfa tras la ejecución de dicho
comando o no cumplan los requisitos descritos en este enunciado se considerarán como
no entregadas.
TABLA DE DESCRIPCIÓN DE LOS LENGUAJES
ALFA1
Tipos básicos
Identificadores
Constantes
Operaciones
aritméticas
Operaciones
lógicas
Comparaciones
Tipo
estructurado
Operaciones
tipo
estructurado
Condicional
Bucle
E/S
Lógico
Entero
Lógico
Entero
Real
Lógicas
Enteras
Lógicas
Reales
Conjunto
•
•
•
•
•
•
Inserción
Unión
Intersección
Pertenencia
Vaciado
Tamaño
Repeat
Lógico (E/S)
Entero (E/S)
Conjunto (S)
Funciones
Comentarios
ALFA2
ALFA3
Lógico
Entero
ALFA4
Lógico
Entero
Longitud menor o igual a 100 caracteres
Lógicas
Lógicas
Enteras
Entera
Suma, resta, multiplicación y división
Menos unario
Conjunción, disyunción y negación
Igual, distinto, mayor, menor, mayor o igual, menor o igual
Vector 1D
Lista
Pila
Vector 2D
• Indexación
• Inserción
• Apilar
principio
• Desapilar
• Inserción
• Cima
final
• ¿Vacía?
• Extracción
• Vaciado
principio
• Tamaño
• Extracción
final
• ¿Vacía?
• Vaciado
• Tamaño
Simple (if)
Repeat
While
While
Lógico (E/S)
Entero (E/S)
Real (E/S)
Vector 1D (S)
Vector 2D (S)
Lógico (E/S)
Entero (E/S)
Lista (S)
Lógico (E/S)
Entero (E/S)
Pial (S)
ALFA5
Lógico
Entero
Lógica
Enteras
Cola
•
•
•
•
•
Insertar
Extraer
¿Vacía?
Vaciado
Tamaño
While
Lógico (E/S)
Entero (E/S)
Cola (S)
SI
SI (de tipo C++ //)
EVALUACIÓN DE LA PRÁCTICA
La descripción detallada de las normas de evaluación puede encontrarse en la web de
prácticas. Su profesor, en los laboratorios, completará, explicará y matizará cualquier
aspecto adicional.
Descargar