compiladores claudio benossi [email protected]

98
Compiladores Claudio Benossi [email protected]

Upload: aline-medina-de-lacerda

Post on 07-Apr-2016

300 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Compiladores Claudio Benossi claudio@benossi.com.br

CompiladoresClaudio Benossi

[email protected]

Page 2: Compiladores Claudio Benossi claudio@benossi.com.br

Bibliografia Recomendada

COMPILADORES Princípios, Técnicas e Ferramentas;

Aho, Alfred V.; Lam, Monica S.; Sethi, Ravi; Ullman, Jeffrey D. Pearson, 2007.

Projeto Moderno de Compiladores;

Bal, Henri E.; Grune, Dick; Langendoen, Koen. CAMPUS, 2001.

Modern Compiler Implementation in Java

Andrew W. Appel. Cambridge University Press, 2002.

Introdução A Teoria dos Autômatos, Linguagens e Computação; Hopcroft, John E.; Ullman, Jeffrey D.; Motwani, Rajeev. CAMPUS, 2002.

Page 3: Compiladores Claudio Benossi claudio@benossi.com.br

Introdução

Pré-processador

Analisador Léxico

Analisador Sintático

Analisador Semântico

Gerador de Código(intermediário)

Otimizador

Gerador de Código

front-end

back-end

Page 4: Compiladores Claudio Benossi claudio@benossi.com.br

Introdução

final = (nota1 + nota2) / 2;

Analisador Léxico

Id1 = (Id2 + Id3) / 2

Analisador Sintático

=

Id1 /

+

Id2 Id3

2

Id1 final double ...Id2 nota1 double ...Id3 nota2 double ......

Tabela de Símbolos

Page 5: Compiladores Claudio Benossi claudio@benossi.com.br

Introdução

=

Id1 /

+

Id2 Id3

intToDouble(2)

Id1 final double ...Id2 nota1 double ...Id3 nota2 double ......

Tabela de Símbolos

Analisador Semântico

temp1 = Id2 + Id3

temp2 = temp1 / 2.0

Id1 = temp2

Gerador de Código(intermediário)

Page 6: Compiladores Claudio Benossi claudio@benossi.com.br

Análise Léxica

O Analisador Léxico (scanner) examina o programa fonte caractere por caractere agrupando-os em conjuntos com um significado coletivo (tokens):

• palavras chave (if, else, while, int, etc),• operadores (+, -, *, /, ^, &&, etc),• constantes (1, 1.0, ‘a’, 1.0f, etc),• literais (“Projeto Mono”),• símbolos de pontuação (; , {, }),• labels.

Page 7: Compiladores Claudio Benossi claudio@benossi.com.br

Análise Léxica

constanteInt digito digito*constanteDouble digito digito*. digito*

