Se desea implementar una calculadora con sintaxis Lisp I/Compiladores... · una secuencia de listas...

138
Compiladores I 1ª Convocatoria 95/96 (27-I-96) 4º Ing. Informática. C.P.S. Universidad de Zaragoza -1- Se desea implementar una calculadora con sintaxis Lisp. El programa debe procesar una secuencia de listas Lisp tomadas de stdin. Cada lista contiene una expresión aritmética (en notación prefija), y para cada una de ellas se debe escribir el resultado de su expresión correspondiente. Para simplificar, asumiremos '+' y '*' como únicos operadores. Ejemplo: Para un fichero de entrada como el siguiente (+ 2 4 6 8 10); (* (+ 1 2 3) (+ 9 7 1)) ; (+ (* 10 2 3) 25 (* 8 9 (+ 1 1) ) ); (+ 20 -20); (+ 20); (* 30); debe generar la salida -> 30 -> 102 -> 229 -> 0 -> 20 -> 30 Como se puede ver en el ejemplo, los separadores en la entrada (blancos, tabuladores, saltos de línea) no influyen en el resultado. Ejercicio 1 (1 pto.): Escribir un fuente Lex (Flex) para el reconocimiento de los tokens fundamentales que permitan resolver, en conjunción con los Ejercicios 2 y 3, la calculadora deseada. Ejercicio 2 (2 ptos.): Escribir una gramática (en Yacc/Bison) que exprese una sintaxis (clara y concisa) para las entradas a la calculadora propuesta. Ejercicio 3 (2 ptos.): Completar la gramática del ejercicio anterior de manera que implemente la calculadora. Notar que basta con añadir al resultado del Ejercicio 2 las acciones necesarias. Nota 1: Si se considera necesario, se puede establecer un nivel de anidamiento máximo en las listas de listas de 125 niveles.

Transcript of Se desea implementar una calculadora con sintaxis Lisp I/Compiladores... · una secuencia de listas...

Compiladores I 1ª Convocatoria 95/96 (27-I-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Se desea implementar una calculadora con sintaxis Lisp. El programa debe procesaruna secuencia de listas Lisp tomadas de stdin. Cada lista contiene una expresiónaritmética (en notación prefija), y para cada una de ellas se debe escribir el resultadode su expresión correspondiente. Para simplificar, asumiremos '+' y '*' como únicosoperadores.

Ejemplo: Para un fichero de entrada como el siguiente

(+ 2 4 6 8 10);(* (+ 1 2 3) (+ 9 7 1)) ;(+ (* 10 2 3)

25(* 8 9 (+ 1 1) )

);(+ 20 -20);(+ 20);(* 30);

debe generar la salida

-> 30-> 102-> 229-> 0-> 20-> 30

Como se puede ver en el ejemplo, los separadores en la entrada (blancos,tabuladores, saltos de línea) no influyen en el resultado.

Ejercicio 1 (1 pto.): Escribir un fuente Lex (Flex) para el reconocimiento de lostokens fundamentales que permitan resolver, en conjunción con los Ejercicios 2 y 3,la calculadora deseada.

Ejercicio 2 (2 ptos.): Escribir una gramática (en Yacc/Bison) que exprese unasintaxis (clara y concisa) para las entradas a la calculadora propuesta.

Ejercicio 3 (2 ptos.): Completar la gramática del ejercicio anterior de manera queimplemente la calculadora. Notar que basta con añadir al resultado del Ejercicio 2las acciones necesarias.

Nota 1: Si se considera necesario, se puede establecer un nivel de anidamientomáximo en las listas de listas de 125 niveles.

Compiladores I 1ª Convocatoria 95/96 (27-I-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

Considérese la siguiente gramática:

ALS →==ALS ALALS →==

====

==ALAL →==NUM NS ',' NS '\n'NS →==NS NNS →==N

Se desea saber si se trata de una gramática SLR o no. Para ello, responder a lassiguientes preguntas.

Ejercicio 4 (2 ptos.): Construir la familia canónica de conjuntos LR(0)

Ejercicio 5 (1.5 ptos.): Construir el autómata a partir de dichos conjuntos

Ejercicio 6 (1.5 ptos.): ¿Se trata de una gramática SLR o no?

Tiempo total para el examen: 3 horas

Compiladores I 2ª Convocatoria 95/96 (22-VI-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1: Considérese la siguiente gramática:

S ∅ ==[ S| S1

S1 ∅ ==

====

==[a]

1.1) (1 pto.) Establecer el lenguaje que genera. Es necesario que se justifique,lo más formalmente posible, la respuesta dada

1.2) (1.5 ptos.) ¿Se trata de una gramática SLR(1)?1.3) (1 pto.) ¿Se trata de una gramática LL(1)?1.4) (0.5 ptos.) Si no es SLR(1), dar una gramática equivalente que sí lo

sea. Análogamente, si no es LL(1) dar una gramática equivalente que sí losea.

Ejercicio 2 (1.5 ptos.): Considerar una analizador LR. Para definir una lista no vacíade identificadores podemos pensar en las siguientes alternativas:

a) listaID: listaID ID| ID

b) listaID: ID listaID| ID

¿Son igualmente correctas las dos definiciones? ¿En qué se diferencia elfuncionamiento de una y otra? Si ambas son correctas, ¿Cuál de ellas es másaconsejable? Ejemplificarlo con los sucesivos cambios de estado de la pila delanalizador sintáctico para la secuencia de tokens

ID ID ID ID

Ejercicio 3 (2.5 ptos.): "Boxes" es un lenguaje para la descripción de secuencias decajas (planas) que se incluyen unas en otras. La siguiente figura muestra en la parteizda. un programa fuente en dicho lenguaje, y en su parte dcha. el resultado gráficode su ejecución.

Compiladores I 2ª Convocatoria 95/96 (22-VI-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

v 2,3[

h 1,1[

---+++++

]h 2,1,2[

++++----v 1,1[

+++--+-+

]]

]

El significado del fuente es el siguiente:

v 2,3: indica que la caja en cuestión se va a dividir verticalmente en dos cajas. Laprimera (empezando por la izda.) ocupará 2/5 del total, mientras que la segundaocupará los 3/5 restantes. Lo que le sigue entre [....] son las descripciones de las cajasinteriores.

h 1,1: indica que la primera de las subcajas (la que ocupaba los 2/5 de la izda.)se va a dividir horizontalmente en dos subcajas, ocupando cada una lamitad del espacio. Para cada una de estas cajas, la secuencia formada por 4elementos de '+','-' indica el color de los lados, empezando por el de mása la izda. y girando en el sentido de las agujas del reloj: '+' indica trazo ennegro, mientras que '-' indica que no hay trazo (el lado no se dibuja).

h 2,1,2: indica que la segunda de la subcajas se divide horizontalmente en 3cajas, que ocupan respectivamente 2/5,1/5,2/5. Y así sucesivamente.

Se pide escribir la gramática Yacc correspondiente al lenguaje Boxes.

Ejercicio 4: En un afamado centro universitario propusieron una vez el siguienteinteresante ejercicio:

Se desea implementar una calculadora con sintaxis Lisp. El programa debeprocesar una secuencia de listas Lisp tomadas de stdin. Cada lista contieneuna expresión aritmética (en notación prefija), y para cada una de ellas sedebe escribir el resultado de su expresión correspondiente. Para simplificar,asumiremos '+' y '*' como únicos operadores.

Compiladores I 2ª Convocatoria 95/96 (22-VI-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

Ejemplo: Para un fichero de entrada como el siguiente

(+ 2 4 6 8 10);(* (+ 1 2 3) (+ 9 7 1)) ;(+ (* 10 2 3)

25(* 8 9 (+ 1 1) )

);(+ 20 -20);(+ 20);(* 30);

debe generar la salida

-> 30-> 102-> 229-> 0-> 20-> 30

Como se puede ver en el ejemplo, los separadores en la entrada (blancos,tabuladores, saltos de línea) no influyen en el resultado.

4.1) (1 pto.) Para resolver el problema, algunos de los alumnos plantearon lasiguiente gramática en Yacc:

listas: listas lista ';'| lista ';'

;lista: '(' operador listaSexps ')';listaSexps: listaSumandos

| listaMultiplicandos;listaSumandos: elemento

| listaSumandos elemento;listaMultiplicandos: elemento

| listaMultiplicandos elemento;operador: '+'

| '*';elemento: NUMERO

| lista;

Compiladores I 2ª Convocatoria 95/96 (22-VI-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-4-

Teniendo presente la necesidad posterior de generar la calculadora (su ejecutable),¿Es correcta la gramática presentada? Justificar la respuesta. En caso de no sercorrecta poner ejemplos de problemas que podrían surgir.

4.2) (1 pto.) A la hora de implementar la calculadora deseada, otros plantearon lasiguiente solución

%........char laOp;%%unionint val;

......%token NUMERO%type <val> Sexp%type <val> lista%type <val> listaSexps%type <val> NUMERO%%listas: listas lista ';' printf("-->%d\n",$2);| lista ';' printf("-->%d\n",$1);

;lista: '('

operadorlistaSexps')' $$=$3;

;

operador: '+' laOp='+';| '*' laOp='*';

;listaSexps: listaSexps Sexp if(laOp=='+')

$$=$1+$2;else

$$=$1*$2;

| Sexp $$=$1;;Sexp: NUMERO $$=$1;

| lista $$=$1;;%%main()yyparse();

¿Es correcta esta solución? Justificar la respuesta. En caso de no ser correcta, ponerejemplos de problemas que podrían surgir y proponer (escuetamente) usa solución.

Tiempo total para el examen: 2 horas 30 min.

Compiladores I 3ª Convocatoria 95/96 (3-IX-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (3 ptos.): Los identificadores para un determinado lenguaje deprogramación se definen de acuerdo con la siguiente descripción:

Un identificador puede empezar con una letra o un "underscore" (carácter"_"), debe estar seguido por 0 ó más letras, dígitos o underscores, pero conlas restricciones siguientes:

1) No pueden aparecer dos underscores seguidos2) Un identificador no puede terminar con un underscore.

Además, no hay ninguna limitación en cuanto a la longitud de losidentificadores.

1.1) (1.5 ptos.) Dibujar el Autómata Finito Determinista que corresponde alos identificadores descritos anteriormente.

Para etiquetar los arcos, en lugar de utilizar caracteres simples utilizarlas siguientes clases de caracteres:

letra [a-zA-Z]digito [0-9]und "_"

1.2) (1.5 ptos.) Dar una expresión regular correspondiente a losidentificadores descritos anteriormente

Ejercicio 2 (2 ptos.): Considérese el lenguaje libros que se define como sigue:

a) Un libro es o bien una novela o bien un colección de historias cortasb) Una novela consiste en un título seguido por uno o más capítulosc) Un capítulo es un entero seguido por un cuerpo de capítulod) Un cuerpo de capítulo es una lista de párrafos y/o ilustraciones. La lista

debe incluir al menos un párrafo.e) Una collección de historias cortas se compone de dos o más historias

cortas. Dos historias cortas se separan por una página en blanco.f) Una historia corta consiste en un título seguido de un cuerpo de historia

cortag) Un cuerpo de historia corta es lo mismo que un cuerpo de capítulo

Compiladores I 3ª Convocatoria 95/96 (3-IX-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

Escribir una gramática lo más clara y compacta posible para dicho lenguaje. Utilizarletras minúsculas para los no terminales de la gramática, así como los siguientesterminales:

terminal lo que denotaT un títuloE un enteroP un párrafoI una ilustraciónB una pág. en blanco

Ejercicio 3 (2 ptos.): Considérese la siguiente gramática, donde NUMERO y MASson los símbolos terminales:

exp=∅ listaElementoslistaElementos ∅ NUMEROlistaElementos ∅ exp MAS NUMERO

Razonar sobre si es una gramática LL(1) o no. En caso de no serlo, dar una gramáticaequivalente que sea LL(1)

Ejercicio 4 (3 ptos.): Considérese la siguiente gramática que se usa para eltratamiento de determinado tipo de expresiones:

exp=→ ter '=' ter

exp=→ terter=→ ter '+' fact

ter=→ ter AND fact

ter=→ factfact=→ ENTEROfact=→ BOOLEANOfact=→ '(' exp ')'

Las reglas de tipo para las expresiones de la gramática son las siguientes:

1) Sólo se pueden sumar enteros; el resultado es un entero.2) El operador AND sólo se puede aplicar sobre booleanos; el resultado es

un booleano.3) El operador de igualdad '=' sólo puede aplicarse sobre elementos del

mismo tipo, y su resultado es siempre un booleano.

Compiladores I 3ª Convocatoria 95/96 (3-IX-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

4) En el caso de que aparezca un error de tipos durante la traducción (esdecir, se viole alguna de las reglas anteriores), el tipo de la expresiónserá error.

Un fuente Yacc incompleto para el problema planteado puede ser el siguiente:

%#include <stdio.h>#include <string.h>

extern char yytext[];/*------------------------------------------------------Se asume que los tipos 'tipos' y 'atrib' se encuentrandefinidos, donde corresponda, para su utilización.

------------------------------------------------------*/typedef enum entero,booleano,error tipos;typedef struct

tipos elTipo;int elValor;

atrib;/*------------------------------------------------------

Aquí código de procedimientos y funciones necesarias------------------------------------------------------*/%%union

atrib atributos;%token ENTERO BOOLEANO AND%type <atributos> exp ter fact%%exp : ter '=' ter /*-UNO-*/

| ter /*-DOS-*/;

ter : ter '+' fact /*-TRES-*/| ter AND fact /*-CUATRO-*/| fact /*-CINCO-*/

;

fact : ENTERO /*-SEIS-*/| BOOLEANO /*-SIETE-*/| '(' exp ')' /*-OCHO-*/

;

%%main()

Compiladores I 3ª Convocatoria 95/96 (3-IX-96)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-4-

yyparse();

4.1) (1.5 ptos.) Escribir las partes de código UNO,...,OCHO que permitansintetizar el atributo 'elTipo' para el no terminal 'exp', de maneraque satisfaga las reglas de tipo.

4.2) (1.5 ptos.) Completar las partes de código UNO,...,OCHO que permitanademás sintetizar el atributo 'elValor' (se debe entender que '+'corresponde a la suma de enteros, 'AND' a la conjunción de booleanos y'=' el operador booleano de igualdad). Se debe asumir que en caso de queel atributo de tipo sea error el atributo de valor queda indeterminado.

Nota 1: Se asume que el analizador léxico simplemente devuelve el tokencorrespondiente y deja en yytext el lexema asociado,convirtiendo las letras minúsculas en mayúsculas.

Nota 2: Por cuestiones de claridad, cada parte de acciones UNO,...,OCHOsólo puede contener una instrucción C. En caso de necesitar más, sedebe realizar una invocación a un procedimiento o función con losparámetros adecuados. Por supuesto, también debes escribir elcódigo de estos procedimientos y funciones.

Tiempo total para el examen: 3 horas

Compiladores I 1ª Convocatoria 96/97 (1-II-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (3 ptos.): Considérese el siguiente fragmento de fuente Yacc para elmanejo de expresiones

#include "tabla.h"#include <stdio.h>void errorSemantico(char *mens)/* Pre: TRUE

Post: escribe '*mens' en stderr y aborta ejecución*/

/*se asume ya implementado*/TABSIM laTabla;%%%unionchar elID[MAXLONGID];

TIPO_VARIABLE elTipo;......... /*1*/

%token ....... /*2*/%type ....... /*3*/%%

.......expr:expSimple /*4*/

| expSimple opRel expSimple /*5*/;

expSimple:term /*6*/

| expSimple opSum term /*7*/;

opRel:'=' /*8*/

| '<' /*9*/| '>' /*10*/| tMEI /*corresponde a "<="*/ /*11*/| tMAI /*corresponde a ">="*/ /*12*/| tNI /*corresponde a "<>"*/ /*13*/;

opSum:'+' /*14*/

| '-' /*15*/| tOR /*corresponde a "OR"*/ /*16*/;

opMul:'*' /*17*/

| tDIV /*corresponde a "DIV"*/ /*18*/| tMOD /*corresponde a "MOD"*/ /*19*/| tAND /*corresponde a "AND"*/ /*20*/;

Compiladores I 1ª Convocatoria 96/97 (1-II-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

term:factor /*21*/

| '+' term %prec MASMAS /*22*/| '-' term %prec MENOSMENOS /*23*/| term opMul factor /*24*/;

factor:tCONSTENTERA /*25*/

| tCONSTCHAR /*26*/| tFALSE /*27*/| tTRUE /*28*/| tIDENTIFICADOR /*29*/| tIDENTIFICADOR selCompVect /*30*/| tIDENTIFICADOR paramActuales /*31*/| '(' expr ')' /*32*/| tNOT factor %prec NEG /*33*/;

paramActuales:'(' listaExpr ')' /*34*/

;

listaExpr:listaExpr /*35*/',' /*36*/expr /*37*/

| expr /*38*/;

selCompVect:'[' expr ']' /*39*/

;

.......

Considérese, por otra parte, la especificación para el manejo de la tabla de símbolosque se entregan en las hojas anexas.

Compiladores I 1ª Convocatoria 96/97 (1-II-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

El objetivo es completar la gramática (parcial) anterior con aquellas accionessemánticas que permitan obtener el tipo de una expresión. Para ello se pidecompletar las partes /*1*/ a /*39*/ que se consideren necesarias con el código Cnecesario de manera que:

a) Se sintetice el atributo 'elTipo' para el símbolo 'expr'b) Se den mensajes de error semántico (mediante la adecuada invocación a

'errorSemantico()') en aquellas circunstancias que podais detectar.No es necesario detectar los errores correspondientes a una inconsistenciade número, tipo y/o clase entre los parámetros actuales y los formales enuna invocación a una función

Notas:1) Para evitar confusiones, escribir en las hojas que entregueis el número

correspondiente a la parte del código y, a continuación, el códigocorrespondiente. Por ejemplo:

4) $$=$1;

Por otra parte, si alguna de las partes no contiene código, escribirúnicamente el número (para indicar que no se trata de un olvido, sinosimplemente de una parte que no requiere código).

2) Asumir que el analizador léxico, cuando reconoce un identificador,además de devolver el token 'tIDENTIFICADOR' asigna al campo'elID' de la variable 'yylval' el string correspondiente al nombredel identificador. Para el resto de los terminales no realiza ninguna acción,excepto la correspondiente a devolver el token.

Ejercicio 2 (5 ptos.) : Considérese la siguiente gramática (en negrita los terminales):

S →==( L )S==→==aL →==L , SL →==S

2.1 (0.5 ptos.) ¿Qué lenguaje genera dicha gramática?2.2 (2.5 ptos.) Construir el autómata SLR para dicha gramática y las tablas

'accion[]' e 'ir_a[]' del análisis SLR, y concluir si se trata de unagramática SLR o no.

