A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Revisão Compiladores – AP2

Apresentações semelhantes


Apresentação em tema: "Revisão Compiladores – AP2"— Transcrição da apresentação:

1 Revisão Compiladores – AP2
Prof. Alexandre Monteiro Recife

2 Contatos Prof. Guilherme Alexandre Monteiro Reinaldo
Apelido: Alexandre Cordel /gtalk: Site: Celular: (81)

3 Análise de Descida Recursiva
É uma análise sintática top-down ou descendente É um parser LL(1) Left-to-right – a ordem de leitura dos tokens é da esquerda para a direita Leftmost derivation – segue a ordem típica de uma derivação mais à esquerda Só olha 1 token por vez

4 Exemplo de Reconhecedor
Gramática: Terminais = {a,b,c} Não-terminais = {S, X} Produções = { S  a X b S  b X a S  c X  b X X  a } Não-terminal inicial = S a b c S a X b b X a X b X Error

5 Produção Única Um não-terminal com apenas uma produção é o caso mais simples de ser tratado Ficará assim frase ::= sujeito predicado “.” void parseFrase() { parseSujeito(); parsePredicado(); acceptToken(PONTO); }

6 Múltiplas Produções Porém, quando houver mais de uma produção, é preciso usar um critério de escolha Por exemplo: Como escolher a produção certa (ou seja, a que representa o código fonte) durante a análise? sujeito ::= “Eu” | “Um” substantivo | “O” substantivo

