Compiladores Ficha de exercícios Simão Melo de Sousa Ano lectivo 2004/2005 1 Linguagens Formais: Construir Frases Exercício 1 Para cada uma das gramáticas G seguintes, (a) descreva a linguagem L(G) gerada pela gramática considerada, (b) Demonstre a sua afirmação, quando possível, (c) Diga de que tipo (classe) é a gramática: 1. S as ba A ba c 2. S aas aa 3. S aas a b 4. S aa A bs a 5. S SA SA BS BS ab B a A c Para esta última gramática, dê duas derivações distintas de aabc Exercício 2 (Gramáticas e derivações) Seja G a gramática definida pelas produções seguintes: S A AC A a b c C AC BC A B B 0 1 2 3 4 5 6 7 8 9 1
1. Diga, das afirmações seguintes, quais são verdadeiras: (a) ab037 L(G) (b) 2a3b L(G) (c) aaaa L(G) (d) S a (e) S ab (f) BC 2 (g) BC + 2 (h) C 2abc (i) C 5 3b4 2. Que linguagem gera a gramática G? Exercício 3 (Gramáticas Formais) Seja G a gramática seguinte, definida a partir do alfabeto A = {a, b, i, e, t} e de símbolo inicial S: S ::= i E t S S S ::= a S ::= e S S ::= ɛ E ::= b 1. A que clásse pertence a gramática G? Justifique. 2. Dê uma árvore de derivação da palavra ibtibtaea 3. Será G ambígua? Justifique. 4. Dê uma derivação esquerda e uma derivação direita da palavra ibtibtaeaeibtaea Exercício 4 Defina uma gramática geradora para cada uma das linguagens seguintes: 1. {a n b p n 1, p 1} 2. {a n b p n 0, p 3} Exercício 5 Mostre que a linguagem {ab 2n cc n 0} pertence a classe 3 (classe das linguagens regulares). Defina uma gramática de tipo diferente de 3 que gera esta linguagem. 2
Exercício 6 Seja G a gramática definida pelas produções seguintes: S ac C ac abc BC CB Ba ab CB Cb bb Bb Cb b Qual é a classe da gramática G? Qual é a linguagem gerada por G? Dê uma gramática de classe 2 (algébrica ou livre de contexto ) equivalente a G. Exercício 7 Considere a gramática G definida pelas seguintes regras de produção: S aa A bs a Construa a árvore de derivação da palavra ababaa. Exercício 8 Mostre que a gramática G definida pelas produções seguintes: é ambígua. S SS asb ɛ Exercício 9 Mostre que uma linguagem algébrica L sobre um alfabeto Σ pode sempre ser gerada por uma gramática G = (Σ, N, P, S) tal que todas as suas produções são da forma A α onde A N e α (N Σ ) Exercício 10 Mostre que as linguagens seguintes são algébricas: 1. L 1 = {a n b p n > p 0} 2. L 2 = {a n b p (n, p 0) (n p)} 3. L 3 = {a n b p c k (n, k 0) (p n + k)} Exercício 11 Seja Σ o alfabeto {a, b}. Mostre que a linguagem sobre Σ constituída de todas as palavras terminadas em a 3 ou b 2 é regular. Exercício 12 Defina uma gramática regular sobre o alfabeto Σ = {a, b} que gera a linguagem constituída por todas as palavras de Σ que contenham um número par de ocorrências de a e um número ímpar de ocorrências de b. 3
Exercício 13 Considere o alfabeto {a, b}. Identifique as expressões regulares representativas das seguintes linguagens: 1. Frases iniciadas por zero ou mais símbolos a seguidos por um ou mais b. 2. Frases formadas por um número par de elementos do alfabeto. 3. Frases iniciadas e terminadas pelo símbolo a. 4. Frases que contêm, pelo menos uma vez, o símbolo a. Exercício 14 (Equivalência entre expressões regulares) A seguinte tabela lista algumas equivalências entre expressões regulares. 1 αɛ = ɛα = α elemento neutro da concatenação 2 α + = + α = α elemento neutro da união 3 (α + β) + γ = α + (β + γ) associatividade da união 4 (αβ)γ = α(βγ) associatividade da concatenação 5 α + β = β + α comutatividade da união 6 α + α = α idempotência 7 α(β + γ) = αβ + αγ distributividade da concatenação a direita 8 (β + γ)α = βα + γα distributividade da concatenação a esquerda 9 α + = αα = α α relação entre fechos 10 α = ɛ + α + relação entre fechos e união 11 (α + ɛ) + = (ɛ + α) + = α relação entre fechos e união Utilize esta tabela para a resolução das alíneas seguintes. 1. Mostre a equivalência de a b + a bb + com a b + 2. Reduza a expressão regular ab + b(b + a + )aa Exercício 15 Considere o seguinte algoritmos: Algoritmo: Conversão de uma gramática regular numa expressão regular Entrada: Resultado: Uma gramática regular Um sistema de equações de expressões regulares 1. Para cada símbolo não terminal A, que apareça no lado esquerdo de uma produção A α 1 α 2... α n, gerar a seguinte expressão: A = φ 1 φ 2... φ n onde φ i é a expressão regular correspondente a α i. 4
2. Para cada símbolo não-terminal A, que apareça no lado esquerdo de uma produção A α 1 α 2... α n, gerar a seguinte expressão regular A = φ 1 + φ 2 +... + φ n onde φ i é a expressão regular correspondente a α i. 3. Simplificar as expressões regulares usando as regras da tabela do exercício 14 ou as regras seguintes: (a) A = β + αa é equivalente a A = α β (b) A = β + Aα é equivalente a A = βα 4. Resolve-se o sistema de equação em ordem ao símbolo inicial. Descreva então por uma expressão regular as linguagens geradas pelas gramáticas seguintes: 1. S Sa B B b Bb 2. S SA SA BS BS ab B a A c Exercício 16 Descreva por uma expressão regular as linguagens geradas pelas gramáticas seguintes: 1. S aa b A bs aa 2. S A B A aa bc B bb ae ɛ C bc ɛ E B ce Exercício 17 (Reconhecimento duma string por uma expressão regular) Neste exercício, propomo-nos de escrever uma função que permita determinar se uma palavra pertence a uma linguagem L(r) gerada por uma expressão regular r. As expressões regulares são representadas elementos do tipo OCaml seguinte: 5
type expreg = Vazio (* Linguagem vazia *) Epsilon (* Palavra vazia ɛ *) Caractere of char (* Caracter c *) Uniao of expreg * expreg (* r 1 r 2 *) Produto of expreg * expreg (* r 1 r 2 *) Estrela of expreg (* r *) 1. Defina uma função contem_epsilon : expreg bool que determina se a palavra vazia ɛ pertence à linguagem gerada pela expressão regular dada em parâmetro. 2. Define-se por resíduo duma expressão regular r relativamente a um caracter c da forma seguinte : Res(r, c) = { w cw L(r) } (a) Calcula Res(r, c) no caso de r = (a b) a e c {a, b}. (b) A linguagem Res(r, c) pode ser ela própria descrita por uma expressão regular. Escreva uma função residuo : expreg char expreg que calcula, a partir de r e de c uma expressão regular r tal que L(r ) = Res(r, c). (c) Calcular residu r c no caso onde r = (a b) a e c {a, b}. 3. Deduzir uma função reconheçe : expreg char list bool que determina se uma lista de caracteres pertence à linguagem definida pela expressão regular dada em parâmetro. 4. Aplicar esta função ao reconhecimento da palavra aba pela expressão regular r = (a b) a. Exercício 18 (Gramática LL(1)?) Seja G a gramática seguinte, definida a partir do alfabeto A = {a, b, i, e, t}: S ::= i E t S S S ::= a S ::= e S S ::= ɛ E ::= b 6
1. Calcula as funções nulo, primeiro e seguinte para a gramática G. 2. Define a tabela de transições da análise descendente LL(1) de G. 3. Será esta gramática uma gramática LL(1)? Justifique. 2 Linguagens Formais: Reconhecer Frases Exercício 19 Defina um autómato sobre {0, 1} que reconhece números binários múltiplos de 5 Exercício 20 Sejam Σ = {a, b} um alfabeto e G uma gramática regular definida pelas produções seguintes: S aa bd a ɛ A aa b D aa bs Defina um autómato A que reconheça a linguagem gerada por G. Exercício 21 1. Construa um autómato que reconhece a linguagem gerada pela gramática regular seguinte: S 01A 11B A 0B 1S 01 B 0S 2. Defina uma expressão regular sobre {0, 1} que reconhece a linguagem gerada por G. Exercício 22 (construção de autómatos a partir de linguagens regulares) Seja Σ = {a, b} um alfabeto. Defina um autómato que reconheça palavras de comprimento ímpar Defina um autómato que reconheça palavras cujo comprimento é um múltiplo de 4. Exercício 23 (Construção de autómatos a partir de expressões regulares) Seja Σ = {a, b, c, d} um alfabeto. Dê o autómato determinista minimal que reconhece as expressões regulares seguintes: (a + c) 3 7
((abc + cba)d+) (aabbbcccc)+ Exercício 24 (Retirado de Processadores de linguagens, Rui Crespo, IST Press) Considere o seguinte protocolo de comunicação de mensagens binárias entre dois computadores. O início e o fim de cada transmissão é marcada pelos caracteres, respectivamente, 00 e 11. As mensagens são obrigatoriamente iniciadas por três bits, indicativos do seu comprimento. Entre duas mensagens há um separador constituído pelo padrão 101. Em todas as transmissões há, no mínimo, uma mensagem por transmitir. Um exemplo de transmissão válida de mensagem é dada por: init size msg sep size msg end 00 010 11 101 001 1 11 1. Escreva uma gramática descritora da transmissão de mensagens. 2. Converta a gramática numa expressão regular. 3. Converta a expressão num AFND. 4. Determina o AFND em AFD. 5. Minimise o AFD. 6. Implemente um reconhecedor de transmissões. Exercício 25 (Autómato determinista minimal e expressão regular) Sejam A {a, b, c}, um alfabeto e r (a bb) cc(a) + b, uma expressão regular sobre o alfabeto A. Dê o autómato finito determinista minimal que reconhece a linguagem L(r). Sugerimos que comece por determinar um autómato não determinista com transições ɛ, que remova as transições ɛ, que torne determinista o autómato resultante e que, finalmente, aplique o algoritmo de minimização. Exercício 26 (Autómatos Regulares) Considere o autómato da figura 1, definido sobre o alfabeto A = {a, b, c}: Determinise o autómato A 1. O autómato resultante será designado por A 2. Minimise A 2. O autómato resultante será designado por A 3. Que linguagem reconhecem os autómatos A 1, A 2 e A 3? 8
Figura 1: O Autómato A 1 Exercício 27 (Autómatos Finitos) Considere o alfabeto A = {a, b} e o autómato A 1 com transições ɛ representado na figura 2. Nesta figura as transições ɛ são representadas por @ Que linguagem reconhece este autómato? Dê um autómato A 2 sem transições ɛ equivalente a A 1. Determinise, caso necessário, o autómato A 2. O autómato resultante será designado por A 3. Minimise A 3. Exercício 28 1. Demonstre que os autómatos A 1 e A 2 da figura 3 reconhecem a mesma linguagem regular. 2. Dê uma expressão regular que descreva a linguagem gerada por estes autómatos. Exercício 29 (Expressões regulares e análise léxica) O objectivo é alinhavar a construção de um analisador léxico para a pequena linguagens apresentada a seguir. Para cada unidade léxica, indicamos o tipo de token associado (neste caso concreto, um número), o seu valor assim como a expressão regular que a define. 9
Figura 2: Autómato A 1 (com transições ɛ) Figura 3: Autómato A 1 e Autómato A 2 10
Tipo Valor Expressão regular Palavras reservadas 1 if, then, else, begin,end a própria palavra Identificadores 2 o nome do identificador letra (letra dígito)* Inteiro 3 o valor (-)?dígito(dígito)* Operação aritmético 4 o operador + - * / Operador relacional 5 o operador < <= > >= = <> Atribuição 6 := := Strings 7 o valor da string qualquer coisa Comentários 8 ignorados (* qualquer coisa *) Reais 9 o valor (-)?inteiror.(inteiro)?(e inteiro)? com inteiro=(dígito)+ Adoptaremos igualmente as convenções seguintes : Os caracteres brancos, tabulações e carrier return não são significativos e podem aparecer em qualquer quantidade, só são consideradas as 8 primeiras letras de cada identificador, uma apostrofe nuam string deve ser duplicada para ser considerada como tal: O Reilly, as strings estão limitadas a 132 caracteres, os comentários terminam ao primeiro *) encontrado e não podem ser aninhados. 1. Defina os autómatos finitos deterministas para cada uma das expressões regulares definidas. Dar, a seguir, o analisador completo. 2. Quais diferenças existem entre o analisador léxico e o reconhecimento realizado por um autómato finito clássico. 3. Determine em que momento intervenham as convenções indicadas. 4. Dar a estruturas geral do analisador léxico. Assuma, para tal a existência dos valores e das funções de base seguintes : init denota o estado inicial ptr variável que indica a posição corrente no buffer string(x, y) onde x t y são índices no buffer. colocada entre estes dois índices. Estas função devolve a string 11
terminal(s) onde s é um estado, indica se o estado é final ou não. type(s) se s é um estado final, devolve o seu tipo. transit(s, c) devolve o estado que segue s pela transição de label c, devolve fail no caso de tal transição não existir. lire() devolve o próximo caracter lido e faz avançar o apontador no buffer. 3 Compilação Exercício 30 Em que fase da compilação podemos detectar cada um dos erros seguintes: 1. Identificador mal formado : 12K3 em C, em OCaml. 2. Conflito de tipo sin( a ). 3. Instrução nunca executada. 4. Variável não declarada. 5. Comentário aberto mas não fechada. 6. Parêntesis não fechada. 7. BEGIN não fechado. 8. Palavra chave utilizada como um identificador. 9. Incoerência entre o número de parâmetro duma definição e o número de parâmetro na chamada dum procedimentos. 10. Tentativa de modificar uma constante. 11. Constante demasiada grande. 12. Ultrapassagem do limite dum vector. Exercício 31 (Correcção de Compiladores) Seja L uma pequena linguagem de expressões aritméticas descrita pela gramática seguinte : 12
Expr ::= Term Expr + Term Expr - Term Term ::= Facteur Term * Facteur Facteur ::= id(n) int(i) ( Expr ) - Facteur Seja L m a linguagem máquina seguinte : LOAD adr,reg carrega o conteúdo da célula adr no registo reg LOADI int,reg carrega a constante int no registo reg STORE reg,adr salva o conteúdo do registo reg na célula de endereço adr ADD reg1,reg2 soma o conteúdo do registo reg1 ao conteúdo do registo reg2 MUL reg1,reg2 multiplica o conteúdo do registo reg1 ao conteúdo do registo reg2 OPP reg muda o sinal do conteúdo do registo reg ADDI int,reg soma a constante int ao conteúdo do registo reg PUSH reg1,reg2 coloca o conteúdo do registo reg1 no registo reg2 1. Formalizar a semântica da linguagem máquina proposta sob a forma duma função de transformação dos registos e da memória. 2. A assinatura (operações de contrução) das árvores de sintaxe abstracta que representam as expressões é a seguinte : type asa expr ident : int -> asa expr cte : int -> asa expr plus, moins, mult : asa expr * asa expr -> asa expr opp : asa expr -> asa expr Assumiremos que os identificadores são representados por um inteiro que corresponde ao endereço máquina da variável em questão. Defina uma função de tradução das árvores de sintaxe abstracta (que representa as expressões) para uma sequência de instruções máquina. Quantos registos são necessários para esta função? 3. Verificar que a tradução preserva a semântica das expressões. Exercício 32 (Fases da compilação) Interessamo-nos aqui às diferentes fases da compilação para o pequeno programa seguinte: 13
program calculo; var T : array[1..10] of integer; S,I : integer; begin S:=0; (* inicializaç~ao *) for I:= 1 to 10 do begin read(t[i]); S := S + T[I] end; writeln(s) end. Assim sendo: 1. forneça a lista das entidades léxicas Dar o início das sequências de tokens (no máximo 25 tokens). Cada tokens está associada a uma classe léxica (poderá por exeplo considerar as classes dadas no exercício 29) e a um valor. Para os identificadores, o valor será o índice da célula da tabela de símbolos onde se encontra arquivada. 2. Propor uma gramática que permita gerar a linguagem à qual este programa pertence. 3. Dar a árvore de derivação sintáctica associada ao programa e a gramática definida no ponto anterior. 4. Propor uma definição de árvore de sintaxe abstracta para a representação dos programas desta linguagem. 5. Dar a árvore de sintaxe abstracta que corresponde as instruções do bloco principal begin..end do programa anterior. 6. Considere a seguinte linguagem intermédia que permite a manipulação de no máximo três endereços. Dê a representação deste programa sob a sua forma intermédia. Mais geralmente defina a função que calcule a tradução duma árvore de sintaxe abstracta para o código intermédio. 14
x y op z x y x cte goto L se x relop y então L x y[i] x[i] y nop x ler escrever x operações lógicas e aritméticas copia carregamento dum valor constante salto incondicional para o label L salto condicional para o label L atribuí a x o valor da célula memória localizada em i unidades a seguir ao endereç atribuí o valor de y a célula localizada i unidades a seguir ao endereço x não faz nada lê um valor e atribuí este valor a x escreve o valor de x Exercício 33 (Linguagem algébrica) Considere a gramática seguinte sobre o alfabeto {0, 1}: N ::= 11 N ::= 1001 N ::= N0 N ::= NN 1. Mostre que todas sequências de bits geradas por esta gramática são inteiros múltiplos de 3. 2. Será que todos múltiplos de três são gerados por esta gramática? Exercício 34 (Gramáticas ambíguas) Considere a gramática das expressões condicionais seguinte: 1 I ::= if E then I 2 I ::= if E then I else I 3 I ::= other 4 E ::= bool 1. Mostre que esta gramática é ambígua. 2. Descreva os passos duma análise ascendente da expressão : if bool then if bool then other else other Em que passo temos a escolha entre uma leitura e uma redução? Quais são as árvores de derivação sintáctica em cada um dos casos? 15
3. Defina uma gramática não ambígua equivalente que associa cada else ao then livre (que ainda não está associado a um else) mais próximo. 4. Que regras de precedências são precisas incluir na gramática inicial para obter o mesmo comportamento? Exercício 35 (Análise sintáctica e derivações) Considere a gramática seguinte: S ::= aab S ::= bss A ::= CC A ::= f C ::= cc C ::= d B ::= bb B ::= e 1. Dê uma derivação direita e esquerda de baccddeafbbe. 2. Escreva os passos da análise descendente da palavra do ponto anterior. construa a tabela de expansão para a gramática. Verifique que a análise descendente permite a reconstrução da derivação esquerda. 3. descreva as etapas de análise ascendente da palavra precedente. Verifique que esta análise permite a reconstrução da derivação direita. Exercício 36 (Análise descendente) Vamos analisar de novo a gramática do exercício 35. 1. Calcule o conjuntos dos primeiros, dos seguintes e dê a tabela de transições do autómato de análise descendente. 2. Nesta gramática, substitua A ::= f por A ::= ɛ. Calcula a seguir a nova tabela de transições e deduza uma derivação esquerda de baccddeabbe. 16
Exercício 37 (Gramática recursiva esquerda) Considera a gramática seguinte: S S L L ::= (L) ::= a ::= L, S ::= S 1. Dê a árvore de derivação sintáctica da expressão: (a, ((a, a), (a, a))) 2. Que linguagem reconhece esta gramática? 3. Será esta gramática uma gramática LL(1)? 4. Elimine a recursividade esquerda na gramática. 5. Construa o analisador descendente correspondente. 6. Dar o funcionamento do analisador sobre a entrada : (((a, a), ((a, a), (a, a)))) Exercício 38 (Análise descendente et ascendente) Considere a gramática seguinte cujo conjunto de símbolos terminais é {(, a, ;, )}, e cujo conjunto de símbolos não-terminais é {S, L, A} e cujo símbolo inicial é S: S ::= (L S ::= a L ::= SA A ::= ;SA A ::= ) 1. Dê as etapas de análise descendente da palavra (a;(a;a)). 2. Dê as etapas de análise ascendente da palavra (a;(a;a)). 3. Deduza uma derivação direita e esquerda desta palavra. 17
Exercício 39 (Análise descendente LL(1), Análise ascendente LR(0) e SLR(1)) Soient les grammaires : 1. S ::= L L ::= L; A A A ::= a 2. S ::= L L ::= A; L A A ::= a 3. S ::= L L ::= L; L A A ::= a 4. S ::= L L ::= at T ::= ɛ ; L 1. Mostre que estas gramáticas geram a mesma linguagem. 2. Diga, para cada uma das gramáticas se é LL(1), LR(0), SLR(1). 3. Compare o tamanho da pilha para a análise ascendente e ascendente da palavra a; a; a para as duas primeiras gramáticas. Que podemos nos dizer sobre esta comparação? Exercício 40 (Gramáticas reduzidas) 1. Define um algoritmo para encontrar todos os símbolos acessíveis e produtivos duma gramática. Este algoritmo deverá assim ser capaz de transformar uma gramática numa gramática reduzida (onde todos os não terminais supérfluos foram removidos) equivalente. 2. Aplica este método a gramática seguinte : S ::= aaa S ::= bbb A ::= be E ::= ɛ B ::= CD C ::= cc D ::= d 18
Exercício 41 (Diferenças entre LL(1) e SLR(1)) Seja a gramática : S ::= AaAb BbBa A ::= ɛ B ::= ɛ Mostre que esta gramática é LL(1) e que não é SLR(1). Exercício 42 (LR(0),SLR(1),LR(1)) Seja a gramática : S ::= E E ::= id E ::= id(e) E ::= E + id Detgermine se a gramática é LR(0), SLR(1), LR(1)? Exercício 43 (Diferenças entre SLR(1) e LALR(1)) Considere a gramática : S ::= X X ::= dc X ::= Ma X ::= bda X ::= bmc M ::= d Determine se a gramática é LR(0), SLR(1) ou LALR(1)? Exercício 44 (Diferenças LL(1)-LALR(1)-LR(1)) Seja a gramática : S ::= (X X ::= F ] S ::= E] E ::= A S ::= F ) F ::= A X ::= E) A ::= ɛ determine se a gramática é LL(1), LR(1), LALR(1)? Exercício 45 (Análise ascendente) Vamos aqui considerar a linguagem dos tipos que permite descrever o tipo dos inteiros e das funções sobre inteiros. Um tipo ou é a constante int ou é da forma τ 1... τ n int em cada τ i é um tipo. Para reconhecer esta linguagem de tipo, consideraremos a gramática com os terminais seguintes {,,, int} e com os não terminais {S, A, T } e o símbolo inicial S: 19
S T T A A ::= T ::= int ::= A int ::= T ::= T A 1. Calcula o conjunto dos seguintes de T e de A. 2. Construa, para esta gramática, a tabela de análise SLR(1), indicando em caso de conflitos as diferentes acções possíveis. Será esta gramática uma gramática SLR(1)? 3. Explique a natureza do conflito obtido dando um exemplo de entrada onde este conflito acontece. A gramática é ambígua? 4. Que sugere para resolver este problema? 20