Compiladores I 1ª Convocatoria 96/97 (1-II-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-4-

2.3 (2 ptos.) Evidentemente, se trata de una gramática no LL(1).Transformarla en una equivalente que sí lo sea, y contruir la tabla delanálisis sintáctico LL(1).

Ejercicio 3 (2 ptos.): Considérese un conjunto finito A=e1,e2,...,ek. Una lista"plana" de elementos de A es de la forma [a1,a2,...,ar] donde los ai sonelementos distintos del conjunto A. También se considera como correcta la listavacía []. Por otra parte, la posición que ocupan los elementos dentro de la lista essignificativa, de manera que las listas [e1,e7] y [e7,e1] son distintas. Este ejerciciopide los siguiente:

3.1 (1 pto.) Describir concisa y claramente una gramática libre de contextoque reconozca listas planas de elementos distintos de A (no se trata deescribir toda la gramática pues k no se ha establecido). Escribircompletamente dicha gramática para el caso k=3.

3.2 (0.5 ptos.) Estimar cuántas producciones tendría dicha gramática3.3 (0.5 ptos.) Si imponemos que los elementos de una lista se tomen

ordenadamente (es decir, nunca pueden darse situaciones del estilo[...,e9,...,e3,...]), estimar cuántas producciones tendría una gramática queconsiderara esta restricción.

Tiempo total para el examen: 3 horas

Compiladores I 2ª Convocatoria 96/97 (4-VII-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (6.25 ptos.): Considerar la siguiente gramática (denominada G), queforma parte de una gramática para un lenguaje de programación imperativo:

%token ID OPAS VAL%%sentencias:

sentencia| sentencias sentencia;

sentencia:etiqueta asignacion

;

etiqueta:

| ID ':';

asignacion:ID OPAS VAL ';'

;%%

1.1) (1.0 Ptos.) Determinar si=ε=∈ L(G). Si la respuesta es afirmativa, encontraruna derivación para ella. Si es negativa, razonar la respuesta.

1.2) (1.25 Ptos.) Obtener completa la tabla del análisis LL(1), y deducir a partirde ella que no se trata de una gramática de dicha clase.

1.3) (2 Ptos.) Realizar las transformaciones necesarias de la gramática G hastaencontrar una gramática equivalente que sí sea LL(1).

1.4) (2 Ptos.) Para la gramática obtenida en el punto 1.3), escribir en C unanalizador descendente recursivo. Asumir la existencia de una función

int yylex()que realiza el análisis léxico: devuelve los tokens declarados, saltaseparadores (blancos, tabuladores y saltos de línea) y devuelve el ASCIIde los caracteres que no corresponden a los casos anteriores.

Compiladores I 2ª Convocatoria 96/97 (4-VII-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

Ejercicio 2 (3 ptos.): Con el objetivo de depurar programas se ha decididoimplementar un formateador para ficheros que contienen listas tipo Lisp de enterossin signo. Se pide escribir un analizador sintáctico, en YACC, que recorra el ficherode entrada (contiene una secuencia de listas de las que estamos considerando) y lasescriba en forma tabulada por niveles, de acuerdo con el ejemplo. Así, si el ficherode entrada contiene

(1 2 3 4 (5 6 ) 7 8)

(88 (77 66) 55 (44 33 (22 11)))

la salida por stdout del analizador debe ser la siguiente

(1234(

56

)

78

)

(88(

7766

)

55(

4433(

2211

)

)

)

Compiladores I 2ª Convocatoria 96/97 (4-VII-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

Nota: definir únicamente el token 'NUMERO' y asumir ya construído unanalizador léxico que:* devuelve dicho token cuando reconoce un entero sin signo* los blancos, tabuladores y saltos de línea los salta* para cualquier otro carácter, devuelve su ASCII

Ejercicio 3 (0.75 ptos.): El libro "Pascal: User Manual and Report" de K. Jensen yN. Wirth, que establece la especificación ISO Pascal Standard, define un comentariodel lenguaje como (sólo vamos a considerar comentarios válidos aquéllos queempiezan por "(*" y terminan por "*)"):

"(*" seguido de cualquier secuencia de 0 ó más caracteres queno contenga "*)", y terminado por "*)"

Escribir una expresión regular con sintaxis LEX para los comentarios Pascal asídefinidos.

Tiempo total para el examen: 2:45 horas

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (2.5 ptos.): La invocación a Yacc con una gramática dada ha generado elfichero 'y.output' que se muestra en el Anexo 1. Se pide lo siguiente:

1.1) (1.0 Ptos.) Deducir a partir de dicho fichero cuál es la gramática que logenera

1.2) (0.5 Ptos.) Razonar por qué no es una gramática LL(1)1.3) (1.0 Ptos.) Transformar la gramática a una equivalente que sí lo sea, y

obtener para esta transformada la tabla del análisis LL(1)

Ejercicio 2 (7.5 ptos.): Se desea construir un intérprete para un lenguaje muysencillo. Dicho lenguaje maneja cadenas de caracteres, y es capaz de asignarlas avariables, realizar la operación de concatenación y escribir por salida estandarexpresiones (limitadas como se verá posteriormente) que involucran cadenas.

Un ejemplo de programa en dicho lenguaje sería el siguiente:

vars a b cstart

print("Un refran:")a="No por mucho "b=""" madrugar"""a=a+bprint("a: " + a)c=b+b+b+" no es sano"print("res: " + c + " segun el califa")print("a:")print(a)

end

que dará como salida

Un refran:a: No por mucho " madrugar"res: " madrugar"" madrugar"" madrugar" no es sano segun el califaa:No por mucho " madrugar

Detallemos un poco más sus características:

a) las variables que se van a utilizar han de ser declaradas previamente(mediante la palabra reservada vars), y todas ellas son capaces dealmacenar una cadena de hasta 300 caracteres.

b) en su representación externa, una constante de tipo cadena va entre doblescomillas. Entre ellas puede ir cualquier secuencia de 0 ó más caracteres

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

distintos del salto de línea ('\n'); cuando se desea representar unasdobles comillas como parte del contenido de la cadena, éstas se han deponer por duplicado (ver la asignación a la variable b en elprograma de ejemplo).

c) además de la asignación y la escritura, es posible realizar la concatenaciónde cadenas, que se representa externamente mediante el operador '+'.

d) el lenguaje distingue entre mayúsculas y minúsculas

El ejercicio pide construir el intérprete completo: analizador léxico, sintáctico,tratamiento de aquéllos errores semánticos que consideres importantes y la propiaejecución del código fuente. Para el tratamiento semántico puedes utilizar la tabla desímbolos que se especifica en el Anexo 2. Notar que se trata de la que habitualmentehas utilizado en prácticas, en las que se han realizado algunas modificaciones parapoder operar con variables de tipo cadena y su contenido.

Tiempo total para el examen: 3 horas

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

Anexo 1

state 0$accept : _S

$end

a shift 4+ shift 3. error

S goto 1A goto 2

state 1$accept :

S_$end

$end accept. error

state 2S : A_B

b shift 7( shift 8. error

B goto 5D goto 6

state 3A : +_B A

b shift 7( shift 8. error

B goto 9D goto 6

state 4A : a_ (3)

. reduce 3

state 5S : A B_ (1)

. reduce 1

state 6B : D_C

c shift 12* shift 11. error

C goto 10

state 7B : b_ (5)D : b_ (9)

c reduce 9* reduce 9. reduce 5

state 8D : (_S )

a shift 4+ shift 3. error

S goto 13A goto 2

state 9A : + B_A

a shift 4+ shift 3. error

A goto 14

state 10B : D C_ (4)

. reduce 4

state 11C : *_D C

b shift 16( shift 8. error

D goto 15

state 12C : c_ (7)

. reduce 7

state 13D : ( S_)

) shift 17. error

state 14A : + B A_

(2)

. reduce 2

state 15C : * D_C

c shift 12* shift 11. error

C goto 18

state 16D : b_ (9)

. reduce 9

state 17D : ( S )_

(8)

. reduce 8

state 18C : * D C_

(6)

. reduce 6

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-4-

Anexo 2

/*======================================================================Prog.: tabla.hTema: funciones para manipular una tabla de simbolos para un

lenguaje de bloquesFecha: Noviembre-96Fuente: J. NeiraCom.: MODIFICADA PARA EXAMEN SEPTIEMBRE 97 DE COMPI

=======================================================================*/

/*========================================================*//* D E F I N I C I O N E S *//*========================================================*/

#define MAXLONGID 100 /* longitud maxima de un identificador */#define TAMANO_TABLA 7 /* Numero de entradas en la tabla hash */

#define CIERTO 1#define FALSO 0

/*========================================================*//* T I P O S *//*========================================================*/

typedef enum /*categor`ias de s`imbolos*/PROGRAMA,VARIABLE,PROCEDIMIENTO,FUNCION,PARAMETRO,RESULTADO

TIPO_SIMBOLO;

typedef enum /*tipos de datos*/ENTERO,BOOLEANO,CHAR,STRING

TIPO_VARIABLE;

typedef enum /*clases de par'ametros*/IN,OUT,INOUT

CLASE_SIMBOLO;

struct UN_SIMBOLO TIPO_SIMBOLO tipo;char identificador[MAXLONGID];TIPO_VARIABLE variable;

int es_vector; /* Si vector, indices */int minimo;int maximo;

CLASE_SIMBOLO clase;

int nivel;

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-5-

int dir; /* Si variable, direccion; si proc/func,dir primera instruccion. Sin uso parapr`actica 5. Asignar 0*/

int visible; /* Si es un parametro */

lista parametros; /* Si proc/func, lista depuntero a los simbolos de losparametros */

struct UN_SIMBOLO *funcion; /* Si es resultado de func.,puntero al simbolo de

la funcion */

char valor[300]; /* valor del s'imbolo.El programador debe hacerla transformaci'on adecuadade valores en funci'on a su tipo*/

;

typedef struct UN_SIMBOLO SIMBOLO;

typedef lista TABSIM[TAMANO_TABLA];

/*========================================================*//* M A C R O S *//*========================================================*/

#define ES_VARIABLE(e) ((e).tipo == VARIABLE)#define ES_PARAMETRO(e) ((e).tipo == PARAMETRO)#define ES_PROCEDIMIENTO(e) ((e).tipo == PROCEDIMIENTO)#define ES_FUNCION(e) ((e).tipo == FUNCION)#define ES_RESULTADO(e) ((e).tipo == RESULTADO)#define ES_ENTRADA(e) (((e).tipo == PARAMETRO) && ((e).clase == IN))#define ES_SALIDA(e) (((e).tipo == PARAMETRO) && ((e).clase == OUT))#define ES_ES(e) (((e).tipo == PARAMETRO) && ((e).clase == INOUT))

/*========================================================*//* F U N C I O N E S *//*========================================================*/

/*========================================================*/void inicializar_tabla (TABSIM tabla);/*========================================================Crea una tabla de simbolos vacia.

IMPORTANTE: Este procedimiento debe invocarse antes de hacerninguna operacion con la tabla de simbolos.========================================================*/

/*========================================================*/SIMBOLO *buscar_simbolo (TABSIM tabla,

char *identificador);/*========================================================Busca en la tabla el simbolo de mayor nivel cuyoidentificador coincida con el del parametro (se distinguenminusculas y mayusculas). Si existe, devuelve comoresultado un puntero al s`imbolo, de lo contrario devuelveNULL.========================================================*/

/*========================================================*/

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-6-

SIMBOLO *introducir_programa (TABSIM tabla,char *identificador,int dir);

/*========================================================Introduce en la tabla un simbolo de tipo PROGRAMA, con elidentificador del parametro, de nivel 0, con la direcciondel parametro. Dado que debe ser el primer simbolo aintroducir, NO SE VERIFICA QUE EL SIMBOLO YA EXISTA.========================================================*/

/*========================================================*/SIMBOLO *intenta_introducir_variable (TABSIM tabla,

char *identificador,TIPO_VARIABLE variable,int nivel,int dir,char *val);

/*========================================================Si existe un simbolo en la tabla del mismo nivel y con elmismo identificador, devuelve NULL. De lo contrario,introduce un simbolo de tipo VARIABLE (simple) con los datosde los argumentos.========================================================*/

/*========================================================*/SIMBOLO *intenta_introducir_vector (TABSIM tabla,

char *identificador,int minimo,int maximo,TIPO_VARIABLE variable,int nivel,int dir);

/*========================================================Si existe un simbolo en la tabla del mismo nivel y con elmismo identificador, devuelve NULL. De lo contrario,introduce un simbolo de tipo VARIABLE (vector) con los datosde los argumentos.========================================================*/

/*========================================================*/SIMBOLO *intenta_introducir_procedimiento (TABSIM tabla,char *identificador, int nivel, int dir);/*========================================================Si existe un simbolo en la tabla del mismo nivel y con elmismo identificador, devuelve NULL. De lo contrario,introduce un simbolo de tipo PROCEDIMIENTO con los datos delos argumentos.========================================================*/

/*========================================================*/SIMBOLO *intenta_introducir_funcion (TABSIM tabla,

char *identificador,int nivel,int dir);

/*========================================================Si existe un simbolo en la tabla del mismo nivel y con elmismo identificador, devuelve NULL. De lo contrario,introduce un simbolo de tipo FUNCION con los datos de losargumentos.

IMPORTANTE: El resultado de la funcion debera serintroducido como un simbolo diferente, de tipo RESULTADO yde nivel + 1.========================================================*/

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-7-

/*========================================================*/SIMBOLO *intenta_introducir_resultado (TABSIM tabla,

char *identificador,TIPO_VARIABLE variable,SIMBOLO *funcion,int nivel,int dir);

/*========================================================Si existe un simbolo en la tabla del mismo nivel y con elmismo identificador, devuelve NULL. De lo contrario,introduce un simbolo de tipo RESULTADO con los datos de losargumentos.========================================================*/

/*========================================================*/SIMBOLO *intenta_introducir_parametro_simple (TABSIM tabla,

char *identificador,TIPO_VARIABLE variable,

int clase,int nivel,int dir);

/*========================================================Si existe un simbolo en la tabla del mismo nivel y con elmismo identificador, devuelve NULL. De lo contrario,introduce un simbolo de tipo PARAMETRO (simple) con losdatos de los argumentos.

IMPORTANTE: Los parametros NO quedan ligados alprocedimiento o funcion donde estan declarados. Se debehacer una lista con los punteros que esta funcion devuelva,y asociarla con el proc/func correspondiente utilizando elprocedimiento colgar_parametros.========================================================*/

/*========================================================*/SIMBOLO *intenta_introducir_parametro_vector (TABSIM tabla,

char *identificador,int minimo,int maximo,TIPO_VARIABLE variable,

int clase,int nivel,int dir);

/*========================================================Si existe un simbolo en la tabla del mismo nivel y con elmismo identificador, devuelve NULL. De lo contrario,introduce un simbolo de tipo PARAMETRO (vector) con losdatos de los argumentos.

IMPORTANTE: Los parametros NO quedan ligados alprocedimiento o funcion donde estan declarados. Se debehacer una lista con los punteros que esta funcion devuelva,y asociarla con el proc/func correspondiente utilizando elprocedimiento colgar_parametros.========================================================*/

/*========================================================*/void colgar_parametros (TABSIM tabla,

SIMBOLO *procfunc,lista lista);

/*========================================================Asocia la lista (que debe ser una lista de SIMBOLOSpreviamente introducidos, correspondientes a parametros)

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-8-

con el simbolo correspondiente a un procedimiento ofuncion.========================================================*/

/*========================================================*/void ocultar_parametros (TABSIM tabla,

int nivel);/*========================================================Marca todos los parametros de un nivel como ocultos para queno puedan ser encontrados por la funcion buscar_simbolo. Semantiene la definicion completa del procedimiento/funciondonde estan declarados para verificacion de invocaciones alprocedimiento/funcion.========================================================*/

/*========================================================*/void eliminar_programa (TABSIM tabla);/*========================================================Elimina de la tabla todos los simbolos (deberia haber unosolo) de tipo programa y nivel 0.========================================================*/

/*========================================================*/void eliminar_variables (TABSIM tabla,

int nivel);/*========================================================Elimina de la tabla todas las variables (simples y vectores)que sean del nivel del argumento.

IMPORTANTE: No elimina parametros ni valores resultado defunciones.========================================================*/

/*========================================================*/void eliminar_parametros_ocultos (TABSIM tabla,

int nivel);/*========================================================Elimina de la tabla todas los parametros que hayan sidoocultados previamente.

IMPORTANTE: Los procedimientos y funciones donde losparametros ocultos estaban declarados, deben ser eliminadospara mantener la coherencia de la tabla.========================================================*/

/*========================================================*/void eliminar_procedimientos (TABSIM tabla,

int nivel);/*========================================================Elimina de la tabla todas los procedimientos de un nivel.

IMPORTANTE: Los parametros ocultos de estos procedimientosdeben ser eliminados para mantener la coherencia de latabla.========================================================*/

/*========================================================*/void eliminar_funciones (TABSIM tabla,

int nivel);/*========================================================Elimina de la tabla todas las funciones de un nivel.

IMPORTANTE: Los parametros ocultos de estas funciones debenser eliminados para mantener la coherencia de la tabla.

Compiladores I 3ª Convocatoria 96/97 (12-IX-97)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-9-

========================================================*/

/*========================================================*/char *valor(TABSIM tabla,

char *identificador);/*========================================================Devuelve un puntero a un string con el contenido dels'imbolo. Depende del usuario tratar posteriormente deacuerdo con el tipo. Si el simbolo no se encuentra enla tabla, el valor queda indefinido========================================================*/

/*========================================================*/void mostrar_tabla (TABSIM tabla);/*========================================================Muestra en pantalla el contenido de la tabla de simbolos.Los simbolos aparecen agrupados segun su posicion en lalista de colision de cada elemento de la tabla hash. Paracada simbolo se da informacion del nombre de suidentificador, el tipo de simbolo, el tipo de variable, laclase de variable, el nivel del simbolo y la direccionasignada.

IMPORTANTE: Para cada procedimiento o funcion se da tambieninformacion de los parametros que le han sido asociados.Asi que los simbolos de tipo parametro aparecen DOS VECES enla descripcion del contenido de la tabla. Sinembargo, en latabla aparecen una sola vez.========================================================*/

Compiladores I 1ª Convocatoria 97/98 (31-I-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (3.0 ptos.): Considérese la siguiente parte de una gramática para unlenguaje de programación:

%token tTPENTERO tTPCARACTER tTPBOOLEANO%token tIDENTIFICADOR tVAL tREF%union

.....parametrosFormales:| '(' listaParametros ')';listaParametros:

listaParametros ';' parametros| parametros;parametros:

claseParametros declaracionParametros;declaracionParametros:

listaID ‘:’ tipo;listaID:

listaID ‘,’ tIDENTIFICADOR| tIDENTIFICADOR;tipo:

tTPENTERO| tTPCARACTER| tTPBOOLEANO;claseParametros:

tVAL| tREF;

Asumimos definidos los siguientes tipos:

typedef enum VALOR,REFERENCIA clasesDeParametros;typedef enum INT,BOOL,CHAR tiposDeVariables;typedef .... simbolo,*ptSimbolo;

Se dispone también del siguiente procedimiento para insertar un parámetro en latabla de símbolos:

ptSimbolo *insertaParametro(TABLA *laTabla,char *elID,clasesDeParametros laClase,tiposDeVariables elTipo);

Compiladores I 1ª Convocatoria 97/98 (31-I-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

Se pide definir los atributos y escribir las acciones que se consideren oportunaspara insertar los parámetros en la tabla.

Compiladores I 1ª Convocatoria 97/98 (31-I-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

Ejercicio 2 (4.0 ptos.): Proveniente de una mala exportación de datos de una basede datos, disponemos de dos ficheros de texto: “datos.txt” y “memos.txt”. Elprimero de ellos contiene la información de los campos de una base dealmacenamiento de topónimos; el segundo, contiene informacióncomplementaria para algunos de los registros contenidos en el fichero inicial.

El siguiente ejemplo muestra parte del fichero de datos:

#ABAD DE AYE.,PIA.DEL BENEFICIO#,#ABAD DE AYE.,PIA DELBENEFICIO#,1591,#ZARE#,#OIBARRIBAR#,#PRA#,#JUAN DESOLA(ZAHARRA)#,#OIBAR#,#K.5(1591)#,1#ABAD VIEJO,CASA#,#ABBADBIEJO,CASSA#,1654,#ZOROKIAIN#,#UNTZITIBAR#,#PRA#,#M.VERA(GAZTEA)

#,#ELO#,#2.K-BIS(1652-56)#,13059#ABAD,CORRALES DEL#,#ABBAD,CORRALESDEL#,1585,#ZARE#,#OIBARRIBAR#,#PRA#,#JUAN DESOLA(ZAHARRA)#,#OIBAR#,#K.3-BIS(1585-7)#,2#ABAD,PIEZA DEL#,#ABBAD,PIEZA

DEL#,1591,#EZPOROGI#,#OIBARRIBAR#,#PRA#,#JUANDE SOLA(ZAHARRA)#,#OIBAR#,#K.5(1591)#,3#ABAD,PIEZAS DEL#,#ABAD,PIAS

DEL#,1591,#EZPOROGI#,#OIBARRIBAR#,#PRA#,#JUANDE SOLA(ZAHARRA)#,#OIBAR#,#K.5(15191)#,9900#ABADIA#,#ABADIA#,1897,#EPAIZ#,#OIBARRIBAR#,##,##,##,#1897KO

KATASTROA#,#ABADIA DE ABAIZ,PIEZAS DE LA#,#ABADIA DE ABAIZ,PIEZAS DELA#,1824,#ESLABA#,#OIBARRIBAR#,#PRA#,#ANTONIO ORTIZ#,#SAN MARTINUNX#,#K.84(1824-25)#,9630

La información es como sigue. Cada registro de la base contiene 10 campos, de loscuales el último puede estar vacío en algunas ocasiones. Los campos son lossiguientes:

c1: forma normalizada del topónimoc2: forma antigua del topónimoc3: año del documento que recoge la forma antiguac4: pueblo al que hace referencia el documentoc5: valle donde se ubicaba el puebloc6: archivo en que se ha localizado el documentoc7: notario que redactó el documento con la forma

antiguac8: pueblo del notarioc9: código del documento donde se ha localizado la

formac10: índice que se asigna al registro, y que se

utiliza para referenciar a la informacióncomplementaria que se encuentra en el fichero

Compiladores I 1ª Convocatoria 97/98 (31-I-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-4-

“memos.txt”. No todas las formas tienen este índice(fijarse en el registro de “ABADIA” del ejemplo).

Veamos un ejemplo de registro tomado del fichero anterior:

c1: #ABAD VIEJO,CASA#c2: #ABBAD

BIEJO,CASSA#c3: 1654c4: #ZOROKIAIN#c5: #UNTZITIBAR#c6: #PRA#c7: #M.VERA(GAZTEA)#c8: #ELO#c9: #2.K

-BIS(1652-56)#c10: 13059

Notar que:1) Los campos van separados por una coma2) Todos los campos, excepto los numéricos (año e índice), se encuentran

delimitados por “#” (estos caracteres no forman parte del contenido del campo,sino que han sido introducidos al exportar los datos de la base antigua, ydeberán ser eliminados en el momento de llevar a cabo la transformación deformatos)

3) Siempre hay al menos un salto de línea después de cada registro4) Debido a una mala introducción de datos, algunos campos no numéricos

contienen tabuladores y saltos de línea; en el momento de cambiar losformatos, los tabuladores y saltos de línea dentro de campos deberán sercambiados por un blanco

Compiladores I 1ª Convocatoria 97/98 (31-I-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-5-

Se pide escribir un programa de acuerdo a las siguientes especificaciones:

1) El programa transforma los datos tomados de “stdin” (se asume suministradosde acuerdo al formato del fichero “datos.txt” descrito anteriormente) y escribepor “stdout” los mismos datos, pero transformados de acuerdo al formato quese describe a continuación

2) El formato de salida almacena cada registro en una línea, separando loscampos por tabuladores. Notar que esto exige que los campos originales quecontengan tabuladores o saltos de línea sean procesados

3) En la salida, el orden de los campos ha de ser el mismo que aparece en ladescripción del contenido del fichero “datos.txt”