7 Múltiplas Produções No exemplo anterior, basta olhar o token atual
void parseSujeito() { TokenType tp = this.token.getType(); if (tp == TokenType.EU) { acceptToken(); } else if (tp == TokenType.UM) { parseSubstantivo(); } else if (tp == TokenType.O) { } else { <.. reportar erro ..> }

8 Conjunto FIRST FIRST(ε) = { ε } FIRST(a) = { a }
Se α for a cadeia vazia (α = ε) FIRST(ε) = { ε } Se for um terminal a qualquer FIRST(a) = { a } Se for um não-terminal N com as produções N → α | β FIRST(N) = FIRST(α)  FIRST(β)

9 Conjunto FIRST Se for uma cadeia de símbolos α = X1X2...Xk
Depende de X1 Se X1 não pode gerar vazio FIRST (X1X2...Xk) = FIRST(X1) Se X1 pode gerar vazio FIRST (X1X2...Xk) = FIRST(X1)  FIRST(X2...Xk) Calcula para X1 e continua o cálculo recursivamente para o restante da cadeia

10 Fatoração à Esquerda Alguns casos em que as produções têm seus conjuntos FIRST idênticos podem ser tratados Um deles é quando as produções têm prefixos comuns Exemplo cmd ::= if exp then cmd else cmd | if exp then cmd | outro

11 Fatoração à Esquerda A solução é parecida com a fatoração em expressões matemáticas Colocar a parte comum em evidência A parte diferente pode se tornar outro não-terminal Exemplo anterior cmd ::= if exp then cmd restoCmd | outro restoCmd ::= else cmd | ε

12 Fatoração à Esquerda Caso geral
Seja N com produções com prefixo comum α Colocando α em comum e criando um novo não-terminal X N → α β1 | α β2 | Ф N → α X | Ф X → β1 | β2

13 Eliminação de Fatoração
Indireta X  a b X  Y c Y  a d Elimina-se a indireção: X  a d c Sem fatoração: X  a Z Z  b Z  d c Direta: X  a b c X  a d e Sem fatoração: X  a Y Y  b c Y  d e

14 Exercícios Resolver fatorações a esquerda: Direta: Indireta: X  a c X
X  a d Indireta: X  a X X  Y c X  d Y  a b

15 Recursão à Esquerda Outra limitação (menos grave) da técnica, é se houver uma produção recursiva à esquerda O que acontece se tentarmos criar o parser diretamente desta gramática? exp ::= exp “+” NUM | NUM

16 Recursão à Esquerda void parseExp() { if (token.getType() == NUM) { parseExp(); acceptToken(MAIS); acceptToken(NUM); } else if (token.getType() == NUM) { acceptToken(); } recursão infiinita ! Qual o problema com esse código? Além dos conjuntos FIRST não serem disjuntos, ele apresenta recursão infinita!

17 Recursão à Esquerda Neste caso, é preciso alterar a gramática para remover a recursão à esquerda É necessário haver outra produção sem a recursão Como reescrever o exemplo anterior para remover a recursão à esquerda? exp ::= exp “+” NUM | NUM

18 Recursão à Esquerda O exemplo anterior reescrito exp ::= NUM restoExpr
restoExpr ::= “+” NUM restoExpr | ε

19 Recursão à Esquerda Caso geral Seja a gramática Comentários N → N α1
A recursão à esquerda serve apenas para produzir repetições de α1 ou α2 (à direita das recursões) A recursão só pára quando o N à esquerda for β1 ou β2 (produções sem recursão à esquerda) N → N α1 | N α2 | β1 | β2 Sejam α1, α2, β1 e β2 cadeias quaisquer

20 Recursão à Esquerda Caso geral (solução)
Criar um novo não-terminal X para criar zero ou mais repetições de α1 ou α2 com recursão à direita Fazer as produções sem recursão de N terminarem com X N → N α1 | N α2 | β1 | β2 N → β1 X | β2 X X → α1 X | α2 X | ε

21 Eliminação da Recursividade Esquerda
Direta: X  X a X  b Sem recursão: X’  ε X’  a X’ X  b X’ Indireta: X  Y a X  b Y  X c Y  d Remove-se a indireção: X  X c a X  d a Resolve-se como no caso anterior

22 Exercícios Resolver recursividades a esquerda: Direta: Indireta:
X  X a X  b Indireta: X  Y a Y  X c Y  d

23 Conjunto FOLLOW FOLLOW (N)
Aplicado a não-terminais N quaisquer É o conjunto de terminais que podem aparecer à direita do não-terminal N, em alguma cadeia derivada pela gramática Se o símbolo inicial deriva uma cadeia “... N x ...” então x faz parte de FOLLOW(A) O símbolo inicial tem $ no conjunto FOLLOW para indicar fim da entrada (EOF) Como calcular?

24 Conjunto FOLLOW Se N for o símbolo inicial
Colocar $ (EOF) no conjunto FOLLOW(N) Para toda produção X → α N β , em que beta não é vazio e não deriva vazio Adicionar tudo de FIRST(β) no FOLLOW(N) Para toda produção X → α N β , em que beta ou é vazio ou deriva vazio Adicionar todo o FOLLOW(X) no FOLLOW(N)

25 Analisador Sintática LR
Existem diversos tipos de analisadores LR(k) O nome LR(k) indica Left-to-right – a ordem de leitura dos tokens é da esquerda para a direita Rigthmost derivation – encontra uma derivação mais à direita (porém, de trás para a frente) K token são olhados à frente (lookahead)

26 Relembrando as Tabelas
Tabela ACTION Diz qual ação será tomada, de acordo com o estado atual e o próximo token Tabela GOTO (usada após um reduce) Diz qual o próximo estado, de acordo com o estado atual e o símbolo não-terminal que foi reduzido

27 Funcionamento SHIFT REDUCE ACCEPT ERROR
A medida que lê os terminais (tokens), o parser poderá realizar certas ações, de acordo com o estado atual SHIFT REDUCE ACCEPT ERROR

28 Exemplo (quadro) 0) S: stmt $ 1) stmt: ID ':=' expr
2) expr: expr '+' ID 3) expr: expr '-' ID 4) expr: ID

29 Exemplo (autômato) State 3 1) stmt: ID ':=' . expr
0) S: stmt $ 1) stmt: . ID ':=' expr State 1 0) S: stmt . $ State 2 1) stmt: ID . ':=' expr State 3 1) stmt: ID ':=' . expr 2) expr: . expr '+' ID 3) expr: . expr '-' ID 4) expr: . ID