digito {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

X* Representa uma seqüência de zero ou mais X.

Page 8: Compiladores Claudio Benossi claudio@benossi.com.br

Análise Sintática

Verifica se as frases obedecem as regras sintáticas da linguagem:

Por exemplo, uma expressão pode ser definida como:expressão + expressãoexpressão – expressão(expressão)constante

Page 9: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas

Um conjunto de regras de produção, é um símbolo de partida. Uma regra de produção tem o formato , onde representa a construção sintática e representa uma forma possível dessa construção:

<expressão> <expressão> + <expressão>

Page 10: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas

<expr> <expr> + <expr>| <expr> – <expr>| (<expr>)| <const>

<const> <const><const>| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9

Page 11: Compiladores Claudio Benossi claudio@benossi.com.br

Derivação

A verificar se uma frase faz parte da linguagem gerada pela gramática, envolve sucessivas substituições da cadeia de símbolos que ocorre do lado esquerdo da produção pela sua construção sintática correspondente, partindo do símbolo inicial.Essa substituição é chamada derivação sendo normalmente denotada pelo símbolo .

Page 12: Compiladores Claudio Benossi claudio@benossi.com.br

Derivação

(10 - 2) + 3

<expressão>

<expr> + <expr> (<expr>) + <expr> (<expr> - <expr>) + <expr> (<const> - <expr>) + <expr> (<const><const> - <expr>) + <expr> (1<const> - <expr>) + <expr> (10 - <expr>) + <expr> (10 - <const>) + <expr>...

Page 13: Compiladores Claudio Benossi claudio@benossi.com.br

Árvore Sintática

<expr>

<expr> + <expr>

(<expr>) <const>

<expr> - <expr>

<const> <const>

10 2 3

(10 – 2) + 3

Page 14: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas Ambíguas

10 – 2 + 3

<expr> - <expr>

<expr>

<expr> + <expr>

10 2 3

<expr>

<expr> + <expr>

<expr> - <expr>

10 2 3

Page 15: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas

<expr> <expr> + <termo> | <expr> - <termo>

| <termo><termo> (<expr>)

| <const>

<expr> <expr> + <termo> <expr> - <termo> + <termo> <termo> - <termo> + <termo> 10 – 2 + 3

<expr>

<expr> + <termo>

<expr> - <termo>

10 2 3

Page 16: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas

<expr> <expr> + <termo>

| <expr> - <termo>| <termo>

<termo> <termo> * <fator>

| <termo> / <fator>

| <fator><fator> (<expr>)

| <const>

<expr> + <termo>

<termo> * <fator>

3 2 3

<expr>1 + 2 * 3

Page 17: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas

<expr> <expr> + <termo>

| <expr> - <termo>| <termo>

<termo> <termo> * <fator>

| <termo> / <fator>

| <fator><fator> (<expr>)

| <const>

<termo>

<termo> * <fator>

<expr>1 + 2 * 3

Page 18: Compiladores Claudio Benossi claudio@benossi.com.br

Tradução Dirigida pela Sintaxe

Analisador Sintático

Analisador Léxico

Analisador Semântico

Tabela de Símbolos

...

Programa Fonte

Código Intermediário

Solicita tokentoken

Page 19: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas - Exercícios

1. Considerando a gramática apresentada anteriormente derive as expressões e apresente a árvore sintática correspondente:(1 + 2) * 3 (1 – 2) + 3 * 4

2. Altere a gramática para incluir o operador unário -, esse operador deve ter precedência maior que os outros operadores.

3. Altere a gramática para que os operadores de adição, subtração, multiplicação e divisão tenham associatividade da direita para a esquerda.

4. Defina uma gramática para expressões aritméticas (operadores +, -, *, /) pós fixadas .

Page 20: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas

Dados 2 conjuntos independentes de símbolos:• Vt – Símbolos terminais

• Vn – Símbolos não terminais.

Uma gramática é definida como a quádrupla:{Vn, Vt, S, P}

Onde, S Vn é o símbolo inicial da gramática.

P é um conjunto de regras de reescrita na forma: , sendo: (Vn Vt)* Vn (Vn Vt)*

(Vn Vt)*

Page 21: Compiladores Claudio Benossi claudio@benossi.com.br

Classificação de Gramáticas

• Irrestritas – nenhuma restrição é imposta

• Sensíveis ao Contexto - || ||

• Livres de Contexto - Vn

(Vn Vt)+

• Regulares - Vn

tem a forma a ou aB, ondea Vt e B Vn

Page 22: Compiladores Claudio Benossi claudio@benossi.com.br

Gramáticas Regulares

C 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 0C | 1C | 2C | 3C | 4C | 5C | 7C | 8C | 9C

C CC | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 C digito digito*

digito 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Page 23: Compiladores Claudio Benossi claudio@benossi.com.br

Especificação

• Análise Léxica – expressões regulares

• Análise Sintática – gramáticas livres de contexto.

• Análise Semântica – sistema de tipos (regras de inferência), semântica denotacional, semântica operacional, semântica de ações.

• Geração/Otimização de Código – linguagens para descrição de arquiteturas.

Page 24: Compiladores Claudio Benossi claudio@benossi.com.br

Linguagens Regulares

• Gerada a partir de uma gramática regular.• Pode ser representada através de uma expressão

regular.• Pode ser reconhecida por um Autômato Finito.• Considerando linguagens compostas por

símbolos 0 e 1 podemos afirmar:a linguagem L01 ={0n1n| n 1} não é regular; a linguagem L01 ={0n1m | n 1, m 1} é regular;

Page 25: Compiladores Claudio Benossi claudio@benossi.com.br

Expressões Regulares

Maneira compacta de representar linguagens regulares. É composta de 3 operações, sendo e1 e e2 expressões geradas por duas linguagens regulares L1 e L2 respectivamente

• Concatenação: e1e2 = { xy | x L1 e y L2}

• Alternação: e1|e2 = { x | x L1 ou x L2}

• Fechamento: e1* = zero ou mais ocorrências de

e1.

É definida a precedência desses operadores como sendo: fechamento, concatenação, alternação (da maior precedência para a menor).

Page 26: Compiladores Claudio Benossi claudio@benossi.com.br

Expressões Regulares

Exemplos:

identificador (letra | _) (letra | digito | _)*letra a | b | ... | A | B | ...digito 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9constInt digito digito*constDouble digito digito*.digito* | . digito digito*

Page 27: Compiladores Claudio Benossi claudio@benossi.com.br

Autômato Finito

A linguagem gerada por uma gramática regular pode ser reconhecida por um autômato finito. Um autômato finito consiste em:

1. Um conjunto finito de estados.

2. Um conjunto finito de símbolos de entrada (alfabeto).

3. Uma função de transição que tem como argumentos um estado e um símbolo de entrada e retorna a um estado.

4. Um estado inicial.

5. Um conjunto de estados finais também chamados estados de aceitação.

Page 28: Compiladores Claudio Benossi claudio@benossi.com.br

Autômato Finito

letra | digito | _

letra | _

letra | digito | _

letra | _

.

.

digitodigito

digito digito

Page 29: Compiladores Claudio Benossi claudio@benossi.com.br

Autômato Finito

letra | digito | _

letra | _

f

o r

letra | digito | _

letra | _

fo r

ldld

ld

Onde ld representa letra | digito | _ (com exceção da letra que faz a transição para outro estado).

AFD – Autômato Finito Determinista

AFN – Autômato Finito Não Determinista

Page 30: Compiladores Claudio Benossi claudio@benossi.com.br

Autômato Finito Implementação

letra | digito | _

letra | _

digito

digito

0 1

2

Page 31: Compiladores Claudio Benossi claudio@benossi.com.br

Geradores de Analisadores Léxicos

delim [ \t]ws {delim}+letra [A-Za-z]digito [0-9]id {letra}({letra}|{digito})*int {digito}+real {digito}+\.{digito}*(E[+-]?{digito}+)?char '{letra}'string '({letra}|{digito}|[ \t\\:])*'%%{char} {yylval.ptr=insereTab(&TabSimb[0], yytext);return TCCHARACTER;}{string} {yylval.ptr=insereTab(&TabSimb[0], yytext);return TCSTRING;}\n {num_linhas++;}FUNCTION {return TFUNCTION;}INTEGER {return TINTEGER;}ARRAY {return TARRAY;}IF {return TIF;}{id} {yylval.ptr=instalar(yytext); return TID;}"<" {return TMENOR;}

Page 32: Compiladores Claudio Benossi claudio@benossi.com.br

Análise Léxica - Exercícios

1. Escreva uma gramática, expressão regular e AFD que defina os números binários terminados em zero.

2. Mostre uma expressão regular e o AFD correspondente a gramática abaixo:S aS B bC C aC | aB | a

3. Escreva uma expressão regular para as constantes double da linguagem C.

Dica pode-se usar o símbolo para indicar uma “cadeia” vazia.

Page 33: Compiladores Claudio Benossi claudio@benossi.com.br

Analisador Sintático

Obtém uma seqüência de tokens fornecida pelo analisador léxico e verifica se a mesma pode ser gerada pela gramática.

Os métodos de análise sintática comumente usados em compiladores são classificados como:

• Métodos top-down.

• Métodos bottom-up.

Os métodos eficientes, tanto top-down quanto bottom-up, trabalham com uma subclasse de gramáticas livres de contexto.

Page 34: Compiladores Claudio Benossi claudio@benossi.com.br

Métodos top-down

Podem ser vistos como a tentativa de encontrar a derivação mais a esquerda para uma cadeia de entrada. Partindo do símbolo inicial da gramática são aplicadas sucessivas derivações tentado produzir a cadeia que se deseja reconhecer.

Exemplos:

• Método descendente recursivo.

• Método LL(1).

Page 35: Compiladores Claudio Benossi claudio@benossi.com.br

Método Descendente Recursivo

<expr> + <expr> <expr>

| - <expr> <expr>

<expr> <const>

<const> 0 | 1| 2 | 3| 4 | 5 | 6 | 7 | 8| 9

Page 36: Compiladores Claudio Benossi claudio@benossi.com.br

Método Descendente Recursivo

void cons(){

if (isdigit(lookahead))nextToken();

elseerro("Erro sintático");

}void expr (){

if (lookahead == '+' || lookahead == '-'){

nextToken(); expr(); expr();}else

cons();}

Page 37: Compiladores Claudio Benossi claudio@benossi.com.br

Analisadores Sintáticos Preditivos

Escrevendo a gramática de forma cuidadosa podemos obter uma gramática processável por um analisador sintático que não necessite de retrocesso. Dado um símbolo de entrada a e um não terminal A a a ser expandido, a gramática deve possuir uma única produção que leve ao reconhecimento da cadeia iniciada com a.

Analisadores sintáticos não preditivos (ou não deterministas) necessitam de retrocesso e em geral são ineficientes.

Page 38: Compiladores Claudio Benossi claudio@benossi.com.br

Fatoração a Esquerda

As vezes é necessário fazer alterações na gramática que possibilitem a implementação de um reconhecedor preditivo:

<cmd> if <expr> then <cmd> else <cmd>

| if <expr> then <cmd>

<cmd> if <expr> then <cmd><cmd’>

<cmd’> else <cmd>

|

Page 39: Compiladores Claudio Benossi claudio@benossi.com.br

Fatoração a Esquerda

A 1 | 2 | ... | n | 1 | 2 | ... | n

A A’ | 1 | 2| ... | n

A’ 1 | 2 | ... | n

Page 40: Compiladores Claudio Benossi claudio@benossi.com.br

Eliminação da Recursividade a Esquerda

E E + T

| E - T

| T

T c

| (E)

E

E – T

E + T – T

T + T – T

* c + c - c

Page 41: Compiladores Claudio Benossi claudio@benossi.com.br

Eliminação da Recursividade a Esquerda

E E + T| E - T| T

T c| (E)

A A1 | A2 | ... | 1 | 2 | ... | m

A 1A’ | 2A’ | ... | mA’

A’ 1A’ | 2A’ | ... |nA’ | E TE’E’ +TE’

| -TE’|

T c| (E)

Page 42: Compiladores Claudio Benossi claudio@benossi.com.br

Análise Sintática Preditiva não Recursiva LL(1)

E TE’E’ +TE’

| T FT’T’ * FT’

| F c

| (E)

NãoTerminal c + * ( ) #E TE’ TE’

E’ +TE’ T FT’ FT’

T’ * FT’ F c (E)

E TE’ FT’E’ cT’E’ cE’ c+TE’ c+FT’E’

c+cT’E’ c+c*FT’E’ c+c*cT’E’ c+c*cE’ c+c*c

Page 43: Compiladores Claudio Benossi claudio@benossi.com.br

Analisador Sintático LL(1)

Considerando w a cadeia de entrada. Empilhar #, Empilhar o símbolo inicial da gramática.Faça p apontar para o primeiro símbolo de w#Repetir

Seja X o símbolo no topo da pilha e a o símbolo apontado por p;Se X for um terminal ou # então

Se X = a então Remover X da pilha e avançar p;

Senão erro.Senão /* X não é um terminal */

Se M[X, a] = X Y1Y2...Yk entãoRemover X da PilhaEmpilhar Yk...Y2Y1

Senãoerro

Até que X = #

Page 44: Compiladores Claudio Benossi claudio@benossi.com.br

Analisador Sintático LL(1)

Uma gramática cuja tabela não possui entradas multiplamente definidas é dita LL(1). O primeiro L indica a varredura da cadeia de entrada, que e feita da esquerda para a direita (left to right) o segundo L indica que são aplicadas derivações mais a esquerda (left linear). O número 1 indica que é necessário apenas um símbolo para decidir qual produção aplicar (1 lookahead).

Page 45: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela LL(1)

A construção de um analisador sintático preditivo e auxiliada por duas funções associadas a gramática: PRIMEIROS e SEGUINTES (FIRSTS e FOLLOWS)

Seja uma cadeia qualquer de símbolos gramaticais, PRIMEIROS() representa o conjunto de símbolos terminais que começam as cadeias derivadas a partir de . Se * então também é um elemento de PRIMEIROS().

E E + TE TT T * FT FF (E)F c

PRIMEIROS(E)

E T F (E)

E T F c

= { (, c}

Page 46: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela LL(1)

SEGUINTES(A), para um não terminal A, é o conjunto de terminais a tais que existe uma derivação S * Aa, para algum e , onde S é o símbolo inicial da gramática. Ou seja o conjunto de símbolos que podem ocorrer após o não terminal A em alguma forma sentencial da gramática.

E E + TE TT T * FT FF (E)F c

E E + T T + T F + T

E E + T E + T E + F #

SEGUINTES(F)

E T T * F F * F

E T F (E) (E + T) (E + F)

= { +, #, *, ) }

Page 47: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela LL(1)

Entrada: Gramática

Saída: Tabela M

Para cada produção A da gramática faça:

• Para cada terminal a em PRIMEIROS(), adicione A em M[A, a].

• Se estiver em PRIMEIROS(), adicione A em M[A, b], para cada terminal b em SEGUINTES(A).

Cada entrada indefinida em M indica uma situação de erro.

Page 48: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela LL(1)E TE’E’ +TE’

| T FT’T’ * FT’

| F c

| (E)

PRIMEIROS (TE’) = {c, ( }PRIMEIROS (+TE’) = {+ }SEGUINTES (E’) = { ), # }PRIMEIROS (FT’) = {c, ( }PRIMEIROS (*FT’) = { * }SEGUINTES (T’) = { +, ), # }PRIMEIROS (c) = {c} PRIMEIROS(E) = { ( }

NãoTerminal c + * ( ) #E TE’ TE’E’ +TE’

T FT’ FT’T’ * FT’

F c (E)

Page 49: Compiladores Claudio Benossi claudio@benossi.com.br

Métodos bottom-up

Podem ser vistos como a tentativa de se reduzir a cadeia de entrada ao símbolo inicia da gramática.

Exemplos:

• Precedência de Operadores;

• SLR(1), LR(1), LALR(1)

Page 50: Compiladores Claudio Benossi claudio@benossi.com.br

Métodos LR(k)

Os métodos de análise sintática LR executam uma derivação mais a direita ao contrário. O L significa que a varredura da entrada e feita a esquerda para a direita (left to right), o R que a derivação correspondente é a derivação mais a direita (rightmost derivation) e o k indica o número de símbolos de entrada que tem que ser examinados para se tomar uma decisão na análise sintática.

Nós métodos SLR e LALR mudam apenas as técnicas usadas para construir a tabela sintática.

Page 51: Compiladores Claudio Benossi claudio@benossi.com.br

Métodos LR

c + * ( ) # E T F0 5 4 1 2 31 6 AC2 R2 7 R2 R23 R4 R4 R4 R44 5 4 8 2 35 R6 R6 R6 R66 5 4 9 37 5 4 108 6 119 R1 7 R1 R110 R3 R3 R3 R311 R5 R5 R5 R5

Estado AÇÃO DESVIO

(1) E E + T(2) E T(3) T T * F(4) T F(5) F (E)(6) F c

Page 52: Compiladores Claudio Benossi claudio@benossi.com.br

Algoritmo LR(1)

Considerando w a cadeia de entrada. Empilhar 0. /* Estado inicial */Faça p apontar para o primeiro símbolo de w#Repetir para sempre

Seja s o estado no topo da Pilha e a o símbolo apontado por pSe AÇÃO[s, a] = empilhar s’ então

Empilhar a; Empilhar s’;Avançar p;

SenãoSe AÇÂO[s, a] = reduzir A então

Desempilhar 2 * || símbolos;Seja s’ o estado no topo da pilhaEmpilhar A; Empilhar DESVIO[s’, A];

Senão Se AÇÃO[s, a] = aceitar então Retornar;Senão erro

fim

Page 53: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0Entrada: c + c #

Page 54: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 c 5Entrada: c + c #

Page 55: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 F 3Entrada: c + c #

Page 56: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 T 2Entrada: c + c #

Page 57: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 E 1Entrada: c + c #

Page 58: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 E 1 + 6Entrada: c + c #

Page 59: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 E 1 + 6 c 5Entrada: c + c #

Page 60: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 E 1 + 6 F 3Entrada: c + c #

Page 61: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 E 1 + 6 T 9Entrada: c + c #

Page 62: Compiladores Claudio Benossi claudio@benossi.com.br

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Pilha : 0 E 1Entrada: c + c #

Page 63: Compiladores Claudio Benossi claudio@benossi.com.br

Tabelas SLR(1)

Um item LR(0), para uma gramática G, é uma produção de G com um ponto em alguma das posições do seu lado direito.Exemplo: A produção E E + T produz 4 itens:[E .E + T][E E .+ T][E E +.T][E E + T.]

Intuitivamente o . indica até que parte da produção foi analisada em um determinado estado do analisador sintático.

Page 64: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

A construção da tabela sintática é auxiliada por duas operações:

Fechamento: Sendo I um conjunto de itens da gramática, o fechamento de I é definido por duas regras:

1. Inicialmente cada item de I é adicionado em FECHAMENTO(I).2. Se [A .B] estiver em FECHAMENTO(I) e B for uma produção,

adicionar o item [B .] a FECHAMENTO(I). Essa regra é aplicada até que nenhum novo item possa ser adicionado.

Desvio:

A operação DESVIO(I, X) é definida como o fechamento do conjunto de todos os itens [A X.] tais que [A .X] esteja em I.

Page 65: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

Construção de um conjunto de itens LR(0):

C FECHAMENTO(S’ .S#) /* Onde S é o símbolo inicial da linguagem */Repetir

Para cada conjunto de itens I em C e cada símbolo gramatical X tal que DESVIO(I,X) não seja vazio e não esteja em C

Incluir Desvio(I,X) em CAté que não haja mais conjunto de itens a serem incluídos em C

Page 66: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

Construção da tabela sintática SLR(1):

1. Construir o conjunto de itens C = {I0, I1,..., In} 2. Cada estado i é construído a partir de Ii. As ações sintáticas são

determinadas como:

• Se [A .a] estiver em Ii e DESVIO(Ii, a) = Ij então ação[i, a] = Empilhar j(se a for um terminal) ou desvio[i, a] = Empilhar j (se a for um não terminal)

• Se [A .] estiver em Ii então ação(i, a) = reduzir através de A , para todo a em SEGUINTE(A).

• Se [S’ S.#] estiver em Ii então ação(i, #) = aceitar

Page 67: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

I0

S .E#E .E + TE .TT .T * FT .FF .(E)F .c

I1 Desvio(0,E)S E.#E E. + T

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I4 Desvio(0,()F (.E)E .E + TE .TT .T * FT .FF .(E)F .c

I5 Desvio(0,c)F c.

I6 Desvio(1,+)E E +.TT .T * FT .FF .(E)F .c

I7 Desvio(2,*)T T * .FF .(E)F .c

I8 Desvio(4,E)F (E.)E E.+ T

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

E

T

F

(c

+

*

E

T

F

)

FI3

I4

I5

c

(

(

cc(

I6+

*

Page 68: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

I5 Desvio(0,c)F c.

I2 Desvio(0, T)E T.T T.* F

I3 Desvio(0,F)T F.

I9 Desvio(6,T)E E +T.T T. * F

I10 Desvio(7,F)T T * F.

I11 Desvio(8, ))F (E).

SEGUINTE(F) = { +, *, ), # }

SEGUINTE(E) = { +, ), # }

SEGUINTE(T) = { +, *, ), # }

SEGUINTE(E) = { +, ), # }

SEGUINTE(F) = { +, *, ), # }

SEGUINTE(F) = { +, *, ), # }

Se [A .] estiver em Ii então ação(i, a) = redução através de A , para todo a em SEGUINTE(A).

Page 69: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

No método SLR(1), como a decisão de reduzir, aplicando uma produção A , é tomada usando o conjunto SEGUINTE(A) e não o contexto onde ocorreu algumas gramáticas LR(1) podem apresentar conflitos empilhar/reduzir se tentamos construir tabelas usando o método SLR(1). Por o exemplo:

S L = RS RL *RL id R L

Podemos pensar em L e R como o l-value e o r-value, respectivamente.

Page 70: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

I0

S’ .S#S .L = RS .RL .*RL .id R .L

I1 Desvio (0,S)S’ S.#

I2 Desvio (0,L)S L. = RR L.

I3 Desvio (0,R)S R.

I4 Desvio (0,*)L *.RR .LL .*RL .id

I5 Desvio (0,id)L id.

I6 Desvio (2,=)S L=.RR .LL .*RL .id

I7 Desvio (4,R)L *R.

I8 Desvio (4,L)R L.

I9 Desvio (6,L)S L=R.

S

L

R

*

id

=

R

L

R

* id

*

L

id

Page 71: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática SLR(1)

SEGUINTE(R) = {=, # }

I2 Desvio (0,L)S L. = RR L.

No estado 2, a ação reduzir R L deve ser executada para todos os seguintes de R, o que nesse caso ocasiona um conflito empilhar/reduzir. Entretanto não existe forma sentencial da gramática que inicie com R =. Para tratar essa gramática é necessário um método que carregue mais informação sobre o contexto para o estado.

Page 72: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática LR(1)

Fechamento(I):Repetir

Para cada item [A .B, a] em I, cada produção B na Gramáticae cada termina b em PRIMEIRO(a) tal que [B ., b] não esta em IFaça Incluir [B ., b] em I

até que não seja mais possível adicionar itens a I.

Desvio(I, X): é fechamento do conjunto de itens [A X., a] tais que [A .X, a] esta em I.

Itens(G’):C = {FECHAMENTO({[S’.S#, ]})} (Onde S é o símbolo inicial da gramática)Repetir

Para cada conjunto de itens I em C e cada símbolo gramatical X tal que Desvio(I, X) e Desvio(I, X) CFaça Incluir Desvio(I, X) em C

até que nenhum novo item possa ser adicionado a C

Page 73: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática LR(1)

I0

[S’ .S#, ][S .L = R,#][S .R,#][L .*R,=,#][L .id,=,#] [R .L,#]

I1 Desvio (0,S)[S’ S.#, ]

I2 Desvio (0,L)[S L. = R,#][R L.,#]

I3 Desvio (0,R)[S R.,#]

I4 Desvio (0,*)[L *.R,=,#] [R .L,=,#][L .*R,=,#][L .id,=,#]

I5 Desvio (0,id)[L id.,=,#]

I6 Desvio (2,=)[S L=.R,#][R .L,#][L .*R,#][L .id,#]

I7 Desvio (4,R)[L *R.,=,#]

I8 Desvio (4,L)[R L.,=,#]

I9 Desvio (6,L)[S L=R.,#]

S

L

R

*

id

=

R

L

R

*id

*

L

id

I12 Desvio (6,id)[L id.,#]

I11 Desvio (6,*)[L *.R,#] [R .L,#][L .*R,#][L .id,#]

I10 Desvio (6,L)[R L.,#]

*

I7 Desvio (11,R)[L *R.,#]

R

Page 74: Compiladores Claudio Benossi claudio@benossi.com.br

LALR – lookahead LR

A idéia geral é construir o conjunto de itens os conjuntos de itens LR(1) e, se nenhum conflito aparecer, combinar os itens com núcleo comum.

Algoritmos eficientes para a geração de tabelas LALR constroem o conjunto de itens LR(0) e numa segunda etapa determina os lookahead correspondentes a cada item.

O método LALR:• Trata a maioria dos casos presentes em linguagens de programação;• Na grande maioria dos casos o número de estados é muito inferior ao

número de estado gerados pelo método LR(1).• Comparando com o método LR(1), em algumas situações a detecção de

erro e postergada, reduções desnecessárias são aplicadas antes que o erro seja detectado.

Page 75: Compiladores Claudio Benossi claudio@benossi.com.br

Construção da Tabela Sintática LALR(1)

I0

[S’ .S#, ][S .L = R,#][S .R,#][L .*R,=,#][L .id,=,#] [R .L,#]

I1 Desvio (0,S)[S’ S.#, ]

I2 Desvio (0,L)[S L. = R,#][R L.,#]

I3 Desvio (0,R)[S R.,#]

I4 Desvio (0,*)[L *.R,=,#] [R .L,=,#][L .*R,=,#][L .id,=,#]

I5 Desvio (0,id)[L id.,=,#]

I6 Desvio (2,=)[S L=.R,#][R .L,#][L .*R,#][L .id,#]

I7 Desvio (4,R)[L *R.,=,#]

I8 Desvio (4,L)[R L.,=,#]

I9 Desvio (6,L)[S L=R.,#]

S

L

R

*

id

=

R

L

R

*id

*

id

L

Page 76: Compiladores Claudio Benossi claudio@benossi.com.br

Hierarquia de Gramáticas Livres de Contexto

GramáticasAmbíguas

Gramáticas não ambíguas

LR(k)

LR(1)LALR(1)

SLR

LL(k)

LL(1)

Page 77: Compiladores Claudio Benossi claudio@benossi.com.br

Uso de Gramáticas Ambíguas

<cmd_If> if (<expr>) <cmd> else <cmd>

| if (<expr>) <cmd>

<cmd> ... | <cmd> | ...

<cmd_If>

if (<expr>) <cmd>

if (<expr>) <cmd> else <cmd>

if (a > 0) if (a > b) m = a else m = b if (a < 0) if (a > b) m = a else m = b

<cmd_If>

if (<expr>) <cmd> else <cmd>

if (<expr>) <cmd>

A gramática é ambígua, no estado onde existe a transição para o token “else” ocorre um conflito empilhar/reduzir. A maioria dos geradores nesses casos “opta” por empilhar (que corresponde a primeira árvore).

Page 78: Compiladores Claudio Benossi claudio@benossi.com.br

Lexdelim [ \t]ws {delim}+digito [0-9]num {digito}+(\.{digito}*(E[+-]?{digito}+)?)?

%%{ws} {}"+" {return TADD;}"-" {return TSUB;}"*" {return TMUL;}"/" {return TDIV;}"(" {return TAPAR;}")" {return TFPAR;}\n {return TFIM;}{num} {yylval=atof(yytext); return TNUM;}

Page 79: Compiladores Claudio Benossi claudio@benossi.com.br

yacc%{#include <stdio.h>#include <stdlib.h>#define YYSTYPE double%}

%token TADD TMUL TSUB TDIV TAPAR TFPAR TNUM TFIM

%%

Page 80: Compiladores Claudio Benossi claudio@benossi.com.br

yaccLinha :Expr TFIM {printf("Resultado:%lf\n", $1);exit(0);}

; Expr: Expr TADD Termo {$$ = $1 + $3;}

| Expr TSUB Termo {$$ = $1 - $3;}| Termo;

Termo: Termo TMUL Fator {$$ = $1 * $3;}| Termo TDIV Fator {$$ = $1 / $3;}| Fator;

Fator: TNUM | TAPAR Expr TFPAR {$$ = $2;};

%%

Page 81: Compiladores Claudio Benossi claudio@benossi.com.br

yacc

int yyerror (char *str){

printf("%s - antes %s\n", str, yytext);

}

int yywrap(){

return 1;}

Page 82: Compiladores Claudio Benossi claudio@benossi.com.br

Programa#include <stdio.h>

extern FILE *yyin;

int main(){

yyin = stdin;printf("Digite uma expressão:");yyparse();return 0;

}

Page 83: Compiladores Claudio Benossi claudio@benossi.com.br

Definição Dirigida pela Sintaxe

Gramática livre de contexto na qual cada símbolo possui um conjunto associado de atributos. A cada produção pode estar associada um conjunto de regras semânticas, que podem alterar valores de atributos, emitir código, atualizar a tabela de símbolos, emitir mensagens de erro ou realizar quaisquer outras atividades. Em geradores de analisadores sintáticos estas regras são geralmente descritas em linguagem de programação.

Os atributos são classificados como:

• Atributos Sintetizados: O valor do atributo de um nó é computado a partir dos atributos de seus filhos.

• Atributos Herdados: O valor do atributo de um nó é computado a partir dos atributos dos irmãos e pais do nó.

Page 84: Compiladores Claudio Benossi claudio@benossi.com.br

Definição Dirigida pela Sintaxe

Produção Regra Semântica

S EE E1 + T

E TT T1 * F

T FF (E)F const

{Imprimir (E.val)} {E.val = E1.val + T.val}

{E.val = T.val}{T.val = T1.val * F.val}

{T.val = F.val} {F.val = E.val}{F.val = const.lexval}

E.val = 1 + T.val = 6

T.val = 1 T.val = 2 * F.val = 3

F.val = 1 F.val = 2 const.lexval

const.lexval const.lexval

1 + 2 * 3

S

E.val = 7

Page 85: Compiladores Claudio Benossi claudio@benossi.com.br

Árvores Sintáticas

E E1 + T {E.ptr = criarNo (‘+’, E1.ptr, T.ptr)}

E T {E.ptr = T.ptr}T T1 * F {T.ptr = criarNo (‘*’, T1.ptr, F.ptr)}

T F {T.ptr = F.ptr}F (E) {F.ptr = E.ptr}F const {F.ptr = criarFolha(const.lexval)}

1 2 3

*

+

Page 86: Compiladores Claudio Benossi claudio@benossi.com.br

DAG Grafo Direcionado Acíclico

Identifica as subexpressões comuns.Exemplo: DAG que representa a expressão a * b + c + a *b.

a b c

*

+

+

Page 87: Compiladores Claudio Benossi claudio@benossi.com.br

Código de 3 endereços

Uma seqüência de enunciados na forma:x = y op zOnde x, y e z são nomes, constantes ou dados temporários (criados pelo compilador) e op representa uma operação qualquer.São uma versão linearizada da árvore sintática, é assim chamado por cada instrução poder conter até três endereços, dois para os operandos e um para o resultado. Bastante semelhante a linguagem de montagem.

Page 88: Compiladores Claudio Benossi claudio@benossi.com.br

Código de 3 endereços

Exemplo: a = 2 * b + ct1 = 2 * bt2 = t1 + ca = t2

Page 89: Compiladores Claudio Benossi claudio@benossi.com.br

Código de 3 endereços

S id = E {S.cod = E.cod ++ gerar(id.lexval = E.local)}E E1 + T {E.local = novoTemporario();

E.cod = E1.cod ++T.cod ++ gerar(E.local = E1.local + T.local)}

E T {E.local = T.local; E.cod = T.cod}T T1 * F {T.local = novoTemporario();

T.cod = T1.cod ++ F.cod ++ gerar(T.local = T1.local * F.local)}

T F {T.local = F.local; T.cod = F.cod}F (E) {F.local = E.local; F.cod = E.cod}F id {F.local = id.lexval; F.cod =“”}F const {F.local = const.lexval; F.cod =“”}

Page 90: Compiladores Claudio Benossi claudio@benossi.com.br

Código de 3 endereços

Alguns enunciados comumente usados:

• x = y op z, onde op é uma operação binária.

• x = op y, onde op é uma operação unária.

• x = y, enunciado de cópia.

• goto L, desvio incondicional.

• if x relop y goto L, onde relop é um operador relacional.

• param x, passagem de parâmetro para funções/procedimentos.

• call p, chamada de uma função/procedimento.

• x = a[i] ou a[i] = x, atribuições indexadas.

• *x = y ou x = *y, indireções.

Page 91: Compiladores Claudio Benossi claudio@benossi.com.br

Código de 3 endereços

n = 1;f = 1;while (n < 10){

f = f * n;n = n + 1;

}

n = 1

f = 1

L1: if n < 10 goto L2 goto L3

L2: f = f * n

n = n + 1

goto L1:

L3:

Page 92: Compiladores Claudio Benossi claudio@benossi.com.br

Definições S-atribuídas

Definições dirigidas pela sintaxe que possuem apenas atributos sintetizados.

Produção Regra Semântica

S EE E1 + T

E TT T1 * F

T FF (E)F const

{Imprimir (E.val)} {E.val = E1.val + T.val}

{E.val = T.val}{T.val = T1.val * F.val}

{T.val = F.val} {F.val = E.val}{F.val = const.lexval}

E.val = 1 + T.val = 6

T.val = 1 T.val = 2 * F.val = 3

F.val = 1 F.val = 2 const.lexval

const.lexval const.lexval

1 + 2 * 3

S

E.val = 7

Page 93: Compiladores Claudio Benossi claudio@benossi.com.br

Definições L-atribuídas

Uma definição dirigida pela sintaxe é L-atribuída se cada atributo herdado de Xj, 1 j n, do lado direito de uma produçãoA X1X2...Xn depende somente:

1.Dos atributos dos símbolos X1X2...Xj-1

(símbolos a esquerda de Xj).

2.Dos atributos herdados de A.

Page 94: Compiladores Claudio Benossi claudio@benossi.com.br

Tradução Top-DownS E {imprimir (E.val)}E T {E’.h = T.val} E’ {E.val = E’.s}E’ +T {E’1.h = E’.h + T.val} E1 {E’.s = E’1.s}

E’ {E’.s = E’.h}T F {T’.h = F.val} T’ {T.val = T’.s}T’ * F{T’1.h = T’.h * F.val} T’ {T’.s = T1’.s}

T’ {T’.s = T’.h}F const {F.val = const.lexval}F ({empilha(T’.h); empilha(E’.h)} E {E’.h = desempilha(); T’.h = desempilha()})

Page 95: Compiladores Claudio Benossi claudio@benossi.com.br

Análise SemânticaD var SS id L {atribuirTipo(id.lexval, L.tipo)}S S id L {atribuirTipo(id.lexval, L.tipo)}L , id L1 {atribuirTipo(id.lexval, L.tipo); L.tipo = L1.tipo}

L :T {L.tipo = T.tipo}T integer {T.tipo = integer}T string {T.tipo = string}

Page 96: Compiladores Claudio Benossi claudio@benossi.com.br

Análise SemânticaE E1 + T {if (E1.tipo = T.tipo) then E.tipo = E1.tipo else error()}

E T {E.tipo = T.tipo}T T1 * F {if (T1.tipo = F.tipo) then T.tipo = T1.tipo else error()}

T F {T.tipo = F.tipo}F id {F.tipo = consultaTipo(id.lexval);}F constInt {F.tipo = Inteiro}F constReal {F.tipo = Real}

Obs: Em uma situação real as regras semânticas devem implementar a coerção dos tipos.

Page 97: Compiladores Claudio Benossi claudio@benossi.com.br

Expressões Lógicas e Relacionais B B1 or M C {corrigir(B1.listaf, M.label);

B.listav = merge(B1.listav, C.listav); B.listaf = C.listaf;}

B B1 and M C {corrigir(B1.listav, M.label); B.listaf = merge(B1.listaf, T.listaf);

B.listav = C.listav;}B C {B.listav = C.listav; B.listaf = C.listaf;}C not C1 {C.listav = C1.listaf; C.listaf = C1.listav;}C (B) {C.listav = B.listav; C.listaf = B.listaf;}C E1 rel E2 {C.listav = criaLista(proxInst);

C.listf = criaLista(proxInst+1);} gerar(if E1.local rel E2.local goto _);

gerar (goto _);M {M.label = novolabel()}

Page 98: Compiladores Claudio Benossi claudio@benossi.com.br

Comandos de Seleção e Repetição

S if (B) then M S {corrigir (B.listav, M.label); corrigir(B.listaf, novolabel();}

S if (B) then M1 S N else M2 S

{corrigir(B.listav, M1.label);

corrigir(B.listf, M2.label);}

S while M1 (B) M2 S

{corrigir(B.listav, M2.label);

gerar(goto M1.label);

corrigir(B.listaf, novolabel();}