4) Finalizada la transformación, el programa debe informar de cuántos registroshan sido procesados

Es necesario desarrollar el fuente Lex que describa el analizador léxico, el fuenteYacc con la gramática y las acciones necesarias, y el fichero Make que lleve acabo la generación del ejecutable que realiza lo que se pide. Proponer tambiénla recuperación de errores sintácticos que considereis oportuna.

Ejercicio 3 (3.0 ptos.): Considerar la siguiente gramática (en negrita losterminales):

S → P MP → E

| qM → n EE → , O

| EO → u

| u , O

Probar que se trata de una gramática NO LL(1). Si es posible, realizar lastransformaciones precisas para convertirla en LL(1) y, construyendo la tabladel análisis LL(1), demostrar que la gramática transformada es efectivamentede esta clase. Es necesario justificar las transformaciones que se realicen. Si nofuera posible transformarla en LL(1), explicar la razón.

Tiempo total para el examen: 3 horas

Compiladores I 2ª Convocatoria 97/98 (3-VII-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (6.0 ptos.)

Considérese el autómata que se muestra en la figura (donde el hexágonorepresenta su estado inicial).

Huesca

Madrid

Zaragoza

Pamplona

t1t2

t4

t3 t5t6

Una herramienta gráfica que es capaz de dibujar autómatas de esta clase generauna descripción textual del autómata, con el fin de que pueda ser utilizada porotros programas. La descripción que se acaba de citar, además de la informaciónestrictamente necesaria, saca otro tipo de información que no tiene, en unprincipio, nada que ver con la propia descripción del autómata.

Para el autómata de la figura la salida de la herramenta de edición se presentaen el apéndice que puedes encontrar al final del enunciado.

Si bien la descripción contiene información redundante, hay que decir que todala información necesaria para conocer el autómata se encuentra entre las líneas

*** Start of TRG ***y

*** End of TRG ***

Veamos con más detalle algunos elementos de la descripción.

5 Tangible Markingsel autómata tiene 5 estados

From #1 .....el estado inicial del autómata es siempre el primero en ser descrito

From #5 (1 timed trans) [ Pamplona ]-Timed-> t3 -to_tang-> #3

Compiladores I 2ª Convocatoria 97/98 (3-VII-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

el estado 5 se denomina “Pamplona” y tiene una única transiciónde salida. Esta transición se denomina “t3” y va al estado 3

El objetivo del ejercicio consiste en realizar un programa que sea capaz dereconocer, almacenar y procesar un autómata descrito de la manera que seacaba de comentar. Para ello hay que responder a las siguientes cuestiones:

1) Definir las estructuras de datos necesarias para poder almacenar lainformación de un autómata

2) Escribir (en Yacc) un analizador sintáctico para el reconocimiento deun grafo. Esto requiere lo siguiente:

* escribir (en Lex) un analizador léxico (con las acciones queconsideres oportunas) para ser integrado con el analizadorsintáctico que se pide

* completar el analizador sintáctico con las acciones oportunaspara el almacenamiento del grafo en las estructuras de datosque has definido en el apartado 1

3) El programa no sólo debe reconocer y almacenar el autómata, sinoque además debe sacarlo por la salida estandar en el siguienteformato (se muestra cómo sería la salida para el ejemplo):

estado inicial: Huesca(Huesca,Madrid,t2)(Huesca,Zaragoza,t1)(Madrid,Vitoria,t6)(Madrid,Pamplona,t5)(Pamplona,Zaragoza,t4)(Zaragoza,Madrid,t3)

Ejercicio 2 (2.0 ptos.)

Determina si la gramática que has propuesto en el ejercicio anterior es LL(1). Sino lo es, transformarla en una equivalente que sí lo sea.

Ejercicio 3 (2.0 ptos.)

Sea G=(N,T,S,P) una gramática libre de contexto. Sea H⊆ N el conjunto definidocomo sigue: H= X∈ N | X→X∈ P . Sea por otra parte PH= X→X∈ P | X∈ H .Consideremos ahora la gramática G’=(N,T,S,P’), donde P’=P \ PH.

Probar que G y G’ son gramáticas equivalentes.

Compiladores I 2ª Convocatoria 97/98 (3-VII-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

Tiempo total para el examen: 3 horas

Compiladores I 2ª Convocatoria 97/98 (3-VII-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-4-

Apéndice: Descripción del autómata generada por la herramienta gráfica

Place invariants for net COMPIJul98:S1 S2 S3 S4 S5

ALL places are covered by some P-invariantStart Reachability Graph construction0.0u 0.0s 0:00 23% 0+0k 0+3io 0pf+0w*** Tangible Reachability Graph of net COMPIJul98 ***5 Tangible Markings0 Vanishing Markings0 ECSActual Conflict Sets:Initial marking is #1 :

[ S1 ]

*** Start of TRG ***5 Tangible Markings

From #1 (2 timed trans) [ Huesca ]-Timed-> t2 -to_tang-> #2-Timed-> t1 -to_tang-> #3

From #2 (2 timed trans) [ Madrid ]-Timed-> t6 -to_tang-> #4-Timed-> t5 -to_tang-> #5

From #3 (1 timed trans) [ Zaragoza ]-Timed-> t4 -to_tang-> #2

From #4 (0 timed trans) [ Vitoria ]

From #5 (1 timed trans) [ Pamplona ]-Timed-> t3 -to_tang-> #3

*** End of TRG ***!!!!!! The initial marking #1 is not reachable !!!!!!

Compiladores I 3ª Convocatoria 97/98 (12-IX-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (1.5 ptos.): Considerar las siguientes gramáticas:

G1 G2A →=Aα A →=βBA →=β B →=αB

B →=ε

Probar formalmente que ambas gramáticas son equivalentes

Ejercicio 2 (1.5 ptos.): Considerar el siguiente Autómata FinitoDeterminista. Dar una expresión regular que corresponda a dichoautómata.

0 1 2

0

1

1

0

01

Ejercicio 3 (5.5 ptos.): Considérese la siguiente gramática:

G:S →=uBDzB →=BvB →=wD →=EFE →=y

E →=εF →=x

F →=ε

1) Construir las tablas del análisis sintáctico SLR, y determinar si se tratade una gramática SLR o no

2) Comprobar que se trata de una gramática no LL(1)3) Transformarla en una gramática LL(1), y calcular su tabla de análisis

LL(1)

Compiladores I 3ª Convocatoria 97/98 (12-IX-98)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

Ejercicio 4 (1.5 ptos.): Considerar el siguiente código C que correspondea un analizador sintáctico descendente recursivo. Determinar, a partirdel propio código, cuál es la gramática, y decir si el analizadorfuncionará correctamente.

enum token …extern enum token getToken(void);

enum token tok;

void advance()

tok=getToken();

void eat(enum token t)

if(tok==t)advance();

elseerror();

void S(void)

switch(tok)case IF: eat(IF); E(); eat(THEN);

S(); eat(ELSE); S(); break;case BEGIN: eat(BEGIN); S(); L(); break;case PRINT: eat(PRINT); E(); break;default: error();

void L(void)

switch(tok)case END: eat(END); break;case SEMI: eat(SEMI); S(); L(); break;default: error();

void E(void)

eat(NUM); eat(EQ); eat(NUM);

Tiempo total para el examen: 3 horas

Compiladores I 1ª Convocatoria 98/99 (4-II-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (6.0 ptos.): Considerar las siguientes gramáticas (escritas ensintaxis Yacc):

/* ESTA ES LA GRAMATICA G1 */

%token tkPRINCIPIO tkFIN A%%bloqueInst:tkPRINCIPIOlistaInsttkFIN

;listaInst:| listaInst inst| inst;inst: A;%%

/* ESTA ES LA GRAMATICA G2 */

%token tkPRINCIPIO tkFIN A%%bloqueInst:tkPRINCIPIOlistaInsttkFIN

;listaInst:| otraListaInst;otraListaInst:otraListaInst inst

| inst;inst: A;%%

1.1) (1.0 Ptos.) Prueba que ambas gramáticas son equivalentes1.2) (1.0 Ptos.) A pesar de ser equivalentes, G1 presenta un conflicto

“desplazamiento/reducción” que no aparece en G2. Identifica lascircunstancias bajo las que puede ocurrir tal conflicto, y da unaexplicación de por qué ocurre

1.3) (1.75 Ptos.) Construye al autómata SLR(1) para G2, así como lastablas para dicho análisis.

Compiladores I 1ª Convocatoria 98/99 (4-II-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

1.4) (1.75 Ptos.) Construye el autómata y las tablas del análisis LR(1)canónico para la siguiente parte de la gramática

/* ESTA ES LA GRAMATICA G3, que es parte de G2 */

%token tkPRINCIPIO tkFIN A%%listaInst:| otraListaInst;otraListaInst:otraListaInst inst

| inst;inst: A;%%

1.5) (0.5 Ptos.) A la vista de los anteriores, ¿Cuántos estados tendría elautómata LALR(1) de G2?

Ejercicio 2 (4.0 ptos.): El ejercicio trata de traducir a C un programaescrito en un lenguaje para el tratamiento de expresiones de reales. Así,para una entrada como

constante cx = 1.2 ;constante cy = 2.1 ;variables x y ;

x = cx + 27;y = 64;x = cy * (x + y);escribir x;

y = 2.0 * x;escribir 2*y+y;

deberá generar una salida como

#include <stdio.h>

#define cx 1.200000#define cy 2.100000float x;float y;

Compiladores I 1ª Convocatoria 98/99 (4-II-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

void main()x = cx + 27.000000;y = 64.000000;x = cy * (x + y);printf("%f\n", x);y = 2.000000 * x;printf("%f\n", 2.000000 * y + y);

Notar que:

1) Todas las variables se declaran como globales2) Todas las constantes tienen una precisión de 6 dígitos decimales3) La salida se tabula con el objeto de hacer más legible el código

generado

Para ello se utiliza el analizador léxico y la gramática Yacc que seadjuntan en los anexos I y II. El ejercicio pide lo siguiente:

2.1) (2.5 Ptos.) Completa la gramática con aquellas acciones que seannecesarias para la generación del código C. Para este apartadopodemos suponer que el código de entrada es completamentecorrecto, por lo que no es necesario llevar a cabo ninguna políticade recuperación de errores.

2.2) (1.0 Ptos) Inserta las estrategias de recuperación de erroressintácticos que consideres oportunas. Para cada caso debesexplicar qué errores tratas de corregir.

2.3) (0.5 Ptos.) Escribe el fuente para la herramienta “make” de Unixde manera que a partir de los ficheros “examen.l” y “examen.y”genere el ejecutable “expr2C” que traduce el fuente deexpresiones a C.

Para responder a los apartados 2.1) y 2.2) numera en el propio Anexo IIcon la gramática los puntos donde insertarías el código y escribe apartedicho código. Por ejemplo:

......%union?????????

%token tkCONSTANTE tkVARIABLES tkESCRIBIR%token <elVal>tkREAL

#1#