30 Exemplo (autômato) 4) expr: . ID GOTO 6 on expr SHIFT 5 on ID State 4
0) S: . stmt $ 1) stmt: . ID ':=' expr GOTO 2 on stmt SHIFT 1 on ID State 1 1) stmt: ID . ':=' expr SHIFT 3 on ':=' State 2 0) S: stmt . $ SHIFT 4 on $ State 3 1) stmt: ID ':=' . expr 2) expr: . expr '+' ID 3) expr: . expr '-' ID 4) expr: . ID GOTO 6 on expr SHIFT 5 on ID State 4 0) S: stmt $. State 5 4) expr: ID . State 6 1) stmt: ID ':=' expr . 2) expr: expr . '+' ID 3) expr: expr . '-' ID SHIFT 7 on '+' SHIFT 8 on '-' State 7 2) expr: expr '+' . ID SHIFT 9 on ID State 8 3) expr: expr '-' . ID SHIFT 10 on ID State 9 2) expr: expr '+' ID . State 10 3) expr: expr '-' ID .

31 Exemplo (Tabelas)

32 Exemplo: a:= b + c - d

33 Análise Semântica O que é? Para que serve?
Qual a finalidade de uma tabela de símbolos (TS) no projeto de um compilador?

34 Tradução em Parsers de Descida Recursiva
...basta posicionar a ação semântica dentro do bloco que trata a produção desejada void parseLoopComand() { if (token.getType() == WHILE) { acceptToken(); System.out.println(“While!"); ... } else if (token.getType() == DO) { parseComand(); System.out.println(“Do-While!"); }

35 Código de Três Endereços
É uma linguagem de baixo nível (simples), porém independente de máquina Programas representados como uma simples lista de instruções As instruções usam, no máximo, três operandos (endereços)

36 Tipos de Endereços Um endereço pode ser:
Um nome – representando uma variável, função, etc. Uma constante – valor literal de um número, uma string, um caractere, etc. Um temporário – variável auxiliar criada pelo compilador (t1, t2, etc.) Um rótulo – localização de uma instrução

37 Tipos de Instruções Instruções de atribuição da forma
Onde op é um operador binário aritmético, binário ou lógico Exemplo: x = y op z aux = t1 + temp

38 Tipos de Instruções Instruções de atribuição da forma
Onde op é um operador unário, como: negação lógica, menos, conversão de tipo Exemplos: x = op y t1 = (int) temp; t1 = - temp;

39 Tipos de Instruções x = y Instruções de cópia
Usadas, em alguns casos, para facilitar a geração do código intermediário Numa fase posterior, de otimização, essa instrução pode ser removida x = y

40 Tipos de Instruções Desvio incondicional
Desvia para o rótulo L : faz com que a próxima instrução a ser executada seja a que tem o rótulo L Exemplo: goto L label2: aux = t + 1; ... goto label2

41 Tipos de Instruções if x goto L ifFalse x goto L Desvios condicionais
Desviam para o rótulo L dependendo do valor booleano de x if x goto L ifFalse x goto L

42 Tipos de Instruções Desvios condicionais com operadores relacionais (<, >, ==, !=, ...) Desvia para L se o resultado da operação relacional for verdadeiro Exemplo: if x op_cond y goto L label2: aux = t + 1; if aux < temp goto label2

43 Traduzindo Expressões
Uma expressão com várias operações... ...é decomposta em expressões menores, com uma operação cada myVar = aux + temp * 3 t1 = 3 t2 = temp * t1 t3 = aux + t2 myVar = t3

44 If-Else Exemplo: int x = 0; x = 0 if (x < 10) { t1 = x < 10
} int y = x; x = 0 t1 = x < 10 ifFalse t1 goto F1 x = 20 goto R1 F1: x = 10 R1: y = x

45 While Exemplo: x = 0; x = 0 while (x < 10) { I1: x = x + 1;
} y = x; x = 0 I1: t1 = x < 10 ifFalse t1 goto R1 t2 = x + 1 x = t2 goto I1 R1: y = x


Carregar ppt "Revisão Compiladores – AP2"

Apresentações semelhantes


Anúncios Google