Compiladores I 1ª Convocatoria 98/99 (4-II-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-4-

......

#1#

float elVal;.......

Notas:• No olvides entregar el Anexo II numerado• El tiempo es parte del examen, por lo que éste se recogerá

exactamente 2:30 horas después de ser entregado

Tiempo total para el examen: 2:30 horas

Anexo I: Fichero “examen.l”

%/* Fichero: examen.l */#include "y.tab.h"#define trata(tk) linepos+=yyleng; return((tk))

extern int lineno,linepos;%separadores ([\t ])+digito [0-9]letra [a-zA-Z]constEntera digito+constReal constEntera("."constEntera)?identificador letra(digito|letra)*%%separadores linepos+=yyleng;"variables" trata(tkVARIABLES);"constante" trata(tkCONSTANTE);"escribir" trata(tkESCRIBIR);identificador strcpy(yylval.laCad,yytext);

trata(tkID);constReal sscanf(yytext,"%f",&yylval.elVal);

trata(tkREAL);\n linepos = 1;lineno++;. trata(yytext[0]);%%

Compiladores I 1ª Convocatoria 98/99 (4-II-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-5-

Anexo II: Fichero “examen.y”

%/* Fichero: examen.y */#include <stdio.h>#include <string.h>#include <stdlib.h>%%union?????????

%token tkCONSTANTE tkVARIABLES tkESCRIBIR%token <elVal>tkREAL%token <laCad>tkID%%programa:parteConstantesparteVariablesparteInstruciones

;parteConstantes:| decConstantes;decConstantes:decConstantes decConstante

| decConstante;decConstante:tkCONSTANTEtkID'='tkREAL';'

;parteVariables:| tkVARIABLESdecVariables';'

;decVariables:decVariablestkID

| tkID;parteInstruciones:parteInstruciones instruccion

| instruccion;

Compiladores I 1ª Convocatoria 98/99 (4-II-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-6-

instruccion:instAsignacion ';'

| instEscritura ;';instEscritura:tkESCRIBIR expr

;instAsignacion:tkID '=' expr

;expr:term

| '+' term| '-'| expr opSum term;opSum:'+'

| '-';term:factor

| term opMul factor;opMul:'*'

| '/';factor:tkID

| tkREAL| '(' expr )';%%main()yyparse();

Compiladores I 2ª Convocatoria 98/99 (8-VII-99)

4º Ing. Informática C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (3.0 ptos.): Considérese la siguiente gramática que se usa parael tratamiento de determinado tipo de expresiones:

%#include <stdio.h>#include <string.h>

extern char yytext[];/*------------------------------------------------------Se asume que los tipos 'tipos' y 'atrib' se encuentrandefinidos, donde corresponda, para su utilización.------------------------------------------------------*/typedef enum entero,booleano,error tipos;typedef struct

tipos elTipo;int elValor;

atrib;/*------------------------------------------------------Aquí código de procedimientos y funciones necesarias------------------------------------------------------*/%%union

atrib atributos;%token tkENT tkBOOL tkAND%type <atributos> exp ter fact%%exp:ter '=' ter /*-UNO-*/

| ter /*-DOS-*/;

ter:ter '+' fact /*-TRES-*/

| ter tkAND fact /*-CUATRO-*/| fact /*-CINCO-*/;

fact:tkENT /*-SEIS-*/

| tkBOOL /*-SIETE-*/| '(' exp ')' /*-OCHO-*/;%%

Las reglas de tipo para las expresiones de la gramática son las siguientes:

* Sólo se pueden sumar enteros; el resultado es un entero.

Compiladores I 2ª Convocatoria 98/99 (8-VII-99)

4º Ing. Informática C.P.S. Universidad de Zaragoza

-2-

* El operador AND sólo se puede aplicar sobre booleanos; elresultado es un booleano.

* El operador de igualdad '=' sólo puede aplicarse sobre elementosdel mismo tipo, y su resultado es siempre un booleano.

* En el caso de que aparezca un error de tipos durante el análisis (esdecir, se viole alguna de las reglas anteriores), el tipo de la expresiónserá error.

Completar las partes de código UNO,...,OCHO que permitan sintetizarlos atributos 'elValor' y 'elTipo' para el símbolo 'exp'.Se debe entender que '+' corresponde a la suma de enteros, 'AND' a laconjunción de booleanos y '=' el operador booleano de igualdad. Se debeasumir que en caso de que el atributo de tipo sea error el atributo devalor queda indeterminado.

Nota 1: Se asume que el analizador léxico simplemente devuelve eltoken correspondiente y deja en yytext el lexema asociado,convirtiendo las letras minúsculas en mayúsculas: en el caso deun entero, yytext contendrá la secuencia de dígitos que loforman; en el caso de un booleano, contendrá o bien "TRUE" obien "FALSE".

Nota 2: Por cuestiones de claridad, cada parte de acciones UNO,...,OCHO sólo puede contener una instrucción C. En caso denecesitar más, se debe realizar una invocación a unprocedimiento o función con los parámetros adecuados. Porsupuesto, también debes escribir el código de estosprocedimientos y funciones.

Compiladores I 2ª Convocatoria 98/99 (8-VII-99)

4º Ing. Informática C.P.S. Universidad de Zaragoza

-3-

Ejercicio 2 (3.5 Ptos.): Considerar ahora la siguiente parte de lagramática anterior:

%token tkENT%%exp:ter '=' ter

| ter;

ter:ter '+' fact

| fact;

fact:tkENT

| '(' exp ')';%%

Construir la tabla del análisis LL(1) para esta gramática (o unaequivalente en caso de que sea no LL(1)).

Compiladores I 2ª Convocatoria 98/99 (8-VII-99)

4º Ing. Informática C.P.S. Universidad de Zaragoza

-4-

Ejercicio 3 (3.5 Ptos.): La siguiente gramática es no SLR(1).Transformarla en una equivalente que sea SLR(1) y construir el autómatay las tablas para el análisis SLR(1) de la gramática transformada

%token tkID tkOPAS tkVAL%%insts:insts inst

| inst;inst:etiq asig

;etiq:| tkID ':';asig:tkID tkOPAS tkVAL

;%%

Tiempo total para el examen: 2:00 horas

Compiladores I 2ª Convocatoria 98/99 (9-IX-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Se desea construir un lenguaje elemental para el manejo de cadenas decaracteres. Para una primera aproximación, el lenguaje sólo es capaz deescribir expresiones de cadenas (una expresión es una constante de tipocadena o bien la concatenación, mediante el operador “+”, de dos ó máscadenas). Un ejemplo de programa en dicho lenguaje sería el siguiente:

startprintln "Un refran:"println "No por mucho madrugar " + “amanece ” + "más temprano"

end

que debería dar como como salida

Un refran:No por mucho madrugar amanece más temprano

1. (1.50 Ptos.) Escribir una gramática Yacc que genere dicho lenguaje,teniendo en cuenta que el analizador léxico que utiliza es elmostrado en el anexo

2. (0.75 Ptos.) Generar el árbol de sintaxis para el programa mostrado,de acuerdo con la gramática que habeis escrito en el apartadoanterior

3. (0.5 Ptos.) De acuerdo con el analizador léxico. ¿Es correcto"\\\"Hola\"" como lexema para una cadena? ¿Por qué? ¿Cuálsería el valor de la variable filtrada una vez ejecutada lainstrucción filtra(yytext,filtrada)?

4. (0.5 Ptos.) De acuerdo con el analizador léxico. ¿Es correcto"\\\"Hola\" como lexema para una cadena ? ¿Por qué? ¿Cuálsería el valor de la variable filtrada una vez ejecutada lainstrucción filtra(yytext,filtrada)?

5. (1.75 Ptos.) Completar la gramática de manera que, asociado alsímbolo que corresponda a una expresión, se sintetice un atributodenominado "valExp" con el valor de la expresión (que será lacadena resultante de las concatenaciones involucradas en laexpresión, una vez filtradas adecuadamente).

6. (2.0 Ptos.) Construir las tablas y el autómata del análisis SLR(1) parala gramática definida

7. (1.0 Ptos.) Imaginemos que se añade una nueva instrucción allenguaje anterior (la instrucción "print" de semántica parecida a la

Compiladores I 2ª Convocatoria 98/99 (9-IX-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

de la instrucción "println", con la salvedad de que no salta delínea después de imprimir su argumento). Razonar sobre cuál seríael tamaño del nuevo autómata SLR(1), en comparación con elanterior

8. (2.0 Ptos.) Programar en C un analizador sintáctico descendenterecursivo para la gramática (o una transformada equivalente, en elcaso de no fuera LL(1)) que incluye además la instrucción "print"descrita en el apartado anterior

Tiempo total para el examen: 2:15 horas

Compiladores I 2ª Convocatoria 98/99 (9-IX-99)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

Anexo I: Fichero “cadenas.l”

%/*--------------------------------------------------”y.tab.h” contiene la definición de los tokenstkSTART tkEND tkPRINTLN tkCAD

--------------------------------------------------*/#include "string.h"#include "y.tab.h"extern char filtrada[256];

void filtra(char *cOr,char *cDes)int i = 1,

j = 0;

while(i <= strlen(cOr)-2)if(cOr[i] != '\\')

cDes[j] = cOr[i];i++;j++;else

if(i == strlen(cOr) -2)cDes[j] = cOr[i];i++;j++;

elseif (cOr[i+1] == '"')

cDes[j] = '"';i += 2;j++;else

cDes[j] = cOr[i];i++;j++;

cDes[j] = '\0';

%separadores ([\t \n])+%%separadores "start" return(tkSTART);"end" return(tkEND);"println" return(tkPRINTLN);\"([^\"\t\n]|\\\")*\" filtra(yytext,filtrada);

return(tkCAD);. return(yytext[0]);%%

Compiladores I 1ª Convocatoria 99/00 (5-II-00)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-1-

Ejercicio 1 (4.0 ptos.): Se desea implementar una calculadora con sintaxisLisp. El programa debe procesar una secuencia de listas Lisp tomadas deun fichero que se pasa como parámetro de la invocación. Así, si elprograma se llama “calcLisp”, la invocación

calcLisp fichCuentas

ejecutará las operaciones indicadas en el fichero de texto denominado“fichCuentas”.El fichero contiene una secuencia de listas separadas entre sí medianteun “;”. Cada lista contiene una expresión aritmética (en notación prefija),y para cada una de ellas se debe escribir el resultado de su expresióncorrespondiente por “stdout”. Para simplificar, asumiremos '+' y '*'como únicos operadores. En el siguiente ejemplo, la columna de laderecha muestra la salida para la ejecución con un fichero con elcontenido de la columna izquierda:

(+ 2 4 6 8 10);(* (+ 1 2 3) (+ 9 71)) ;(+ (* 10 2 3)

25(* 8 9 (+ 1 1) )

);(+ 20 -20);(+ 20);(* 30);

-> 30-> 102-> 229-> 0-> 20-> 3

Para resolver el problema se ha considerado la siguiente gramática (ensintaxis Yacc):

%start listas%token NUMERO%%listas :

listas lista ';'| lista ';'

;

Compiladores I 1ª Convocatoria 99/00 (5-II-00)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-2-

lista :'(' op listSE ')'

;op :

'+'| '*'

;listSE :

listSE SE| SE

;SE :

NUMERO| lista

;%%

A continuación se muestra tanto el esqueleto del autómata SLR(1) comola tabla ACCION (sin completar) para esta gramática.

Escribir los conjuntos de configuraciones de los nodos Completar la tabla ACCION. Indicar un desplazamiento al nodo “k”

como “d(k)” y una reducción por la producción número “k” como“r(k)” (la numeración de producciones se indica en la propiagramática, reservando la producción 0 para S’listas)

Nota: utilizar los nombres de símbolos de lagramática dada, sin cambiarlos

0 2 5

1

4

9

3 6 11

8

7

10

15

13

1214

NUMERO ; ( ) + * $

0123456789101112131415

ACCION

Compiladores I 1ª Convocatoria 99/00 (5-II-00)4º Ing. Informática. C.P.S. Universidad de Zaragoza

-3-

Ejercicio 2 (4.0 ptos.): Escribir un programa en C que implemente lacalculadora descrita. El programa debe tener las siguientescaracterísticas:

debe implementar un análisis descendente recursivo la gramática debe obtenerse mediante transformaciones de la que se

propone, de manera que sea viable la implementación del programa

Ejercicio3 (2.0 ptos.): Sea Σ un alfabeto, y sea r una expresión regular

sobre Σ. Vamos a denotar L(r) el lenguaje generado por la expresión r.Por otro lado, siendo r y s dos expresiones regulares,

rs representa el lenguaje L(rs)= vw | v ∈ L(r) y w[∈ L(s),formado por las concatenaciones de una cadena de r y una de s

r+s representa el lenguaje formado las cadenas de L(r) ∪∪∪∪ L(s)

Probar que r(s+t) = rs+rt Razonar sobre la siguiente afirmación: “ε∈ rs si, y sólo si, ε∈ r+s”

Tiempo total para el examen: 2:15 horas

Compiladores I 2ª Convocatoria 99/00 (19-VI-00)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:15 horas

Ejercicio 1 (5.0 ptos.): Lo que sigue son ejemplos de polinomios en unaúnica variable “X” y de coeficientes reales:

♦ ( 2.0 X^5+X^2- 5.0X ^6 )♦ ( -5.0 )♦ ( -1.0 +3.0X^3 )

que representan, respectivamente, los polinomios

♦ -5.0X6+2.0X5+X2

♦ -5.0♦ -3.0X3-1.0

Hay que tener presente que

♦ un polinomio siempre se escribe entre paréntesis♦ los coeficientes que aparezcan, siempre se escriben con parte entera y

parte decimal♦ los exponentes son siempre no negativos♦ a veces, puede no aparecer el coeficiente, en cuyo caso debe

entenderse que es 1.0♦ los distintos monomios pueden aparecer “desordenados” (es decir, no

siempre los monomios correspondientes a los mayores exponentesaparecen más a la izquierda en la línea)

♦ la única variable, “X”, puede aparecer tanto en mayúscula como enminúscula

Se nos pide implementar una calculadora que sea capaz de sumar, restarmultiplicar y dividir dos polinomios. Así, por ejemplo,

( 2.0 X^5+X^2- 5.0X ^6 ) + (-1.0 +3.0X^3 )

respresenta la suma de los dos polinomios. En concreto, el ejercicio pidelo siguiente:

1. Dar una estructura de datos para representar polinomios de grado 102. Implementar, utilizando Lex y Yacc, la calculadora (de entre las

operaciones, implementar únicamente la suma de polinomios). Su

Compiladores I 2ª Convocatoria 99/00 (19-VI-00)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:15 horas

funcionamiento debe ser tal que para la entrada anterior, escriba:

(-5.0X^6+2.0X^5+3.0X^3+1.0X^2-5.0)

La calculadora debe tratar polinomios de grado 10 por lo que en casode detectar un monomio de grado mayor debe ignorarlo.

Ejercicio 2 (1.25 ptos.): Razonar sobre si las siguientes afirmaciones soncorrectas o no, justificando las respuestas:

Sea G=(N,T,P,S) una gramática libre de contexto, y consideremos lagramática G’, obtenida de G mediante la eliminación de una de susproducciones. Entonces,• el lenguaje generado por G’ es siempre un subconjunto del

lenguaje generado por G• es más, se da la igualdad de ambos lenguajes si, y sólo si, la parte

izquierda de la producción eliminada es un símbolo no derivable.

Ejercicio 3 (1.25 ptos.): Razonar sobre si las siguientes afirmaciones soncorrectas o no, justificando la respuesta:

• en una tabla del análisis LL(1) en cada columna hay por lo menosun elemento distinto de error

• para una gramática dada, el autómata del análisis LR(1) essiempre mayor que el del análisis LALR(1)

Ejercicio 4 (2.5 ptos.): Construir el autómata y las tablas del análisissintáctico SLR(1) para la siguiente gramática:

%start A%token a b c d%%A :

a A a C d;C :

A C B d;B :

b B c|

;%%

Compiladores I 3ª Convocatoria 99/00 (01-IX-00)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:15 horas

♦ Ejercicio 1 (3.0 ptos.): Considerar la siguiente gramática:

%token a b c d%%S: X;X: M a;X: b M c;X: d c;X: b d a;M: d;%%

Se pide:

• Completar el autómata LALR que se muestra a continuación,definiendo los conjuntos de configuraciones que deben aparecer enlos nodos

• Escribir las tablas “ir_a” y “acción” correspondientes al análisis LALR

Compiladores I 3ª Convocatoria 99/00 (01-IX-00)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:15 horas

Ejercicio 2 (1.0 ptos.): Razonar sobre la siguiente afirmación:

Sea G=(N,T,P,S) una gramática libre de contexto que contiene

producciones ε. Siempre es posible encontrar una gramática

equivalente sin producciones ε.

Ejercicio 3 (6.0 ptos.):

• Escribir una gramática libre de contexto, LL(1), que reconozca lasiguiente expresión regular:

((a|b)+”.”(a|b)*)|(yx*y)

• Probar que, efectivamente, se trata de una gramática LL(1)

• Implementar, completamente en C, un analizador sintáctico para laexpresión anterior

Compiladores I 1ª Convocatoria 00/01 (09-II-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (3.5 ptos.): Como parte de una calculadora matemáticacompleja se desea implementar una herramienta capaz de realizaroperaciones de suma y resta de polinomios en la variable “X”(mayúscula o minúscula). Las operaciones a realizar se especifican en unfichero de texto. El fichero contiene una secuencia de cuaternas“polinomio,operador,polinomio,=”, indicando cada una de estascuaternas una operación a realizar, y estando los elementos en cuatrolíneas consecutivas. El fichero contiene al menos una de estasoperaciones. Así, por ejemplo, si el fichero denominado “misCuentas”contiene

3X^2 + x – 7.0+2.4X^2+-1.0 + 29X^5 –X^2=

x –7.0-–X^2 + 2X=

la invocación “calcula misCuentas” genera lo siguiente porstdout:

-> +29.00 X^5 +4.40 X^2 –8.00-> +1.00 X^2 -1.00 X^1 –7.00

Es preciso tener en cuenta los siguientes requisitos:• los polinomios no superan el grado 15• en la entrada, los monomios no tienen por qué estar ordenados por

grado, pudiendo incluso aparecer varios con el mismo grado• los coeficientes son reales, aunque se pueden escribir, como se ve en

el ejemplo, con parte decimal o sin ella, con signo o sin él e, incluso,no aparecer (en cuyo caso se ha de entender que es 1.0)

• los exponentes son naturales• en caso de no aparecer el exponente en un monomio, se entiende que

éste es 1• notar que en la salida se escriben todos los coeficientes con dos

decimales, con signo (pegado al coeficiente).

Compiladores I 1ª Convocatoria 00/01 (09-II-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Se pide escribir un analizador léxico en Flex, llamado “calcula.l”, unanalizador sintáctico en Bison, llamado “calcula.y”, y un fuente parala utilidad make, llamado “calculaMakefile”, de manera que laejecución “make –f calculaMakefile” genere el ejecutable“calcula”, con el comportamiento especificado.

Ejercicio 2 (2.0 ptos.): Responder a las siguientes cuestiones:

• Un desarrollador hace la siguiente propuesta a su jefe, responsabledel proyecto de desarrollo de un nuevo compilador: “con el objetivode poder dar una información más útil en el momento de larecuperación de errores sintácticos, es conveniente que cada vez queel analizador léxico encuentre un comentario, en lugar de ‘comérselo’,devuelva un token ‘tkCOM’”. ¿Es buena la opción?

• Considerar una gramática cualquiera G que contiene, entre otras, lassiguientes producciones: X → α, Y → α . Razonar sobre la siguienteafirmación: “Todo analizador SLR(1) para G generará un conflictoreducción/reducción entre las producciones anteriores”.

Compiladores I 1ª Convocatoria 00/01 (09-II-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (2.5 ptos.): Considerar la siguiente gramática:

%token a b c d e%%S: X;X: M a;X: b M c;X: b d a;M: e;%%

Se pide:

• Completar el autómata SLR(1) que se muestra a continuación,definiendo los conjuntos de configuraciones que deben aparecer enlos nodos

• Escribir las tablas “ir_a” y “acción” correspondientes al análisisSLR(1)

Notas1. El examen se puntúa sobre 8; las prácticas se puntúan sobre 22. Para aquéllos que aprobaran las prácticas en el curso anterior, el

examen se puntuará sobre 10.

Tiempo total para el examen: 2:15 horas

Compiladores I 2ª Convocatoria 00/01 (10-VII-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

Ejercicio 1 (1.5 ptos.): Transformar la siguiente gramática en unaequivalente, eliminando las producciones unitarias:

S --> C B a | DA --> b b CB --> S c | d d dC --> e A| f | CD --> E | S A B CE --> g h

Ejercicio 2 (2.5 ptos.): Considerar la siguiente gramática. ¿Es LL(1)? ¿EsSLR(1)?

S --> A | b A c | d c | b d aA --> d

Ejercicio 3 (4.0 ptos.): Estamos definiendo un lenguaje capaz demanipular listas planas de enteros. Una lista de enteros puede ser o bienuna lista vacía o bien una lista no vacía, que es aquélla que en su interiorcontiene al menos un entero. Lo que sigue son ejemplos de listas (en elprograma fuente, los comentarios se indican mediante la marca “#”,extendiéndose desde dicho carácter hasta el final de línea):

() #la lista vacía(1 2 3 4) #lista con los primeros enteros(-56 +23 8) #opcionalmente, puede haber signos

#que van “pegados” al valor absoluto

Lo que sigue es un pequeño ejemplo de fuente en el lenguajeconsiderado.

#Fichero: prueba.leVars l: lista := (1 2 3); #puede haber inicialización

lP: lista;n: entero;

PrincipiolP := listaVacia; #lP=(),l=(1 2 3),n=???n := primero(l); #lP=(),l=(1 2 3),n=1l := ponPrimero(l,n); #lP=(),l=(1 1 2 3),n=1lP := ponPrimero(lP,primero(l)); #lP=(1),l=(1 1 2 3),n=1l := resto(l); #lP=(1),l=(1 2 3),n=1lP := resto(l); #lP=(2 3),l=(1 2 3),n=1leer(n); #lP=(2 3),l=(1 2 3),n=N

Compiladores I 2ª Convocatoria 00/01 (10-VII-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

l := resto(resto(lP)); #lP=(2 3),l=(),n=Nl := ponPrimero(l,n); #lP=(2 3),l=(N),n=Nescribir(resto(lP)); #lP=(2 3),l=(N),n=N,en stdout “(3)”l := ponPrimero(l,n); #lP=(2 3),l=(N N),n=Nescribir(l); #lP=(2 3),l=(N N),n=N,en stdout “(N N)”

Fin.

El lenguaje tiene las siguientes características:

1. Las variables a utilizar han de ser declaradas2. En la declaración puede haber, opcionalmente, inicialización de la

variable3. Los operadores que maneja son los siguientes:

• “listaVacia”:Pre: TRUEPost: listaVacia=()

• “esVacia(l)”:Pre: l=(d1 d2 ... dn), n>=0Post: esVacia=¿n=0?

• “primero(expr)”:Pre: expr es una expresión de tipo lista,

expr=(d1 d2 ... dn), n>0Post: primero=d1

• “resto(expr)”:Pre: expr es una expresión de tipo lista,

expr=(d1 d2 ... dn), n>0Post: resto=(d2 ... dn)

• “ponPrimero(l,expr)”:Pre: expr es una expresión de tipo entero,

expr=Nl=(d1 d2 ... dn), n>=0

Post:ponPrimero=(N d1 d2 ... dn)• “:=”: asignación interna, lo mismo para enteros que

para listas• “leer”: asignación externa, lo mismo para variables

enteras que para variables de tipo lista• “escribir”: salida de resultados por stdout, lo mismo

para expresiones enteros que para expresiones de tipolista

• vamos a asumir, por cuestiones de simplicidad, quelas únicas expresiones de tipo entero son o bien unaconstante entera o bien una variable entera (esdecir, no vamos a sumar, restar, ... enteros)

4. Las invocaciones a operadores que no cumplan la precondición seconsiderarán como errores de tipo semántico

Compiladores I 2ª Convocatoria 00/01 (10-VII-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

5. El acceso a una variable sin inicializar también se considerará comoerror semántico

El ejercicio desarrolla un analizador de fuentes que, además de llevar acabo el análisis sintáctico haga “un poco” de análisis semántico (que acontinuación se va a detallar). Para ello se pide lo siguiente:

1. Escribir el fichero “lEnt.l” con el fuente Flex del compiladordescrito.

2. Escribir el fichero “lEnt.y” con el fuente Bison correspondiente alanalizador sintáctico, de manera que la invocación para procesar elfichero de listas “prueba.le” sigue el patrón del siguiente ejemplo:

lEnt prueba.le

Además del análisis sintáctico debe implementar los siguientesaspectos del análisis semántico: el programa debe comprobar,abortando en caso de detectar algún error

• que toda variable que aparezca en la parte izquierda de unaasignación haya sido declarada previamente.

• que en cada asignación tanto la variable en la parte izquierdacomo la expresión en la parte derecha sean del mismo tipo (obien ambas son enteros, o bien ambas son de tipo lista).

• que en toda expresión, toda variable utilizada ha sidopreviamente inicializada.

Nota 1: por simplificar, se puede suponer que en el programa no sevan a manejar nunca más de 1250 variables, y que losidentificadores no son de más de 25 caracteres

Compiladores I 3ª Convocatoria 00/01 (17-IX-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

Ejercicio 1 (1.0ptos.): Probar que la siguiente gramática es LL(1), pero noSLR(1)

S --> A a A bS --> B b B a

A --> εB --> ε

Ejercicio 2 (1.5 ptos.): El Anexo-I muestra el algoritmo para el análisisLL(1) basado en el uso de la tabla de análisis. Dada una secuencia ω determinales, el algoritmo emite la secuencia de producciones aplicadaspara su derivación, o error si no es capaz de encontrarla. Vamos adenotar n el número de no terminales de la gramática, y |ω| la longitudde la secuencia de entrada. Se sabe que, en el caso de que el algoritmo dérespuesta afirmativa, el coste de ejecución del algoritmo esΩ(|ω|),Ο(n∙|ω|). En el cálculo de este coste se han considerado comooperaciones de coste constante las siguientes:• obtener la cima de la pila• apilar y desapilar símbolos gramaticales• obtener el siguiente terminal de la sencuencia de entrada• consultar el valor en la tabla correspondiente a un par (no terminal,

terminal)• emitir una producción

Consideremos ahora la siguiente gramática:

X1 --> X2 X2 X2X2 --> a2 | X3X3 --> a3 | X4X4 --> a4 | X5....Xn-1 --> an-1 | XnXn --> an

El ejercicio pide escribir dos frases del lenguaje generado por lagramática anterior, ω1 y ω2, tal que los costes de ejecución del algoritmode reconocimiento sean, respectivamente, del orden de |ω1| y n∙|ω2|.¿Cuál puede ser el coste del algoritmo, en el mejor y el peor caso, cuandose aplica a una frase que no es reconocida por el análisis LL(1)?

Compiladores I 3ª Convocatoria 00/01 (17-IX-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

Nota: en todos los casos, la respuesta debe ser razonada.

Ejercicio 3 (5.5) ptos.): Se desea construir un intérprete para un lenguajemuy sencillo. Dicho lenguaje maneja cadenas de caracteres, y es capaz deasignarlas a variables, realizar la operación de concatenación y escribirpor salida estándar expresiones que involucran cadenas.

Un ejemplo de programa en dicho lenguaje sería el siguiente:

vars a b c;start

print("Un refran:");a="No por mucho ";b=""" madrugar""";a=a+b;print("a: " + a);c=b+b+b+" no es sano";print("res: " + c + " por mucho que te empeñes");print("a:");print(a);

end

cuya ejecución dará como salida

Un refran:a: No por mucho " madrugar"res: " madrugar"" madrugar"" madrugar" no es sano por mucho que te empeñesa:No por mucho " madrugar

Detallemos un poco más sus características:

1. las variables que se van a utilizar han de ser declaradas previamente(mediante la palabra reservada vars), y todas ellas son capaces dealmacenar una cadena de hasta 300 caracteres.

2. en su representación externa, una constante de tipo cadena va entredobles comillas. Entre ellas puede ir cualquier secuencia de 0 ó máscaracteres distintos del salto de línea o tabulador ('\n','\t') ;cuando se desea representar unas dobles comillas como parte delcontenido de la cadena, éstas se han de poner por duplicado (ver laasignación a la variable b en el programa de ejemplo).

Compiladores I 3ª Convocatoria 00/01 (17-IX-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

3. además de la asignación y la escritura, es posible realizar laconcatenación de cadenas, que se representa externamente medianteel operador '+'.

4. el lenguaje distingue entre mayúsculas y minúsculas

El ejercicio pide construir el intérprete completo: analizador léxico enFlex, sintáctico en Bison con las acciones necesarias para que el códigosea ejecutado. El intérprete debe ser tal que, si el programa fuenteanterior se llama “entradaCadenas.cad”la invocación sea

trataCadenas entradaCadenas.cad

Se valorará, además, el hecho de que el programa detecte algunoserrores semánticos importantes.

Compiladores I 3ª Convocatoria 00/01 (17-IX-01)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

Anexo-I

Pre: M:Nx(T∪ ε)→2P:tabla de análisis sintáctico LL(1)La frase a analizar termina con $

Post: Muestra la secuencia de producciones aplicadas enel análisis o ERROR

Variables p:pila de símbolos gramaticalessigTok,X:token

PrincipiopilaVacia(p);sigTok=yylex()push(p,$,S) --S es el símbolo inicial de la gramáticaRepetir

X=cima(p)Si X es terminal ∨ X=$

Si X=sigTokpop(p)sigTok=yylex()

Si noerrorSintáctico()

FSiSi no

Si M[X,sigTok]= X→Y1... Ykpop(p)push(p,YkYk-1... Y1)emitir producción X→Y1... Yk

Si noerrorSintáctico()

FSiFSi

Hasta Que X=$Fin

Compiladores I 1ª Convocatoria 01/02 (04-II-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

Ejercicio 1 (1.25 ptos.): Considerar los siguientes fuentes

/*------------------------------ prueba.l------------------------------*/%#include "y.tab.h"%%%[a-zA-Z]+ return(tkID);. return(yytext[0]);\n%%

/*------------------------------ prueba.y------------------------------*/%#include <stdio.h>extern char *yytext;%%token tkID%%F: tkID printf("0: %s\n",yytext); '.' | tkID printf("1: %s\n",yytext); '(' printf("2: %s\n",yytext); ')' printf("3: %s\n",yytext); '.';%%int main()

yyparse();

Explicar razonadamente cuáles serán las salidas de la ejecución delprograma generado a partir de dichos fuentes para las siguientesentradas:

UNO.

UNO().

Compiladores I 1ª Convocatoria 01/02 (04-II-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

Ejercicio 2 (1.25 ptos.): Escribir una gramática libre de contexto quegenere el subconjunto del lenguaje generado por la expresión regulara*b* que contengan más veces la a que la b. Razonar sobre la correcciónde la solución dada.

Ejercicio 3 (2.5 ptos.): Considerar la siguiente gramática:

%%A: A B | B;B: B '*' | '(' A ')' | 'x';%%

Se pide:

1. Construir el autómata y las tablas del análisis LALR(1)2. Tranformarla en una equivalente que sea LL(1), y calcular la tabla

del análisis LL(1) de la transformada

Ejercicio 4 (3.0 ptos.): Un grafo dirigido se define como una estructuracompuesta por dos tipos de elementos, arcos y nodos. Los arcos sonpares formados por nodos. Tanto arcos como nodos pueden tenerinformación asociada.La figura 2 muestra la descripción textual del grafo de la figura 1 (que eneste caso es un autómata finito) que genera una herramienta para lamanipulación de grafos dirigidos.

Compiladores I 1ª Convocatoria 01/02 (04-II-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

2 3

4 5

1 ++

0-9

0-9

0-9

0-9

0-9

.

.

Figura 1: Un autómata

numeroRealgraph [ node [ id 1 parameter "inicial" ] node [ id 2 parameter "" ] node [ id 3 parameter "final" ] node [ id 4 parameter "" ] node [ id 5 parameter "final" ] edge [ source 1 target 2 parameter "0-9" ] edge [ source 1

target 4 parameter "." ] edge [ source 2 target 2 parameter "0-9" ] edge [ source 2 target 3 parameter "." ] edge [ source 3 target 3 parameter "0-9" ] edge [ source 4 target 5 parameter "0-9" ] edge [ source 5 target 5 parameter "0-9" ]]

Figura 2: Descripción textual del autómata de la figura 1

Compiladores I 1ª Convocatoria 01/02 (04-II-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:45 horas

El ejercicio pide lo siguiente:

1. Definir las estructuras de datos necesarias para almacenar lainformación asociada a un grafo, de acuerdo con lo que se deducedel ejemplo anterior

2. Escribir los fuentes flex y bison necesarios para poder generar elprograma “grafo” que lee y almacena la descripción de un grafo apartir de un fichero de entrada cuyo nombre se pasa comoparámetro en la invocación del programa

Nota: se puede asumir que trabajaremos siempre con grafosde no más de 300 nodos y no más de 3000 arcos.

Compiladores I 2ª Convocatoria 01/02 (02-VII-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

Ejercicio 1 (1.0 ptos.): Demostrar que toda gramática libre de contextosin producciones epsilon y tal que cada alternativa empieza siempre porun terminal distinto es siempre LL(1).

Ejercicio 2 (3.0 ptos.): Considerar la siguiente gramática

%token a%%S: a S a | a a;

1. ¿Qué lenguaje genera?2. Construir el autómata y las tablas del análisis LALR(1).3. Está claro que no es una gramática LL(1). Tranformarla en una

equivalente que sí lo sea, y probar formalmente que la transformadaes de la clase LL(1).

Ejercicio 3 (4.0 ptos.): Los anexos I y II contienen los fuentes(incompletos) Flex y Bison de un programa para la evaluación del tipode expresiones aritméticas sencillas. En lugar de hacer una evaluación“al vuelo” del atributo TIPO, se va a hacer mediante la construcción yposterior evaluación del árbol de sintaxis correspondiente a la expresión.El tipo de una operación binaria (+, -, *, /) se determina como sigue apartir de los tipos de sus operandos: si ambos operandos son enteros, elresultado es ENTERO; si ambos son reales, el resultado es REAL; si sonde tipos distintos, el tipo del resultado es DESCONOCIDO. Las figuras 1y 2 muestran un ejemplo de árbol de sintaxis para una expresión una vezha sido generado y después de sintetizar el atributo de tipo,respectivamente. Para ello se utiliza el TAD específico definido en elanexo III.

El ejercicio pide: Completar los puntos /* 1 */ a / * 8 */ de los anexos I y II de forma

que se genere el árbol de sintaxis. Escribir el código de la función

TIPOS_ESCALARES evaluaTipo(ptArbolSintaxis p)que, dado un árbol de sintaxis, sintetiza el tipo en cada uno de susnodos, teniendo en cuenta las reglas para tipos que se han establecidoarriba.

Compiladores I 2ª Convocatoria 01/02 (02-VII-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

(EXPR,*,*, ,NULL)

(OP_BIN,*,*, , )

(EXPR,*,*, ,NULL)

(TERMINO,*,*, ,NULL)

(FACTOR,*,*, ,NULL)

(CONST_ENT,*,*,NULL,NULL)

(TERMINO,*,*, ,NULL)

(FACTOR,*,*, ,NULL)

(CONST_REAL,*,*,NULL,NULL)

laExp

Figura 1: Árbol de sintaxis decorado para la entrada “3 + 4.5”, previoa la evaluación del atributo de tipo.

Compiladores I 2ª Convocatoria 01/02 (02-VII-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

(EXPR,DESCONOCIDO,*, ,NULL)

(OP_BIN,DESCONOCIDO,*, , )

(EXPR,ENTERO,*, ,NULL)

(TERMINO,ENTERO,*, ,NULL)

(FACTOR,ENTERO,*, ,NULL)

(CONST_ENT,ENTERO,*,NULL,NULL)

(TERMINO,REAL,*, ,NULL)

(FACTOR,REAL,*, ,NULL)

(CONST_REAL,REAL,*,NULL,NULL)

laExp

Figura 2: Árbol de sintaxis decorado para la entrada “3 + 4.5” una vezque se ha evaluado el atributo de tipo.

Compiladores I 2ª Convocatoria 01/02 (02-VII-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

ANEXO-I

%#include "y.tab.h"#include "arbolSintaxisExp.h"% /*EXPRESIONES REGULARES*/separadores [\t ]+digito [0-9]letra [a-zA-Z]constEntera digito+constReal constEntera"."constEntera%%separadores /*nada*/constReal

/* 1 */return(tkREAL);

constEntera /* 2 */ return(tkENTERO);

\n /*nada*/. return(yytext[0]);%%

Compiladores I 2ª Convocatoria 01/02 (02-VII-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

ANEXO-II

%#include <stdio.h>#include <stdlib.h>#include "arbolSintaxisExp.h"

ptArbolSintaxis laExp;%%union

ptArbolSintaxis elArbol;%token <elArbol>tkREAL%token <elArbol>tkENTERO%type <elArbol>expr%type <elArbol>term%type <elArbol>factor%type <elArbol>term%left '-' '+'%left '*' '/'%%expr:

term /* 3 */

| expr opSum term /* 4 */

;opSum:

'+'| '-';term:

factor /* 5 */

| term opMul factor /* 6 */

;opMul:

'*'| '/';factor:

tkREAL /* 7 */

| tkENTERO /* 8 */

;%%int main() TIPOS_ESCALARES elTipoFinal;

yyparse();elTipoFinal = evaluaTipo(laExp);printf("Tipo de la expresión: ");muestraTipo(elTipoFinal);liberaArbol(laExp);exit(0);

Compiladores I 2ª Convocatoria 01/02 (02-VII-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

ANEXO-III

/*================================================================ Fichero: arbolSintaxisExp.h Tema: TAD para el manejo de árboles de sintaxis de expresiones simples Version: 1.0 Fecha: Jumio-02 Autor: Joaquin Com.: Ejercicio para construir árboles de sintaxis=================================================================*/typedef enum

OP_UN,OP_BIN,CONST_ENT,CONST_REAL,EXPR,TERMINO,FACTOR CLASE_DE_NODO;typedef enum ENTERO,REAL,DESCONOCIDO TIPOS_ESCALARES;

typedef struct NODO CLASE_DE_NODO laClaseDeNodo;TIPOS_ESCALARES elTipo;union

float valReal;int valEnt;

elValor;

struct NODO *expDcha;struct NODO *expIzda;

arbolSintaxis,*ptArbolSintaxis;

ptArbolSintaxis creaArbol(CLASE_DE_NODO laClase);/* Pre: Post: creaArbol = (laClase,*,*,NULL,NULL)*/void liberaArbol(ptArbolSintaxis p);/* Pre: p = (lC,eT,eV,eI,eD) Post: p = NULL, la memoria ocupada por los elementos

del árbol se ha liberado*/void ponElTipo(ptArbolSintaxis p,TIPOS_ESCALARES t);/* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,t,eV,eI,eD)*/void ponValorReal(ptArbolSintaxis p,float r);/* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,eT,r,eI,eD)*/void ponValorEntero(ptArbolSintaxis p,int n);/* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,eT,n,eI,eD)*/void ponExpIzda(ptArbolSintaxis p,ptArbolSintaxis e);/* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,eT,eV,e,eD)*/void ponExpDcha(ptArbolSintaxis p,ptArbolSintaxis e);/* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,eT,eV,eI,e)*/void ponClaseDeNodo(ptArbolSintaxis p,CLASE_DE_NODO c);

Compiladores I 2ª Convocatoria 01/02 (02-VII-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

/* Pre: p = (lC,eT,eV,eI,eD) Post: p = (c,eT,eV,eI,eD)*/CLASE_DE_NODO dameLaClaseDeNodo(ptArbolSintaxis p);/* Pre: p = (lC,eT,eV,eI,eD) Post: dameLaClaseDeNodo = lC*/TIPOS_ESCALARES dameElTipo(ptArbolSintaxis p);/* Pre: p = (lC,eT,eV,eI,eD) Post: dameElTipo = eT*/ptArbolSintaxis dameSubexpIzda(ptArbolSintaxis p);/* Pre: p = (lC,eT,eV,eI,eD) Post: dameSubexpIzda = eI*/ptArbolSintaxis dameSubexpDcha(ptArbolSintaxis p);/* Pre: p = (lC,eT,eV,eI,eD) Post: dameSubexpDcha = eD*/TIPOS_ESCALARES evaluaTipo(ptArbolSintaxis p);/* Pre: p = (lC,eT,eV,eI,eD) Post: sintetiza el atributo “elTipo” para cada uno de los nodos del

árbol, evaluaTipo = el tipo del nodo raíz (ver enunciado)

*/void muestraTipo(TIPOS_ESCALARES t);/* Pre: Post: imprime en stdout información sobre el tipo t*/

Compiladores I 3ª Convocatoria 01/02 (13-IX-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:00 horas

Ejercicio 1 (2.0 ptos.): Considerar la siguiente gramática para eltratamiento de un subconjunto muy simple de expresiones:

exp: tkENTERO;exp: tkID;exp: exp '+' exp;exp: tkID '(' exp ')';

Asumiendo que la función yylex (definida como int yylex()tal ycomo la genera Flex) devuelve el siguiente token, escribir en C unanalizador descendente recursivo que reconozca el mismo lenguaje quela gramática dada.

Ejercicio 2 (2.0 ptos.): Escribir el algoritmo que se especifica acontinuación, y estimar su coste de ejecución:

Función derivaEpsilon(E G: GLC) Dev (dE:booleano)--Pre: G=(N,T,P,S) es una gramática libre de contexto

--Post: dE = ¿L(G)?

Compiladores I 3ª Convocatoria 01/02 (13-IX-02)4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:00 horas

Ejercicio 3 (2.0 ptos.): Razonar sobre la verdad o falsedad de lassiguientes afirmaciones:

Sea G una gramática libre de contexto tal que contiene las produccionesX , Y .

un analizador SLR(1) siempre encontrará un conflictoreducción/reducción cuando se encuentre en la cima de lapila.

un analizador SLR(1) nunca encontrará un conflictoreducción/reducción cuando se encuentre en la cima de lapila.

Ejercicio 4 (2.0 ptos.): Considerar la siguiente gramática, ampliada de lapropuesta en el primer ejercicio,

SP: exp;exp: tkENTERO;exp: tkID;exp: exp '+' exp;exp: tkID '(' exp ')';

Construir las tablas del análisis SLR(1), y determinar si la gramáticapertenece a dicha clase o no.

Compiladores I 1ª Convocatoria 03/04 (21-I-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

Ejercicio 1 (3.0 ptos.): Lo que sigue son ejemplos de polinomios en una única variable “X” y de coeficientes reales: ♦ ( 2.0X^5+X^2-5.0X^6 ) ♦ ( -5.0 ) ♦ ( -1.0 +1.0X^3 ) que representan, respectivamente, los polinomios ♦ -5.0X6+2.0X5+X2 ♦ -5.0 ♦ X3-1.0 En la descripción de un polinomio hay que tener presente que:

1. un polinomio siempre se escribe entre paréntesis. 2. los coeficientes que aparezcan siempre se escriben con parte entera

y parte decimal. 3. el signo y el valor absoluto de un coeficiente nunca llevan

separadores entre ellos. 4. los exponentes son siempre no negativos. 5. a veces, puede no aparecer el coeficiente, en cuyo caso debe

entenderse que es 1.0. 6. los distintos monomios pueden aparecer “desordenados” (es

decir, no siempre los monomios correspondientes a los mayores exponentes aparecen más a la izquierda en la línea).

7. la única variable, “X”, puede aparecer tanto en mayúscula como en minúscula.

Como parte del desarrollo de un programa que trabaja con polinomios se nos ha suministrado el siguiente código.

typedef float tpPolinomio[11]; int elToken; . . . int main() tpPolinomio elPol; inicializaPol(&elPol); /*todo ceros*/ elToken = yylex();

Compiladores I 1ª Convocatoria 03/04 (21-I-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

polinomio(&elPol); escribePol(&elPol); fprintf(stdout,”Análisis correcto\n”);

El ejercicio pide lo siguiente: • Dar una gramática LL(1) para la parte de análisis sintáctico • Mediante la construcción de la tabla del análisis LL(1), comprobar

que la gramática propuesta es, efectivamente, de dicha clase. • Completar el código incompleto que se ha mostrado arriba. Para

ello, hay que escribir el fuente Flex para la parte del análisis léxico e implementar un analizador sintáctico descedente recursivo. Las acciones semánticas se limitarán a rellenar los datos del polinomio.

• Su funcionamiento debe ser tal que para una entrada como ( 2.0X^5 +X^2 -5.0X^6 )

escriba -5.0X^6+2.0X^5+1.0X^2

• La calculadora debe tratar polinomios de grado 10, por lo que en

caso de detectar un monomio de grado mayor debe simplemente ignorarlo.

Ejercicio 2 (3.0 ptos.): Para una gramática, descrita en el fichero bison denominado “examen.y”, la invocación a bison con la opción “-v” ha generado el fichero “examen.output” con la descripción (parcial) del autómata LALR(1). El contenido de dicho fichero es el mostrado en el Anexo I. En la descripción de un nodo del autómata no se almacena el conjunto de configuraciones completo, sino la información necesaria para poder completar el correspondiente conjunto de configuraciones. El ejercicio pide lo siguiente: • Deducir cuál es la gramática original en el fichero “examen.y”. • Dibujar completo el autómata LALR(1) correspondiente a dicha

gramática. • Construir completas las tablas del análisis LALR(1) correspondiente

a la gramática considerada. • Determinar si la gramática dada es de la clase LALR(1). En caso de

no serlo, transformarla en una equivalente que sí lo sea.

Compiladores I 1ª Convocatoria 03/04 (21-I-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

Ejercicio3 (2.0 ptos.): Sea Σ un alfabeto, y sea r una expresión regular

sobre Σ. Vamos a denotar L(r) el lenguaje generado por la expresión r. Por otro lado, siendo r y s dos expresiones regulares, • rs representa el lenguaje L(rs)= vw | v ∈ L(r) y w ∈ L(s), formado

por las concatenaciones de una cadena de r y una de s • r+s representa el lenguaje formado las cadenas de L(r) ∪ L(s) • siendo n un número natural, rn representa el lenguaje generado la

concatenación de n cadenas del lenguaje generado por r • siendo n un número natural, nr representa el lenguaje generado la

(r+r+...n veces...+r) El ejercicio pide razonar sobre la corrección o incorrección de las siguientes afirmaciones, donde r, s, t son expresiones regulares: • r(s+t) = rs+rt • ε∈rs si, y sólo si, ε∈r+s • (r+s)2 = r2 + s2 + 2rs

Compiladores I 1ª Convocatoria 03/04 (21-I-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

ANEXO-I state 0 0 $accept: . S $end q shift, and go to state 1 ',' shift, and go to state 2 S go to state 3 A go to state 4 C go to state 5 state 1 3 A: q . $default reduce using rule 3 (A) state 2 5 C: ',' . D u shift, and go to state 6 D go to state 7 state 3 0 $accept: S . $end $end shift, and go to state 8 state 4 1 S: A . B n shift, and go to state 9 B go to state 10 state 5

Compiladores I 1ª Convocatoria 03/04 (21-I-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

2 A: C . 6 C: C . n reduce using rule 2 (A) n [reduce using rule 6 (C)] $default reduce using rule 2 (A) state 6 7 D: u . 8 | u . ',' D ',' shift, and go to state 11 $default reduce using rule 7 (D) state 7 5 C: ',' D . $default reduce using rule 5 (C) state 8 0 $accept: S $end . $default accept state 9 4 B: n . C ',' shift, and go to state 2 C go to state 12 state 10 1 S: A B . $default reduce using rule 1 (S) state 11

Compiladores I 1ª Convocatoria 03/04 (21-I-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

8 D: u ',' . D u shift, and go to state 6 D go to state 13 state 12 4 B: n C . 6 C: C . $end reduce using rule 4 (B) $end [reduce using rule 6 (C)] $default reduce using rule 4 (B) state 13 8 D: u ',' D . $default reduce using rule 8 (D)

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

Ejercicio 1 (2.5 ptos.): Considerar la siguiente gramática: %token a b c %% S: A a A b S; S: B b B a; S: c; A: ; B: ; %%

El ejercicio pide: • ¿Qué lenguaje genera? • Obtener la tabla del análisis LL(1), y concluir si se trata de una

gramática de esa clase. • Obtener el autómata y las tablas del análisis LALR(1), y determinar

si se trata de una gramática de la clase LALR (1) o no. Ejercicio 2 (2.0 ptos.): Considerar la siguiente gramática libre de contexto, denominada G: %token a b %% S: b A | a B |; A: a b a S; B: b a b S;

El ejercicio pide: • ¿Se trata de una gramática regular ? (una gramática es regular si el

lenguaje que genera es un lenguaje regular). • Si es una gramática regular, dar un autómata finito determinista

mínimo cuyo lenguaje sea el mismo que el generado por dicha gramática. Dar también la expresión regular correspondiente a dicho autómata.

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

Ejercicio 3 (3.5 ptos.): Los anexos I y II contienen los fuentes (incompletos) Flex y Bison de un programa para la evaluación del tipo de expresiones aritméticas sencillas. En lugar de hacer una evaluación “al vuelo” del atributo TIPO, se va a hacer mediante la construcción y posterior evaluación del árbol de sintaxis correspondiente a la expresión. El tipo de una operación binaria (+, -, *, /) se determina a partir de los tipos de sus operandos como sigue: si ambos operandos son enteros, el resultado es ENTERO; si ambos son reales, el resultado es REAL; si son de tipos distintos, el tipo del resultado es DESCONOCIDO. Las figuras 1 y 2 muestran un ejemplo de árbol de sintaxis para una expresión una vez ha sido generado y después de sintetizar el atributo de tipo, respectivamente. Para ello se utiliza el TAD específico definido en el Anexo III. El ejercicio pide: • Completar los puntos /* 1 */ a / * 8 */ de los anexos I y II de

forma que se genere el árbol de sintaxis. • Escribir el código de la función

TIPOS_ESCALARES evaluaTipo(ptArbolSintaxis p) que, dado un árbol de sintaxis, sintetiza el tipo en cada uno de sus nodos, teniendo en cuenta las reglas para tipos que se han establecido arriba.

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

Figura 1: Árbol de sintaxis decorado para la entrada “3 + 4.5”,

previo a la evaluación del atributo de tipo.

(EXPR,?,?, ,NULL)

(OP_BIN,?,?, , )

(EXPR,?,?, ,NULL)

(TERMINO,?,?, ,NULL)

(FACTOR,?,?, ,NULL)

(CONST_ENT,?,?,NULL,NULL)

(TERMINO,?,?, ,NULL)

(FACTOR,?,?, ,NULL)

(CONST_REAL,?,?,NULL,NULL)

laExp

(EXPR,?,?, ,NULL)

(OP_BIN,?,?, , )

(EXPR,?,?, ,NULL)

(TERMINO,?,?, ,NULL)

(FACTOR,?,?, ,NULL)

(CONST_ENT,?,?,NULL,NULL)

(TERMINO,?,?, ,NULL)

(FACTOR,?,?, ,NULL)

(CONST_REAL,?,?,NULL,NULL)

laExp

(EXPR,?,?, ,NULL)

(OP_BIN,?,?, , )

(EXPR,?,?, ,NULL)

(TERMINO,?,?, ,NULL)

(FACTOR,?,?, ,NULL)

(CONST_ENT,?,?,NULL,NULL)

(TERMINO,?,?, ,NULL)

(FACTOR,?,?, ,NULL)

(CONST_REAL,?,?,NULL,NULL)

laExp

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

Figura 2: Árbol de sintaxis decorado para la entrada “3 + 4.5” una

vez que se ha evaluado el atributo de tipo.

(EXPR,DESCONOCIDO,?, ,NULL)

(OP_BIN,DESCONOCIDO,?, , )

(EXPR,ENTERO,?, ,NULL)

(TERMINO,ENTERO,?, ,NULL)

(FACTOR,ENTERO,?, ,NULL)

(CONST_ENT,ENTERO,?,NULL,NULL)

(TERMINO,REAL,?, ,NULL)

(FACTOR,REAL,?, ,NULL)

(CONST_REAL,REAL,?,NULL,NULL)

laExp

(EXPR,DESCONOCIDO,?, ,NULL)

(OP_BIN,DESCONOCIDO,?, , )

(EXPR,ENTERO,?, ,NULL)

(TERMINO,ENTERO,?, ,NULL)

(FACTOR,ENTERO,?, ,NULL)

(CONST_ENT,ENTERO,?,NULL,NULL)

(TERMINO,REAL,?, ,NULL)

(FACTOR,REAL,?, ,NULL)

(CONST_REAL,REAL,?,NULL,NULL)

laExp

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

ANEXO-I

% #include "y.tab.h" #include "arbolSintaxisExp.h" % /*EXPRESIONES REGULARES*/ separadores [\t ]+ digito [0-9] letra [a-zA-Z] constEntera digito+ constReal constEntera"."constEntera %% separadores /*nada*/ constReal /* 1 */ return(tkREAL); constEntera /* 2 */ return(tkENTERO); \n /*nada*/ . return(yytext[0]); %%

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

ANEXO-II

% #include <stdio.h> #include <stdlib.h> #include "arbolSintaxisExp.h" ptArbolSintaxis laExp; % %union ptArbolSintaxis elArbol; %token <elArbol>tkREAL %token <elArbol>tkENTERO %type <elArbol>expr %type <elArbol>term %type <elArbol>factor %type <elArbol>term %left '-' '+' %left '*' '/' %% expr: term /* 3 */ | expr opSum term /* 4 */ ; opSum: '+' | '-' ; term: factor /* 5 */ | term opMul factor /* 6 */ ; opMul: '*' | '/' ; factor: tkREAL /* 7 */ | tkENTERO /* 8 */ ; %% int main() TIPOS_ESCALARES elTipoFinal; yyparse(); elTipoFinal = evaluaTipo(laExp);

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

printf("Tipo de la expresión: "); muestraTipo(elTipoFinal); liberaArbol(laExp); exit(0);

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

ANEXO-III

/*============================================================ Fichero: arbolSintaxisExp.h Tema: TAD para el manejo de árboles de sintaxis de expresiones simples Version: 1.0 Fecha: Junio-02 Autor: J.E. Com.: Ejercicio para construir árboles de sintaxis ============================================================*/ typedef enum OP_UN,OP_BIN,CONST_ENT,CONST_REAL,EXPR,TERMINO,FACTOR CLASE_DE_NODO; typedef enum ENTERO,REAL,DESCONOCIDO TIPOS_ESCALARES; typedef struct NODO CLASE_DE_NODO laClaseDeNodo; TIPOS_ESCALARES elTipo; union float valReal; int valEnt; elValor; struct NODO *expDcha; struct NODO *expIzda; arbolSintaxis,*ptArbolSintaxis; ptArbolSintaxis creaArbol(CLASE_DE_NODO laClase); /* Pre: Post: creaArbol = (laClase,*,*,NULL,NULL) */ void liberaArbol(ptArbolSintaxis p); /* Pre: p = (lC,eT,eV,eI,eD) Post: p = NULL, la memoria ocupada por los elementos del árbol se ha liberado */ void ponElTipo(ptArbolSintaxis p,TIPOS_ESCALARES t); /* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,t,eV,eI,eD) */ void ponValorReal(ptArbolSintaxis p,float r); /* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,eT,r,eI,eD) */ void ponValorEntero(ptArbolSintaxis p,int n); /* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,eT,n,eI,eD) */ void ponExpIzda(ptArbolSintaxis p,ptArbolSintaxis e); /* Pre: p = (lC,eT,eV,eI,eD)

Compiladores I 2ª Convocatoria 02/03 (26-VI-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:15

Post: p = (lC,eT,eV,e,eD) */ void ponExpDcha(ptArbolSintaxis p,ptArbolSintaxis e); /* Pre: p = (lC,eT,eV,eI,eD) Post: p = (lC,eT,eV,eI,e) */ void ponClaseDeNodo(ptArbolSintaxis p,CLASE_DE_NODO c); /* Pre: p = (lC,eT,eV,eI,eD) Post: p = (c,eT,eV,eI,eD) */ CLASE_DE_NODO dameLaClaseDeNodo(ptArbolSintaxis p); /* Pre: p = (lC,eT,eV,eI,eD) Post: dameLaClaseDeNodo = lC */ TIPOS_ESCALARES dameElTipo(ptArbolSintaxis p); /* Pre: p = (lC,eT,eV,eI,eD) Post: dameElTipo = eT */ ptArbolSintaxis dameSubexpIzda(ptArbolSintaxis p); /* Pre: p = (lC,eT,eV,eI,eD) Post: dameSubexpIzda = eI */ ptArbolSintaxis dameSubexpDcha(ptArbolSintaxis p); /* Pre: p = (lC,eT,eV,eI,eD) Post: dameSubexpDcha = eD */ TIPOS_ESCALARES evaluaTipo(ptArbolSintaxis p); /* Pre: p = (lC,eT,eV,eI,eD) Post: sintetiza el atributo "elTipo" para cada uno de los nodos del árbol, evaluaTipo = el tipo del nodo raíz (ver enunciado) */ void muestraTipo(TIPOS_ESCALARES t); /* Pre: Post: imprime en stdout información sobre el tipo t */

Compiladores I 3ª Convocatoria 02/03 (09-IX-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

Ejercicio 1 (3.5 ptos.): Consideremos la siguiente definición de expresión regular para un alfabeto Σ: ε es la e.r. cuyo lenguaje es L(ε)=ε

Si a∈Σ, a es la e.r. cuyo lenguaje es L(a)=a

Sean r,s dos e.r. con lenguajes L(r) y L(s),

respectivamente

r+s es la e.r. cuyo lenguaje es L(r)∪L(s)

r.s es la e.r. cuyo lenguaje es L(r)L(s)

r* es la e.r. cuyo lenguaje es (L(r))*

(r) es la e.r. cuyo lenguaje es L(r) La figura muestra un esquema del diseño de lo que se pretende hacer.

Los elementos son los siguientes: • “nomFich” es el nombre de un fichero físico que contiene los

caracteres que componen el alfabeto de un lenguaje regular, siendo

el carácter # reservado para representar ε. • “generaReconocedor” es el nombre de un programa (puede ser

un programa hecho en C, o un script que realice varias invocaciones a programas o servicios, o lo que se considere oportuno) que genera el ejecutable “nomFich_ER”.

nomFichnomFich nomFichERnomFich_ERgeneraReconocedorgeneraReconocedor

Compiladores I 3ª Convocatoria 02/03 (09-IX-03) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 02:45

• Esta aplicación lee de entrada estándar una supuesta expresión regular basada en el alfabeto en “nomFich” y dice si se trata de una expresión regular para dicho alfabeto o no.

Veamos un par de casos de uso. Supongamos que el fichero de texto “AB” contiene la secuencia de caracteres “01”. La ejecución de generaReconocedor AB

deberá generar el ejecutable “AB_ER” de manera que la invocación AB_ER < ent1

siendo el contenido de “ent1” (0.0|1*)* debe decir que es una expresión regular correcta, mientras que la invocación AB_ER < ent2

siendo el contenido de “ent2” *0.0 debe decir que no es una expresión regular correcta. Ejercicio 2 (1.0 ptos.): Escribir una gramática libre de contexto que genere el siguiente lenguaje, probando la corrección de la solución propuesta: L(G)=ambn|m>=n>=0. Ejercicio 3 (3.5 ptos.): Considerar la siguiente gramática. Construir las tablas del análisis LL(1), SLR(1) y LALR(1), y determinar si se trata de una gramática de cada una de esas clases. S --> A | b A c | d c | b d a A --> d

Compiladores I 2ª Convocatoria 03-04 (06-07-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (3.0 ptos.): Considérese la siguiente gramática: Para la siguiente gramática construir el autómata y las tablas SLR(1). E -> '(' L ')' | a ; L -> E L | E ;

• Construir el autómata y las tablas SLR(1) • Transformar la gramática en una equivalente que sea LL(1), y

construir para ella la tabla del análisis LL(1). Ejercicio 2 (2.0 ptos.): Responder a las siguientes cuestiones

• ¿Es la siguiente gramática ambigua? Razonar la respuesta.

A -> a A a | ε ;

• ¿Es la siguiente gramática ambigua? Razonar la respuesta.

A -> A A | ( A ) | ε ; Ejercicio 3 (3.0 ptos.): Se desea construir un lenguaje elemental para el manejo de cadenas de caracteres. Para una primera aproximación, el lenguaje sólo es capaz de escribir expresiones de cadenas. Las expresiones se forman mediante cadenas y los operadores + (concatenación de cadenas) y - (resta de cadenas; para que ésta sea correcta, el segundo operando debe ser un sufijo del primero). Un ejemplo de programa en dicho lenguaje sería el siguiente: start println "UNO:" println "ab" + “cdefg” - "fg" end

que debería dar como como salida UNO: abcde

Tiempo total para el examen: 2:30 horas

Compiladores I 2ª Convocatoria 03-04 (06-07-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

1. Escribir una gramática Bison que genere dicho lenguaje, teniendo en cuenta que el analizador léxico que utiliza es el mostrado en el anexo.

2. Completar la gramática de manera que, asociado al símbolo que corresponda a una expresión, se sintetice un atributo denominado "valExp" con el valor de la expresión. Los aspectos semánticos que se consideren sin especificar deberán ser completados de manera justificada.

Anexo I: Fichero “cadenas.l”

% /*-------------------------------------------------- ”y.tab.h” contiene la definición de los tokens tkSTART tkEND tkPRINTLN tkCAD --------------------------------------------------*/ #include "y.tab.h" separadores ([\t \n])+ %% separadores "start" return(tkSTART); "end" return(tkEND); "println" return(tkPRINTLN); \"[^\"\t\n]*\" return(tkCAD); . return(yytext[0]); %%

Tiempo total para el examen: 2:30 horas

Compiladores I 1ª Convocatoria 03/04 (30-01-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (3.5 ptos.): Considérese la siguiente gramática (está escrita en sintaxis Bison), que se usa para el tratamiento de determinado tipo de expresiones: %token ENTERO AND BOOLEANO %% exp: ter expP ; expP: | '=' ter; ter: fact terP ; terP: | '+' fact terP | AND fact terP; fact: ENTERO | BOOLEANO | '(' exp ')' ;

Las reglas de tipo para las expresiones de la gramática son las siguientes:

1. Sólo se pueden sumar enteros; el resultado es un entero. 2. El operador AND sólo se puede aplicar sobre booleanos; el

resultado es un booleano. 3. El operador de igualdad '=' sólo puede aplicarse sobre elementos

del mismo tipo, y su resultado es siempre un booleano. 4. En el caso de que aparezca un error de tipos durante la traducción

(es decir, se viole alguna de las reglas anteriores), el tipo de la expresión será error.

La gramática considerada es LL(1). El ejercicio pide escribir un analizador descendente recursivo que sintentice el tipo de la expresión y, en caso de ser éste correcto, también su valor. Para ello hay que: • escribir un fuente Flex apropiado, entendiendo que debe devolver

BOOLEANO cuando encuentra true o false (sin distinguir mayúsculas de minúsculas) y ENTERO cuando encuentra una secuencia de uno o más dígitos (no vamos a considerar la posibilidad de enteros con signo). Además, se salta los separadores habituales. En cualquier otro caso devuelve el primer carácter encontrado.

• completar el fuente C que sigue, de manera que lleve a cabo el análisis solicitado. Nótese que esto implica desarrollar también el código del procedimiento "evaluaExp", así como las macros "EL_TIPO" y

Tiempo total para el examen: 2:30 horas

Compiladores I 1ª Convocatoria 03/04 (30-01-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

"EL_VALOR". En el Anexo-I se adjunta la especificación de un TAD para el manejo de árboles n-arios, limitados a un máximo de hijos. Vamos a asumir que los fuentes son léxica y sintácticamente correctos.

include "arbNArio.h" typedef enum ENT,BOOL,ERROR tipos; int elToken; int main() arbolN aSConcreta; elToken = yylex(); exp(&aSConcreta); evaluaExp(&aSConcreta); /*completa los atributos necesarios*/ switch(EL_TIPO(aSConcreta)) case BOOL: printf( "Tipo: booleano. Valor: %1d\n",EL_VAL(aSConcreta)); break; case ENT: printf( "Tipo: entero Valor: %1d \n", EL_ VAL(aSConcreta)); break; case ERROR: printf( "Tipo: error Valor: indefinido\n"); break; liberaArbol(&aSConcreta); exit(1);

Ejercicio 2 (1.0 ptos.): Sea G una gramática libre de contexto, y sea A uno de sus símbolos no terminales. Si A --> Aα1 | Aα2 | ... | Aαn

son todas las producciones recursivas por la izquierda a partir de A y A --> β1 | β2 | ... | βm

son el resto de producciones que tienen A en la parte izquierda, dar una transformación de G que, mediante la adición de un único nuevo no terminal Z, genere una gramática equivalente sin recursividad por la izquierda. Razonar sobre la corrección de la solución propuesta.

Tiempo total para el examen: 2:30 horas

Compiladores I 1ª Convocatoria 03/04 (30-01-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 3 (1.0 ptos.): Escribir una gramática libre de contexto que genere el siguiente lenguaje, probando la corrección de la solución propuesta: L(G)=ambn|m>=n>0. Mostrar el árbol de derivación para a3b2 . Ejercicio 4 (2.5 ptos.): Para la siguiente gramática, se pide construir el autómata y las tablas del análisis LALR(1), y concluir si se trata de una gramática de esa clase o no. %token I %% e: I | I '(' e ')' | I '[' e ']' | e '+' I ; %%

Tiempo total para el examen: 2:30 horas

Compiladores I 1ª Convocatoria 03/04 (30-01-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Anexo-I /********************************************************* Fichero: arbNArio.h Tema: especificación TAD arbol n-ario genérico Fecha: Septiembre-03 Uso: Para usar en COMPI **********************************************************/ #define MAX_HIJOS 12 /*ningún arbol sint. con sentido común tendrá más de MAX_HIJOS hijos*/ typedef void *ELEMENTO; /*para colgar la información del nodo*/ struct NODO; typedef struct NODO *bosque[MAX_HIJOS]; typedef bosque *ptBosque; typedef struct NODO ELEMENTO dato; int nHijos; bosque losHijos; nodo,*arbolN,**ptArbolN; void creaArbolUnitario(ELEMENTO e,ptArbolN ptA,int tamDato); /* Pre: TRUE Post: *a = <e,[]> Com: e se copia */ int numHijos(arbolN a); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: numHijos = n */ ptBosque losHijos(arbolN a); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: *losHijos = [a_1...a_n] Com: es un puntero a los hijos */ ELEMENTO raizC(arbolN a,int tamDato); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: *raiz = D', D'=D Com: raiz es una copia del contenido de la raíz */

Tiempo total para el examen: 2:30 horas

Compiladores I 1ª Convocatoria 03/04 (30-01-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

ELEMENTO raiz(arbolN a); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: *raiz = D Com: es un puntero al contenido de la raíz */ arbolN hijo(arbolN a,int i); /* Pre: *a = <D,[a_1...a_n]>,1<=i<=n Post: hijo = a_i Com: un puntero al hijo i-ésimo */ void liberaArbol(ptArbolN a); /* Pre: *a = <D,[a_1...a_n]> Post: *a = <> */ void eliminaHijo(arbolN a,int i); /* Pre: *a = <D,[a_1...a_n]>,1<=i<=n Post: *a = <D,[a_1...a_i-1,a_i+1...,a_n]> Com: a_i es eliminado físicamente */ void ponHijo(arbolN a,int i,arbolN h); /* Pre: *a = <D,[a_1...a_n]>,1<=i<=n+1 Post: *a = <D,[a_1...a_i-1,h,a_i+1...,a_n]> */ void copiaArbol(arbolN a,ptArbolN p,int tamDato); /* Pre: *a = <D,[a_1...a_n]> Post: *p = <D,[a_1...a_n]> Com: duplica el árbol *a y lo asigna a *p */

Tiempo total para el examen: 2:30 horas

Compiladores I 3ª Convocatoria 03/04 (02-09-04) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 2:30 horas

Ejercicio 1 (2.0 ptos.): Dar un método que elimine todas la producciones unitarias (aquéllas de la forma X-->Y, siende X e Y no terminales) de una gramática libre de contexto, dando lugar a una gramática equivalente sin producciones simples. Probar que la gramática obtenida es, efectivamente, equivalente a la original. Ejercicio 2 (3.5 ptos.): Considérese la siguiente gramática simplificada para declaraciones de variables en C: dec: tipo var_list tipo: int | float var_list: ident ',' var_list | ident

Si se trata de una gramática LL(1), construir su tabla de análisis LL(1). Si no lo es, transformarla en una equivalente que sí lo sea, y construir la tabla LL(1) de la gramática transformada. Para la gramática LL(1) obtenida, implementar un analizador sintáctico en C que, además, lea de la entrada estándar el fuente C y saque por la salida estándar el código la declaración equivalente en Ada. Así, por ejemplo, para la entrada int a,b,c

salida debería ser a,b,c: integer

Ejercicio 3 (2.5 ptos.): Construir el autómata y las tablas del análisis LR(1) para la siguiente gramática A --> ( A ) | a

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (2.5 ptos.): Considérese la siguiente gramática: 1.A) Se pide completar el siguiente autómata, que se corresponde al análisis SLR(1).

1) S → A b

2) S → E c

3) S → b A c

4) S → b E

5) A → a

6) E → a

c

Estado 10

Estado 6

Estado 7

Estado 8

Estado 9

Estado 1

Estado 2

Estado 3

Estado 4

Estado 5

Estado 0

a

a

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

1.B) Completar la siguiente tabla de análisis SLR(1).

a b c $ S A E Estado0 Estado 1 Estado 2 Estado 3 Estado 4 Estado 5 Estado 6 Estado 7 Estado 8 Estado 9 Estado 10

1.C) Como conclusión, determinar si se trata de una gramática SLR(1). En caso de respuesta negativa, explicar las causas de los conflictos producidos. 1.D) Se pide por último completar la secuencia de estados por los que pasaría el análisis SLR(1) cuando se aplica el procesamiento de la secuencia “bac”. (Nota: en caso de conflicto, debe asumirse que el analizador aplica las mismas reglas que por defecto aplica Bison.)

entrada árbol pila acción

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 2 (1.5 ptos.): Considérese la siguiente gramática G: 2.A) Para ella, construir completa la tabla del análisis LL(1), y concluir si se trata de una gramática de esa clase o no. 2.B) Transformar dicha gramática en una equivalente “sin ε” (una gramática G se dice “sin ε” cuando cumple que si ε no es del lenguaje, no hay ninguna producción epsilon, y si ε es del lenguaje, la gramática contiene S -> ε como única producción epsilon). Ejercicio 3 (2.0 ptos.): Sea L un lenguaje independiente de contexto (es decir, generado por una gramática independiente –libre- de contexto). Probar que L* es también un lenguaje independiente de contexto. Ejercicio 4 (2.0 ptos.): Se desea implementar un programa que procese lotes de futuras transacciones bancarias sobre una cuenta concreta y determine si dicho lote es aceptable o no. Un lote es aceptable si en ningún momento entra en números rojos (es decir, la cantidad de la cuenta es inferior a cero). Las transacciones pueden ser de dos tipos: ingresos o cargos de cantidades naturales (es decir, cantidades mayores o iguales a 0). El fichero de entrada para un lote de transacciones tiene el siguiente formato: la primera línea establece el saldo actual de una cuenta mediante el término "Saldo inicial:", seguido de un entero no negativo, que indica el saldo. La líneas siguientes representan transacciones: valores negativos representan cargos, valores positivos indican ingresos. Un ejemplo de fichero de lote de transacciones a procesar puede ser el siguiente:

Saldo inicial: 34567 + 1000 -300 - 500 +100

Si suponemos que el fichero anterior se denomina "miFichero", la ejecución del programa de validación, denominado "procesaTransacciones", sería

S→ var A | B

A → id A num | B

B → id B num | ε

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

procesaTransacciones < miFichero

que debe dar como salida

Lote correcto. Saldo final: 34867

En el caso de un lote incorrecto da un mensaje de error en cuanto encuentre una transacción incorrecta, como en el ejemplo siguiente (fichero "miOtroFichero"):

Saldo inicial: 1000 -300 +500 -2000 +300

procesaTransacciones < miOtroFichero

debería dar como resultado:

Transacción incorrecta: -2000. No se admiten estados de saldo negativo.

Para realizar el ejercicio se puede usar (modificar si fuera necesario) el siguiente fuente Flex ("procesaTransacciones.l"):

% #include <stdio.h> #include "procesaTransacciones.tab.h" % %option case-insensitive separador [\t\n ]+ digito [0-9] cteInt digito+ %% separador /*Saltarlo*/ "Saldo inicial:" return(tkSALDO); cteInt yylval.valCant = atoi(yytext); return(tkCANTIDAD); "+" return yytext[0]; "-" return yytext[0]; . return yytext[0]; %%

El ejercicio pide completar el siguiente fuente Bison ("procesaTransacciones.y") con las acciones necesarias para que su comportamiento sea el especificado. (Nota: no está permitido utilizar

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

ninguna variable auxiliar, debiendo trabajar exclusivamente con los atributos definidos. En caso de usar variables adicionales, el ejercicio se puntuará sobre 1.0 puntos.)

% #include <stdio.h> #include <string.h> % %union struct int valTrans; int estado; atribCantidad; int valCant; %start S %token <valCant>tkCANTIDAD %token tkSALDO %type <atribCantidad>cantidad %type <valCant>listaOperaciones %% S: tkSALDO cantidad listaOperaciones ; listaOperaciones: cantidad listaOperaciones | cantidad ; cantidad: tkCANTIDAD | '+' tkCANTIDAD | '-' tkCANTIDAD ; %% int main() yyparse(); exit(0);

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Estado 0 Estado 1 S

Estado 3

Estado 2

Estado 4

a

Estado 7

Estado 12

Estado 8 A

Estado 11

Estado 6

Estado 5

Estado 13

Estado 9 Estado 10

c

Ejercicio 1 (2.0 ptos.): Escribir una gramática libre de contexto, de la clase LL(1), que genere el mismo lenguaje que la expresión regular (a|c+|ba|bc)* b+ Probar que, efectivamente, es de dicha clase.

Ejercicio 2 (2.5 ptos.): Dada la siguiente gramática, se debe construir el autómata LR(1) y las tablas del análisis LR(1):

S: a a A| a A c| c; A: A b | b a;

Se pide: 2A) Rellenar el contenido de los estados del autómata LR(1). 2B) Completar el contenido de las tablas "acción" e "ir_a" correspondientes al análisis LR(1), y determinar si se trata de una gramática de la clase LR(1).

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

2C) Realizar los pasos necesarios para analizar la cadena de entrada aacb.

a b c $ S A

Estado 0

Estado 1

Estado 2

Estado 3

Estado 4

Estado 5

Estado 6

Estado 7

Estado 8

Estado 9

Estado 10

Estado 11

Estado 12

Estado 13

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 3 (1.0 ptos.): Justifica si es verdad o no la siguiente afirmación: “Toda gramática SLR(1) es también LL(1)”. Ejercicio 4 (1.0 ptos.): Determinar si el lenguaje generado por la siguiente gramática es finito o infinito. Razonar, tan formalmente como sea posible, la respuesta. S --> a a A | B B --> a A | b a --> b B

Pila Árbol entrada

Acción

Compiladores I 1ª Convocatoria 04/05 (02-02-05) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 5 (1.5 ptos.): Sea el siguiente analizador léxico (procesaArbolesBinarios.l) y el siguiente analizador sintáctico (procesaArbolesBinarios.y) para árboles binarios de números enteros: % #include <stdio.h> #include “procesaArbolesBinarios.tab.h” % %option case-insensitive separador [\t \n]+ digito [0-9] cteEntera digito+ %% separador /*saltarlo*/ cteEntera yylval.valCant = atoi(yytext); return tkNumero; “nil” return tkNil %%

% #include <stdio.h> % %union struct . . . /*completar con más atributos, si se considera necesario */ int estaOrdenado; /*1 si está ordenado, 0 en caso contrario */ atributosArbol; int valCant; %start arbol %token <valCant> tkNumero %token tkNil %type <atributosArbol> arbol %% arbol: tkNumero arbol arbol . . . ; | tkNil . . . ; %% int main() yyparse(); exit(0);

Completar el fuente Bison con los atributos y acciones necesarias para sintetizar el atributo “estaOrdenado”: los valores en el subárbol izquierdo han de ser <= que el valor del número actual, y los valores en el subárbol derecho han de ser >= que el valor del número actual. Así, (2 (1 nil nil) (3 nil nil) ) está ordenado, pero ( 1 (2 nil nil) (3 nil nil) ) no lo está.

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (2.5 ptos.): Considérese la siguiente gramática: S → a a A| a A c| c; A → A b | b a;

1.A) Se pide completar el siguiente autómata, que se corresponde al análisis LR Canónico.

1.B) Completar la siguiente tabla de análisis LR Canónico.

a b c $ S A E Estado 0 Estado 1 Estado 2 Estado 3 Estado 4 Estado 5 Estado 6

c

Estado 10

Estado 6

Estado 7

Estado 8

Estado 9

Estado 1

Estado 2

Estado 3

Estado 4

Estado 5

Estado 0

a

a

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Estado 7 Estado 8 Estado 9 Estado 10

1.C) Como conclusión, determinar si se trata de una gramática LR Canónica. En caso de respuesta negativa, explicar las causas de los conflictos producidos. 1.D) Se pide por último completar la secuencia de estados por los que pasaría el análisis LR Canónico cuando se aplica el procesamiento de la secuencia “ b a c” (Nota: en caso de conflicto, debe asumirse que el analizador aplica las mismas reglas que aplica Bison).

entrada árbol pila acción

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 2 (*.* ptos.): ¿Es la siguiente gramática ambigua? Justificar la respuesta.

S → a A a | b B b | ε A → b A | b B → a B | a

Ejercicio 3 (*.* ptos.): Escribir una gramática libre de contexto, de la clase LL(1), que genere el mismo lenguaje que la expresión regular:

((a+b*c)| (b*c))+ (a+b*c)

Ejercicio 4 (*.* ptos.): Lo que sigue son ejemplos de polinomios en una única variable “X” y de coeficientes reales: ♦ 2.0 X^5+X^2- 5.0X ^6 ♦ -5.0 ♦ -1.0 +3.0X^3 que representan, respectivamente, los polinomios ♦ -5.0X6+2.0X5+X2 ♦ -5.0 ♦ -3.0X3-1.0 Hay que tener presente que ♦ los coeficientes que aparezcan, siempre se escriben con parte entera y

parte decimal ♦ los exponentes son siempre no negativos ♦ a veces, puede no aparecer el coeficiente, en cuyo caso debe

entenderse que es 1.0 ♦ los distintos monomios pueden aparecer “desordenados” (es decir, no

siempre los monomios correspondientes a los mayores exponentes aparecen más a la izquierda en la línea)

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

♦ la única variable, “X”, puede aparecer tanto en mayúscula como en

minúscula Se nos pide implementar , usando Flex y Bison, un programa que sea capaz de leer un polinomio, terminado con un carácter "\n", lo almacene en una variable de tipo polinomio (typedef int polinomio[10]), y que a continuación lo escriba, multiplicado por 2.0. Por ejemplo, si la entrada es 2.0 X^5+X^2- 5.0X ^6 debería escribir por stdout lo siguiente:

+4.0X^5+2.0X^2-10.0X^6 El programa debe tratar polinomios de grado 10, por lo que, en caso de detectar un monomio de grado mayor, debe ignorarlo.

Ejercicio 4 (*.* ptos.): 4.A) Dada la siguiente gramática especificada en Bison y que describe la sintaxis de Bison, construir un analizador léxico en Flex que permita realizar el análisis sintáctico. El analizador léxico no debe tener en cuenta errores léxicos, ni estrategias de recuperación. %start spec %token tkIDENT /*incluye identificadores de terminales y no terminales*/ %token tkIDENTDP /* identificador (solo terminal) seguido de : */ %token tkACCIONC /* se refiere a una acción C delimitada entre llaves */ %token tkMARCA /* los símbolos %% */ %token tkPREC /* la secuencia %prec */ %% spec: tkMARCA reglas ; reglas: tkIDENTDP resto prec | reglas regla ; regla: tkDENTDP resto prec | '|' resto prec ; resto: | resto tkIDENT | resto accion ; accion: tkACCIONC

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

; prec: | tkPREC tkIDENT | tkPREC tkIDENT accion | prec ';' ; %% int main(int argc, char *argv[]) FILE *fin; extern FILE *yyin; if (argc == 2) if ((fin = fopen(argv[1],"r")) == NULL) fprintf(stderr,"ERROR: no se pudo abrir el fichero!\n"); exit(-1); else fprintf(stderr, "La invocacion debe ser: %s <fichero_fuente>\n”, argv[0]); exit(1); yyin = fin; yyparse(); exit(0);

4.B) Partiendo de la gramática en Bison, completarla (escribiendo las acciones necesarias, etc.), para que en el análisis de fuentes Bison determine cuál es la primera regla de mayor longitud y escriba por la salida estándar el número de orden de la regla y su longitud. Se entiende que la longitud de una regla se define como el número de terminales y no terminales que tiene en la parte derecha.

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 03:00

Estado 6

Estado 8

Estado 7

Estado 8

Estado 5

Estado 4

R

d Estado 9

Estado 10

Estado 11

Estado 12

Estado 13

Ejercicio 1 (3 ptos.): Considérese la siguiente gramática: S → L = R| R L → * R | d R → L

1.A) Se pide completar el siguiente autómata, que se corresponde al análisis LR Canónico.

Estado 1

Estado 3

*

S

Estado 2

Estado 0

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 03:00

1.B) Completar la siguiente tabla de análisis LR Canónico.

= * d $ S L R Estado 0 Estado 1 Estado 2 Estado 3 Estado 4 Estado 5 Estado 6 Estado 7 Estado 8 Estado 9 Estado 10 Estado 11 Estado 12 Estado 13

1.C) Como conclusión, determinar si se trata de una gramática LR Canónica. En caso de respuesta negativa, explicar las causas de los conflictos producidos. 1.D) Se pide por último completar la secuencia de estados por los que pasaría el análisis LR Canónico cuando se aplica el procesamiento de la secuencia “ d = d” (Nota: en caso de conflicto, debe asumirse que el analizador aplica las mismas reglas que aplica Bison).

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 03:00

entrada árbol pila acción

entrada árbol pila acción

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 03:00

Ejercicio 2 (1 pto.): ¿Es la siguiente gramática ambigua? Justificar la respuesta.

S → a A a | b B b | ε A → b A | b B → a B | a

Ejercicio 3 (1 pto.): Escribir una gramática libre de contexto que genere el mismo lenguaje que la expresión regular:

((a+b*c)| (b*c))+ (a+b*c) Ejercicio 4 (3 ptos.): Las siguientes especificaciones (en FLEX y BISON) tienen como objetivo realizar conjuntamente el análisis sintáctico de fuentes simplificados de BISON. 4.A) Notar que el fuente FLEX no está completo porque no devuelve el token ‘tkACCIONESC’. Completar la especificación FLEX para que salte las acciones C y le proporcione al analizador sintáctico el token ‘tkACCIONESC’. % #include <stdio.h> #include "y.tab.h" % ID [a-zA-Z]([a-zA-Z0-9]|_[a-zA-Z0-9])* %% (\t|\n|" ")+ ID return tkID; "'".|\n"'" return tkID; "%%" return tkMARCA; ***** completar aquí lo que solicita el ejercicio ***** . return yytext[0];

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 03:00

% #include <stdio.h> % %token tkID tkACCIONESC tkMARCA %% .... spec : tkMARCA reglas ; reglas : regla | reglas regla ; regla : parteIzq ':' listaPartesDchas ';' ; parteIzq : noTerminal ; listaPartesDchas : parteDcha | listaPartesDchas '|' parteDcha ; parteDcha : simbGramMasAcciones | parteDcha simbGramMasAcciones ; simbGramMasAcciones: accionesc | noTerminal accionesc | terminal accionesc ; accionesc : | '' tkACCIONESC '' ; noTerminal: tkID; ; terminal: tkID; ; %% int main(int argc, char *argv[]) FILE *fin; extern FILE *yyin; if (argc == 2) if ((fin = fopen(argv[1],"r")) == NULL) fprintf(stderr,"ERROR: no se pudo abrir el fichero!\n"); exit(-1);

Compiladores I 2ª Convocatoria 05/06 (28-09-06) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Tiempo total para el examen: 03:00

else fprintf(stderr, "La invocacion debe ser: %s <fichero_fuente>\n”, argv[0]); exit(1); yyin = fin; yyparse(); exit(0);

4.B) Partiendo del fuente BISON suministrado, completadlo (escribiendo las acciones necesarias, etc.), para que en el análisis de fuentes BISON determine cuál es la primera regla de longitud máxima y escriba por la salida estándar el número de orden de la regla y su longitud. Se entiende que la longitud de una regla se define como el número de terminales y no terminales que tiene en la parte derecha (en caso de que la parte

derecha sea ε, se considera de longitud 0).

Compiladores I 1ª Convocatoria 06/07 (12-02-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (2.0 ptos.): Considérese la siguiente gramática: 1.A) Se pide completar el siguiente autómata, que se corresponde al análisis SLR(1).

1.B) Como conclusión, determinar si se trata de una gramática SLR(1). En caso de respuesta negativa, explicar las causas de los conflictos producidos.

1) S → A

2) S → x b

3) A → a A b

4) A → B

5) B → x

A

Estado 7

Estado 4

Estado 6

Estado 1

Estado 2

Estado 3

Estado 5

Estado 9

Estado 0

Estado 8

Compiladores I 1ª Convocatoria 06/07 (12-02-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

1.C) Completar la siguiente tabla de análisis SLR(1).

a b x $ S A B Estado 0 Estado 1 Estado 2 Estado 3 Estado 4 Estado 5 Estado 6 Estado 7 Estado 8 Estado 9

1.D) Se pide por último completar la secuencia de estados por los que pasaría el análisis SLR(1) cuando se aplica el procesamiento de la secuencia “a x b”.

entrada árbol pila acción entrada árbol pila acción

Compiladores I 1ª Convocatoria 06/07 (12-02-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 2 (1.0 ptos.): Considérese la siguiente gramática G. Determinar si se trata de una gramática ambigua o no. Justificar la respuesta.

Ejercicio 3 (1.0 pto.): Consíderese el alfabeto Σ=a b c. Una cadena w de longitud mayor o igual a 1 se dice que es un palíndromo si se lee igual de derecha a izquierda que de izquierda a derecha. El ejercicio pide escribir una gramática independiente de contexto G=(N,T,S,P) que genere como lenguaje el conjunto de palíndromos de Σ∗. Ejercicio 4 (1.0 ptos.): Considérese la siguiente gramática G:

Probar que ninguna cadena w perteneciente al lenguaje generado por la gramática, L(G), puede contener la cadena “b a” como subcadena.

S→ a S

| a S b S

| ε

S→ a S

| S b

| a

| b

Compiladores I 1ª Convocatoria 06/07 (12-02-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 5 (3 ptos.): Construir una calculadora que realice la suma y la multiplicación de números complejos, de manera que lea un fichero de texto con expresiones y escriba por la salida estándar los resultados de las evaluaciones. La calculadora se ejecutará pasándole como único parámetro el nombre del fichero de texto que contiene las expresiones. Por ejemplo, asumamos que tenemos un fichero de texto "miFicheroDeExpresionesComplejas", cuyo contenido es:

(+2+4i)+(-3-i)*(-4-5i) (-4-i)*(-2-3i)*(-1-i)*(+1+10i) (+1+i)+(-1+i)+(+100+i) (-12.4+i)+(-1.7-i)

La ejecución de > calculadorai miFicheroDeExpresionesComplejas generará la salida:

Resultado: 9.0+23.0i Resultado: 199.0+71.0i Resultado: 100.0+3.0i Resultado: -14.1+0.0i

Notar que cada línea de resultado se corresponde con una de las líneas de expresiones. A partir del fuente Bison que se proporciona a continuación se pide: 5.A) Escribir el fuente Flex que le proporcione los tokens necesarios y le permita realizar la evaluación de expresiones complejas. 5.B) Completar el fuente Bison dado, para que realice los cálculos y muestre el resultado por la salida estándar.

% token tkREAL % token tkNUMEROI /* el número i*/ % left '+' '-' % left '*' %% calc_expresiones: calc_expresiones '\n' expresion ;

Compiladores I 1ª Convocatoria 06/07 (12-02-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

calc_expresiones: expresion ; expresion: expresion '+' expresion | expresion '*' expresion | '(' termino ')' ; termino: '-' parte_real '+' parte_imaginaria | '-' parte_real '-' parte_imaginaria | '+' parte_real '+' parte_imaginaria | '+' parte_real '-' parte_imaginaria ; parte_real: tkREAL ; parte_imaginaria: tkREAL tkNUMEROI | tkNUMEROI ; %% int main (int argc, char* argv[]) /* Completar el programa principal también */

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 1 (2.0 ptos.): Considérese la siguiente gramática:

E → ( L ) | a

L → L , E | E

1.A) Se pide completar el siguiente autómata y tablas, que se corresponde al análisis SLR(1). Como conclusión, determinar si se trata de una gramática SLR(1). En caso de respuesta negativa, explicar las causas de los conflictos producidos.

( , ) a $ E L Estado 0 Estado 1 Estado 2 Estado 3 Estado 4 Estado 5 Estado 6 Estado 7

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Estado 8

1.B) Se pide completar el siguiente autómata y tablas, que se corresponde al análisis LALR(1). Como conclusión, determinar si se trata de una gramática LALR (1). En caso de respuesta negativa, explicar las causas de los conflictos producidos.

( , ) a $ E L Estado 0 Estado 1 Estado 2 Estado 3 Estado 4 Estado 5 Estado 6 Estado 7 Estado 8

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Ejercicio 2 (3.5 ptos.): 2.A) Considérense las siguientes gramáticas:

/*G1*/ %token tkDEC tkID tkBEGIN tkEND P: D S ; D: D V | ; S: S I | ; V : tkDEC tkID ‘;’ ; V : tkDEC tkID ‘(‘ P ‘)’ ‘;’ ; V : tkDEC ‘[‘ D ‘]’ tkID ‘;’ ; I : tkID ‘;’ ; I : tkBEGIN P tkEND ;

*/G2*/ %token tkDEC tkID tkBEGIN tkEND P: D S ; D: D V | ; S: S I | ; V : tkDEC tkID ‘;’ ; V : tkDEC tkID ‘[‘ P ‘]’ ‘;’ ; V : tkDEC ‘(‘ D ‘)’ tkID ‘;’ ; I : tkID ‘;’ ; I : tkBEGIN P tkEND ;

Determinar si las siguientes frases (en que la correspondencia entre lexemas y “tokens” es la que dice la intuición) pertenecen al lenguaje generado por alguna de las gramáticas G1 ó G2. En caso afirmativo, dar un árbol de derivación para cada una de ellas. En caso de respuesta negativa, dar alguna razón.

decl id ( begin id ; [ id ] end ) decl id ( decl [ decl id ; ] id ; ) ;

2.B) Responder, de manera justificada, a las siguientes preguntas:

1. ¿Puede una gramática LL(1) ser ambigua? 2. Toda gramática sin símbolos inútiles con un ciclo de producciones unitarias es

ambigua

2.C) Considérese la siguiente gramática para el procesamiento de listas de nombres.

*/G3*/ %token tkNOM lN: lN tkNOM ; lN: tkNOM ;

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Suponiendo que deseamos construir un analizador ascendente mediante cualquiera de las técnicas estudiadas en el curso, determinar si esta tarea es viable sin transformar la gramática. Razonar adecuadamente la respuesta. Ejercicio 3 (2.5 ptos.): Los siguientes ejemplos son tuplas de números naturales junto con su representación en forma de árbol n-ario.

( 2 5 4 )

( 2 ( 3 6 6 ) 1 ) Un patrón de tuplas de números naturales es una tupla en la que sus elementos son o bien números naturales o bien el símbolo ‘*’+, como, por ejemplo, ( 2 5 * ). Se trata de construir un programa que recorra un fichero de texto que contiene una tupla o un patrón y lo almacene en un ábol n-ario. Para ello, se ha programado el analizador léxico suministrado en el Anexo-I. El ejercicio pide completar el programa, parcialmente desarrollado en el Anexo-II, de manera que: 5.A) Se implemente el procedimiento void analizadorDescendenteRecursivo(ptArbolN a) Éste utiliza un analizador sintáctico descendente recursivo de manera que devuelve en el parámetro “a” el árbol que representa la tupla o el patrón. 5.B) Se implemente la función int esPatron(arbolN a) para que, dado un árbol n-ario correspondiente a una tupla o un partón determine si es un patrón o no.

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Anexo-I: Analizador léxico suministrado

% #include "declaraciones.h" extern int yylval; % DIGITO [0-9] %% DIGITO+ yylval = atoi(yytext); return tkNATURAL; "("|")"|"*" return yytext[0]; [ \t]+ . fprintf(stderr, "Lexical Error: %s\n", yytext ); exit(1); %%

>> declaraciones.h

#ifndef _DECLARACIONES_H #define tkNATURAL 256 int yylval; #endif

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Anexo-II: Desarrollo parcial del programa a construir

#include "arbNArio.h" #include <stdio.h> #include "declaraciones.h" int elToken; extern int yylval; extern FILE* yyin; void analizadorDescendenteRecursivo(ptArbolN a) // completar... int esPatron(arbolN a) // completar... int main(int argc, char *argv[]) arbolN miArbol; if (argc == 2) yyin = fopen(argv[1], "r"); elToken = yylex(); analizadorDescendenteRecursivo(&miArbol); if (esPatron(miArbol)) fprintf(stdout, "Es Patr’on\n"); else fprintf(stdout, "No es Patr’on\n"); liberaArbol(&miArbol); exit(0); else fprintf(stderr,"Err.-> %s ficheroTuplas", argv[0]); exit(1);

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

Anexo III : Especificación de un TAD para árboles n-arios genéricos en C

/********************************************************* Fichero: arbNArio.h Tema: especificación TAD arbol n-ario genérico Fecha: Septiembre-03 Uso: Para usar en COMPI **********************************************************/ #include "arbNArio.h" #define MAX_HIJOS 12 /*ningún arbol sint. con sentido común tendrá más de MAX_HIJOS hijos*/ typedef void *ELEMENTO; /*para colgar la información del nodo*/ struct NODO; typedef struct NODO *bosque[MAX_HIJOS]; typedef bosque *ptBosque; typedef struct NODO ELEMENTO dato; int nHijos; bosque losHijos; nodo,*arbolN,**ptArbolN; void creaArbolUnitario(ELEMENTO e,ptArbolN ptA,int tamDato); /* Pre: TRUE Post: *a = <e,[]> Com: e se copia */ int numHijos(arbolN a); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: numHijos = n */ ptBosque losHijos(arbolN a); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: *losHijos = [a_1...a_n] Com: es un puntero a los hijos */ ELEMENTO raizC(arbolN a,int tamDato); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: *raiz = D', D'=D Com: raiz es una copia del contenido de la raíz */ ELEMENTO raiz(arbolN a); /* Pre: *a = <D,[a_1...a_n]>,0<=n Post: *raiz = D Com: es un puntero al contenido de la raíz

Compiladores I – Duración 3h 15min. 2ª Convocatoria 06/07 (04-09-07) 4º Ing. Informática. C.P.S. Universidad de Zaragoza

*/ arbolN hijo(arbolN a,int i); /* Pre: *a = <D,[a_1...a_n]>,1<=i<=n Post: hijo = a_i Com: un puntero al hijo i-ésimo */ void liberaArbol(ptArbolN a); /* Pre: *a = <D,[a_1...a_n]> Post: *a = <> */ void eliminaHijo(arbolN a,int i); /* Pre: *a = <D,[a_1...a_n]>,1<=i<=n Post: *a = <D,[a_1...a_i-1,a_i+1...,a_n]> Com: a_i es eliminado físicamente */ void ponHijo(arbolN a,int i,arbolN h); /* Pre: *a = <D,[a_1...a_n]>,1<=i<=n+1 Post: *a = <D,[a_1...a_i-1,h,a_i+1...,a_n]> */ void copiaArbol(arbolN a,ptArbolN p,int tamDato); /* Pre: *a = <D,[a_1...a_n]> Post: *p = <D,[a_1...a_n]> Com: duplica el árbol *a y lo asigna a *p */