Você está na página 1de 106

Compiladores

Cristiano Damiani Vasconcellos


damiani@joinville.udesc.br

Bibliografia Recomendada
COMPILADORES Princpios, Tcnicas 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 Appel, Andrew W. Appel. Cambridge University Press, 2002.

Computer Systems: A Programmer's Perspective. Bryant, Randal E.; O'Hallaron; David R..

Introduo (Construo de um Executvel)


prog.c Pr-processador (cpp) prog.i Compilador (cc1) prog.as Montador (as) prog.o Edito de Ligao (ld) prog (executvel) biblioteca.lib outro.o

Introduo (Fases de um Compilador)


Analisador Lxico Analisador Sinttico Analisador Semntico Gerador de Cdigo
(intermedirio)

front-end

Otimizador

back-end
Gerador de Cdigo

Introduo
final = (nota1 + nota2) / 2; Analisador Lxico Id1 = (Id2 + Id3) / 2 Analisador Sinttico = Id1 + Id2 Id3 / 2

Tabela de Smbolos Id1 Id2 Id3 ... final nota1 nota2 double double double ... ... ...

Introduo
Analisador Semntico = Id1 + Id2 Id3 / intToDouble(2)

Gerador de Cdigo (intermedirio)

Tabela de Smbolos Id1 final nota1 nota2 double double double ... ... ... Id2 Id3 ...

temp1 = Id2 + Id3 temp2 = temp1 / 2.0 Id1 = temp2

Anlise Lxica
O Analisador Lxico (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, etc), smbolos de pontuao (; , {, }, etc), labels.

Anlise Lxica
constanteInt constanteDouble digito digito* digito digito*. digito*

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

X* Representa uma seqncia de zero ou mais X.

Anlise Sinttica
Verifica se as frases obedecem as regras sintticas da linguagem: Por exemplo, uma expresso pode ser definida como: expresso + expresso expresso expresso (expresso) constante

Gramticas Livres de Contexto


Definidas por uma qudrupla (VN, VT, S, P), onde: VN um conjunto de smbolos no terminais (representam as construes sintticas da linguagem). VT um conjunto de smbolos terminais (tokens da linguagem). S VN o smbolo inicial da gramtica. P um conjunto de regras de produo, pares ordenados representados na forma , onde VN e (VN VT)*.

Gramticas Livres de Contexto


<expr> <expr> + <expr> | <expr> <expr> | (<expr>) | <const> <const> <const><const> |0|1|2|3|4|5|6|7|9

Derivao
Verificar se uma frase faz parte da linguagem gerada pela gramtica, envolve sucessivas substituies dos smbolos que ocorrem do lado esquerdo da produo pela sua construo sinttica correspondente. Essa substituio chamada derivao sendo normalmente denotada pelo smbolo . E deve iniciar a partir do smbolo inicial da gramtica.

Derivao
<expresso> <expr> + <expr> (<expr>) + <expr> (<expr> - <expr>) + <expr> (<const> - <expr>) + <expr> (<const><const> - <expr>) + <expr> (1<const> - <expr>) + <expr> (10 - <expr>) + <expr> (10 - <const>) + <expr>

...

(10 - 2) + 3

rvore de Derivao
(10 2) + <expr> <expr> (<expr>) <expr> - <expr> <const> 10 <const> 2 3 + <expr> <const> 3

Gramticas Ambguas
10 2 + 3 <expr> <expr> <expr> <expr> + <expr> 10 2 3 <expr> <expr> + <expr>

<expr> - <expr> 10 2 3

Gramticas
<expr> <expr> + <termo> | <expr> - <termo> | <termo> <termo> (<expr>) | <const>

<expr> <expr> + <termo>

<expr> - <termo> 2 3

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

Gramticas
<expr> <expr> + <termo> | <expr> - <termo> | <termo> <termo> * <fator> | <termo> / <fator> | <fator> (<expr>) | <const> 1+2*3 <expr>

<termo>

<expr>

<termo>

<fator>

<termo> * <fator> 3 2 3

Gramticas
<expr> <expr> + <termo> | <expr> - <termo> | <termo> <termo> * <fator> | <termo> / <fator> | <fator> (<expr>) | <const> 1+2*3 <expr>

<termo>

<termo>

<fator>

<termo> * <fator>

Traduo Dirigida pela Sintaxe


Programa Fonte Analisador Lxico Tabela de Smbolos token Solicita token

...
Analisador Sinttico

Analisador Semntico Cdigo Intermedirio

Gramticas - Exerccios
1. Considerando a gramtica apresentada anteriormente derive as expresses e apresente a rvore sinttica correspondente: (1 + 2) * 3 (1 2) + 3 * 4 Altere a gramtica para incluir o operador unrio -, esse operador deve ter precedncia maior que todos os outros operadores. Altere a gramtica para que os operadores de adio, subtrao, multiplicao e diviso tenham associatividade da direita para a esquerda. Defina uma gramtica para expresses aritmticas (operadores +, -, *, /) ps fixadas.

2.

3.

4.

Gramticas
Dados 2 conjuntos independentes de smbolos: VT Smbolos terminais. VN Smbolos no terminais. Uma gramtica definida como a qudrupla: (VN, VT, S, P) Onde, S VN o smbolo inicial da gramtica. P um conjunto de regras de reescrita na forma: , sendo: (VN VT)* VN (VN VT)* (VN VT)*

Classificao de Gramticas
Irrestritas nenhuma restrio imposta Sensveis ao Contexto - || || Livres de Contexto -

VN (VN VT)+ VN tem a forma a ou aB, onde


a VT e B VN

Regulares -

Gramticas Regulares
Uma gramtica regular gera uma linguagem regular.
C0|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

Linguagens Regulares
Geradas a partir de uma gramtica regular; Podem ser representadas atravs de uma expresso regular; Podem ser reconhecidas por Autmatos Finitos. Considerando linguagens compostas por smbolos 0 e 1 podemos afirmar: a linguagem L1 ={0n1n | n 1} no regular; a linguagem L2 ={0n1m | n 1, m 1} regular;

Expresses Regulares
Maneira compacta de representar linguagens regulares. composta de 3 operaes. Sendo e1 e e2 expresses que geram respectivamente duas linguagens regulares L1 e L2: Concatenao: e1e2 = { xy | x L1 e y L2} Alternao: e1|e2 = { x | x L1 ou x L2} Fechamento: e1* = zero ou mais ocorrncias de e1.
definida a precedncia desses operadores como sendo: fechamento, concatenao, alternao (da maior precedncia para a menor).

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

Autmato Finito
A linguagem gerada por uma gramtica regular pode ser reconhecida por um autmato finito. Um autmato finito consiste em:
1. Um conjunto finito de estados. 2. Um conjunto finito de smbolos de entrada (alfabeto). 3. Uma funo de transio que tem como argumentos um estado e um smbolo de entrada e retorna a um estado. 4. Um estado inicial. 5. Um conjunto de estados finais tambm chamados estados de aceitao.

Autmato Finito
letra | digito | _ letra | _

letra | digito | _ letra | _

.
digito digito digito digito

Autmato Finito
letra | digito | _ letra | _ f o r AFN Autmato Finito No Determinista

letra | digito | _ letra | _ AFD Autmato Finito Determinista ld f o ld r ld Onde ld representa letra | digito | _ (com exceo das letras que fazem transies para outros estados).

Autmato Finito Implementao


letra | digito | _ letra | _ 0 digito digito 2 1

Geradores de Analisadores Lxicos


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;}

Anlise Lxica Exerccios


1. Escreva uma gramtica, expresso regular e AFD que defina os nmeros binrios terminados em zero. 2. Mostre uma expresso regular e o AFD correspondente a gramtica abaixo: S aS B bC C aC | aB |a 3. Escreva uma expresso regular para as constantes double da linguagem C.

Especificao
Anlise Lxica expresses regulares. Anlise Sinttica gramticas livres de contexto. Anlise Semntica sistema de tipos (regras de inferncia), semntica denotacional, semntica operacional, semntica de aes. Gerao/Otimizao de Cdigo linguagens para descrio de arquiteturas.

Analisador Sinttico
Obtm uma sequncia de tokens fornecida pelo analisador lxico e verifica se a mesma pode ser gerada pela gramtica. Os mtodos de anlise sinttica comumente usados em compiladores so classificados como: Mtodos top-down. Mtodos bottom-up.
Os mtodos eficientes, tanto top-down quanto bottom-up, trabalham com subclasses das gramticas livres de contexto.

Mtodos top-down
Podem ser vistos como a tentativa de encontrar a derivao mais a esquerda para uma cadeia de entrada. Partindo do smbolo inicial da gramtica so aplicadas sucessivas derivaes tentado produzir a cadeia que se deseja reconhecer. Exemplos: Mtodo descendente recursivo. Mtodo LL(1).

Mtodo Descendente Recursivo


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

Mtodo Descendente Recursivo


void cons() { if (isdigit(lookahead)) nextToken(); else erro("Erro sinttico"); } void expr () { if (lookahead == '+' || lookahead == '-') { nextToken(); expr(); expr(); } else cons(); }

Analisadores Sintticos Preditivos


Escrevendo a gramtica de forma cuidadosa podemos obter uma gramtica processvel por um analisador sinttico que no necessite de retrocesso. Dado um smbolo de entrada a e um no terminal A, a ser expandido, a gramtica deve possuir uma nica produo que leve ao reconhecimento da cadeia iniciada com a. Analisadores sintticos no preditivos (ou no deterministas) necessitam de retrocesso (backtraking) e em geral so ineficientes.

Fatorao a Esquerda
As vezes necessrio fazer alteraes na gramtica que possibilitem a implementao de um reconhecedor preditivo: <cmd> if <expr> then <cmd> else <cmd> | if <expr> then <cmd> <cmd> if <expr> then <cmd><cmd> |

<cmd> else <cmd>

Fatorao a Esquerda
A 1 | 2 | ... | n | 1 | 2 | ... | m A A | 1 | 2| ... | m A 1 | 2 | ... | n

Eliminao da Recursividade a Esquerda


EE+T |E-T |T Tc | (E) E ET E+TT T+TT * c + c - c

Eliminao da Recursividade a Esquerda


A A1 | A2 | ... | An | 1 | 2 | ... | m A 1A | 2A | ... | mA A 1A | 2A | ... |nA | EE+T |E-T |T Tc | (E) E TE E +TE | -TE | Tc | (E)

Anlise Sinttica Preditiva no Recursiva LL(1)


E TE E +TE | T FT T * FT | Fc | (E) E TE FTE cTE cE c+TE c+FTE
No Terminal

c
TE

+
+TE

(
TE

E E T T F

FT

FT

* FT (E)

c+cTE c+c*FTE c+c*cTE c+c*cE c+c*c

Analisador Sinttico LL(1)


Considerando w a cadeia de entrada. Empilhar #, Empilhar o smbolo inicial da gramtica. Faa p apontar para o primeiro smbolo de w# Repetir Seja X o smbolo no topo da pilha e a o smbolo apontado por p; Se X for um terminal ou # ento Se X = a ento Remover X da pilha e avanar p; Seno erro. Seno /* X no um terminal */ Se M[X, a] = X Y1Y2...Yk ento Remover X da Pilha Empilhar Yk...Y2Y1 Seno erro At que X = #

Analisador Sinttico LL(1)


Uma gramtica cuja tabela no 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 so aplicadas derivaes mais a esquerda (left linear). O nmero 1 indica que necessrio apenas um smbolo para decidir qual produo aplicar (1 lookahead).

Construo da Tabela LL(1)


A construo de um analisador sinttico preditivo e auxiliada por duas funes associadas a gramtica: PRIMEIROS e SEGUINTES (FIRSTS e FOLLOWS) Seja uma cadeia qualquer de smbolos gramaticais, PRIMEIROS() representa o conjunto de smbolos terminais que comeam as cadeias derivadas a partir de . Se * ento tambm um elemento de PRIMEIROS().
EE+T ET TT*F TF F (E) Fc

PRIMEIROS(E) = { (, c}
ET F (E) ET F c

Construo da Tabela LL(1)


SEGUINTES(A), para um no terminal A, o conjunto de terminais a tais que existe uma derivao S * Aa, para alguma cadeia e alguma cadeia , onde S o smbolo inicial da gramtica. Ou seja o conjunto de smbolos que podem ocorrer aps o no terminal A em alguma forma sentencial da gramtica.
EE+T ET TT*F TF F (E) Fc

SEGUINTES(F) = { +, #, *, ) }
EE+T T+T F+T EE+T E+T E+F# ET T*F F*F ET F (E) (E + T) (E + F)

Construo da Tabela LL(1)


Entrada: Gramtica Sada: Tabela M Para cada produo A da gramtica faa: 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 situao de erro.

Construo da Tabela LL(1)


E TE E +TE | T FT T * FT | Fc | (E) PRIMEIROS (TE) PRIMEIROS (+TE) SEGUINTES (E) PRIMEIROS (FT) PRIMEIROS (*FT) SEGUINTES (T) PRIMEIROS (c) PRIMEIROS(E)
No Terminal

= {c, ( } = {+ } = { ), # } = {c, ( } ={*} = { +, ), # } = {c} ={(}


* ( TE ) FT * FT (E) #

c TE

+ +TE

E E T T F

FT c

Mtodos bottom-up
Podem ser vistos como a tentativa de se reduzir a cadeia de entrada ao smbolo inicial da gramtica. Exemplos: Precedncia de Operadores; SLR(1), LR(1), LALR(1).

Mtodos LR(k)
Os mtodos de anlise sinttica LR executam uma derivao mais a direita ao contrrio. O L significa que a varredura da entrada e feita da esquerda para a direita (left to right), o R que a derivao correspondente a derivao mais a direita (rightmost derivation) e o k indica o nmero de smbolos de entrada que tem que ser examinados para se tomar uma deciso na anlise sinttica.

A diferena entre os mtodos SLR e LALR apenas a tcnica usada para a construo das tabelas sintticas.

Mtodos LR
Estado

AO c 5 + 6 R2 R4 5 R6 5 5 6 R1 R3 R5 7 R3 R5 R6 4 4 11 R1 R3 R5 R1 R3 R5 * ( 4 ) # AC R2 R4 8 R6 R6 E 1

0 1 2 3 4 5 6 7 8 9 10 11

DESVIO T 2

F 3

7 R4 4

R2 R4

2 9

3 3 10

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

Algoritmo LR(1)
Considerando w a cadeia de entrada. Empilhar 0. /* Estado inicial */ Faa p apontar para o primeiro smbolo de w# Repetir para sempre Seja s o estado no topo da Pilha e a o smbolo apontado por p Se AO[s, a] = empilhar s ento Empilhar a; Empilhar s; Avanar p; Seno Se AO[s, a] = reduzir A ento Desempilhar 2 * || smbolos; Seja s o estado no topo da pilha Empilhar A; Empilhar DESVIO[s, A]; Seno Se AO[s, a] = aceitar ento Retornar; Seno erro fim

Pilha : 0 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 c 5 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 F 3 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 T 2 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 E 1 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 E 1 + 6 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 E 1 + 6 c 5 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 E 1 + 6 F 3 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 E 1 + 6 T 9 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Pilha : 0 E 1 Entrada: c + c #
I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Tabelas SLR(1)
Um item LR(0), para uma gramtica G, uma produo de G com um ponto em alguma das posies do seu lado direito. Exemplo: A produo 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 produo foi analisada em um determinado estado do analisador sinttico.

Construo da Tabela Sinttica SLR(1)


A construo da tabela sinttica auxiliada por duas operaes: Fechamento: Sendo I um conjunto de itens da gramtica, 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 produo, adicionar o item [B .] a FECHAMENTO(I). Essa regra aplicada at que nenhum novo item possa ser adicionado. Desvio: A operao DESVIO(I, X) definida como o fechamento do conjunto de todos os itens [A X.] tais que [A .X] esteja em I.

Construo da Tabela Sinttica SLR(1)


Construo de um conjunto de itens LR(0): C FECHAMENTO(S .S#) /* Onde S o smbolo inicial da linguagem */ Repetir Para cada conjunto de itens I em C e cada smbolo gramatical X tal que DESVIO(I,X) no seja vazio e no esteja em C Incluir Desvio(I,X) em C At que no haja mais conjunto de itens a serem includos em C

Construo da Tabela Sinttica SLR(1)


Construo da tabela sinttica SLR(1): 1. Construir o conjunto de itens C = {I0, I1,..., In} 2. Cada estado i construdo a partir de Ii. As aes sintticas so determinadas como: Se [A .a] estiver em Ii e DESVIO(Ii, a) = Ij ento ao[i, a] = Empilhar j (se a for um terminal) ou desvio[i, a] = Empilhar j (se a for um no terminal) Se [A .] estiver em Ii ento ao(i, a) = reduzir atravs de A , para todo a em SEGUINTE(A). Se [S S.#] estiver em Ii ento ao(i, #) = aceitar

Construo da Tabela Sinttica SLR(1)


I0 S .E# E .E + T E .T T .T * F T .F F .(E)

I1 Desvio(0,E) S E.# E E. + T I2 Desvio(0, T) E T. T T.* F I3 Desvio(0,F) T F.

T F

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

T F ( c c
I3 I4 I5

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

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

F .c

c
I5 Desvio(0,c) F c.

( c

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

(
I4 Desvio(0,() F (.E) E .E + T E .T T .T * F T .F F .(E) F .c

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

I6

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

Construo da Tabela Sinttica SLR(1)


I5 Desvio(0,c) F c.

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

I2 Desvio(0, T) SEGUINTE(E) = { +, ), # } E T. T T.* F I3 Desvio(0,F) T F. I9 Desvio(6,T) E E +T. T T. * F

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

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

Se [A .] estiver em Ii ento ao(i, a) = reduo atravs de A , para todo a em SEGUINTE(A).

I10 Desvio(7,F) SEGUINTE(F) = { +, *, ), # } T T * F. I11 Desvio(8, )) F (E). SEGUINTE(F) = { +, *, ), # }

Construo da Tabela Sinttica SLR(1)


No mtodo SLR(1), como a deciso de reduzir aplicando uma produo A , tomada usando o conjunto SEGUINTE(A) e no o contexto onde ocorreu, algumas gramticas LR(1) podem apresentar conflitos empilhar/reduzir se tentamos construir as tabelas usando esse mtodo. Por o exemplo: SL=R SR L *R L id RL
(Nesse exemplo os no terminais L e R representam l-value e r-value respectivamente)

Construo da Tabela Sinttica SLR(1)


I0 S .S# S .L = R S .R L .*R L .id R .L S I1 Desvio (0,S) S S.# L 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 * id id = I6 Desvio (2,=) S L=.R R I9 Desvio (6,L) R .L L .*R S L=R. L .id

R *

* R I7 Desvio (4,R) L *R. L

id

L I8 Desvio (4,L) R L.

I5 Desvio (0,id) L id.

Construo da Tabela Sinttica SLR(1)


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

SEGUINTE(R) = {=, # }

No estado 2, a ao reduzir R L deve ser executada para todos os seguintes de R, o que nesse caso ocasiona um conflito empilhar/reduzir. Entretanto no existe forma sentencial da gramtica que inicie com R =. Para tratar essa gramtica necessrio um mtodo que carregue mais informao sobre o contexto para o estado.

Construo da Tabela Sinttica LR(1)


Fechamento(I): Repetir Para cada item [A .B, a] em I, cada produo B na Gramtica e cada termina b em PRIMEIRO(a) tal que [B ., b] no esta em I Faa Incluir [B ., b] em I at que no seja mais possvel 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 smbolo inicial da gramtica) Repetir Para cada conjunto de itens I em C e cada smbolo gramatical X tal que Desvio(I, X) e Desvio(I, X) C Faa Incluir Desvio(I, X) em C at que nenhum novo item possa ser adicionado a C

Construo da Tabela Sinttica LR(1)


I0 L [S .S#, ] [S .L = R,#] [S .R,#] [L .*R,=,#] R [L .id,=,#] [R .L,#] S * I2 Desvio (0,L) = [S L. = R,#] [R L.,#] I3 Desvio (0,R) [S R.,#] R I6 Desvio (2,=) [S L=.R,#] [R .L,#] [L .*R,#] [L .id,#] R L * I7 Desvio (4,R) [L *R.,=,#] I9 Desvio (6,L) [S L=R.,#]
I10 Desvio (6,L)

[R L.,#]

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

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


I7 Desvio (11,R)

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

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

I12 Desvio (6,id)

[L id.,#]

LALR lookahead LR
A idia geral construir o conjunto de itens LR(1) e, se nenhum conflito aparecer, combinar os itens com ncleo comum. Algoritmos eficientes para a gerao de tabelas LALR constroem o conjunto de itens LR(0) e numa segunda etapa determinam os lookaheads correspondentes de cada item. O mtodo LALR: Trata a maioria dos casos presentes em linguagens de programao; Na grande maioria dos casos o nmero de estados muito inferior ao nmero de estados gerados pelo mtodo LR(1). Comparando com o mtodo LR(1), em algumas situaes, a deteco de erro postergada, redues desnecessrias so aplicadas antes que o erro seja detectado.

Construo da Tabela Sinttica LALR(1)


I0 L [S .S#, ] [S .L = R,#] [S .R,#] [L .*R,=,#] R [L .id,=,#] [R .L,#] S * I2 Desvio (0,L) = [S L. = R,#] [R L.,#] I3 Desvio (0,R) [S R.,#] I6 Desvio (2,=) [S L=.R,#] [R .L,#] [L .*R,#] [L .id,#] R I9 Desvio (6,L) [S L=R.,#]

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

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

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

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

id

Hierarquia de Gramticas Livres de Contexto


Gramticas no ambguas LR(k) LL(k) LR(1) LALR(1) LL(1) SLR(1) Gramticas Ambguas

Uso de Gramticas Ambguas


<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

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

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

Essa gramtica ambgua, como consequcia temos um conflito empilhar/reduzir no estado onde ocorre a transio para o token else. Caso esse conflito seja resolvido escolhendo a opo empilhar as redues executadas sero as correspondentes a primeira rvore.

Lex
delim ws digito num [ \t] {delim}+ [0-9] {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;}

yacc
%{ #include <stdio.h> #include <stdlib.h> #define YYSTYPE double %} %token TADD TMUL TSUB TDIV TAPAR TFPAR TNUM TFIM %%

yacc
Linha :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;} ; %%

yacc
int yyerror (char *str) { printf("%s - antes %s\n", str, yytext); } int yywrap() { return 1; }

Programa
#include <stdio.h> extern FILE *yyin; int main() { yyin = stdin; printf("Digite uma expresso:"); yyparse(); return 0; }

Definio Dirigida pela Sintaxe


uma gramtica livre de contexto na qual a cada smbolo associado um conjunto de atributos. A cada produo pode estar associada um conjunto de regras semnticas, que podem alterar valores de atributos, emitir cdigo, atualizar a tabela de smbolos, emitir mensagens de erro ou realizar quaisquer outras atividades. Em geradores de analisadores sintticos, estas regras so geralmente descritas em uma linguagem de programao. Os atributos so 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 ns irmos e/ou pais.

Definio Dirigida pela Sintaxe


Produo SE E E1 + T ET T T1 * F TF F (E) F const Regra Semntica {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}

S E.val = 7 E.val = 1 + T.val = 1 F.val = 1 const.lexval 1 + T.val = 6 T.val = 2 * F.val = 3 F.val = 2 const.lexval 2 * 3 const.lexval

rvores Sintticas
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

+ *

DAG Grafo Direcionado Acclico


Identifica as subexpresses comuns. Exemplo: DAG que representa a expresso: a * b + c + a *b.
+

+ * a b c

Cdigo de 3 endereos
Uma sequncia de enunciados na forma: x = y op z Onde x, y e z so nomes, constantes ou dados temporrios (criados pelo compilador) e op representa uma operao qualquer. Uma verso linearizada da rvore sinttica, assim chamado por cada instruo poder conter at trs endereos, dois para os operandos e um para o resultado. Bastante semelhante a uma linguagem de montagem.

Cdigo de 3 endereos
Exemplo: a = 2 * b + c t1 = 2 * b t2 = t1 + c a = t2

Cdigo de 3 endereos
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 =}

Cdigo de 3 endereos
Alguns enunciados comumente usados: x = y op z, onde op uma operao binria. x = op y, onde op uma operao unria. x = y, enunciado de cpia. goto L, desvio incondicional. if x relop y goto L, onde relop um operador relacional. param x, passagem de parmetro para funes/procedimentos. call p, chamada de uma funo/procedimento. x = a[i] ou a[i] = x, atribuies indexadas. *x = y ou x = *y, indirees.

Cdigo de 3 endereos
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:

Cdigo de 3 endereos
n = 1; f = 1; while (n < 10) { f = f * n; n = n + 1; } n=1 f=1 L1: if n >= 10 goto L3 f=f*n n=n+1 goto L1: L3:

Definies S-atribudas
Definies dirigidas pela sintaxe que possuem apenas atributos sintetizados.
Produo SE E E1 + T ET T T1 * F TF F (E) F const Regra Semntica {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}

S E.val = 7 E.val = 1 + T.val = 1 F.val = 1 const.lexval 1 + T.val = 6 T.val = 2 * F.val = 3 F.val = 2 const.lexval 2 * 3 const.lexval

Definies L-atribudas
Uma definio dirigida pela sintaxe L-atribuda se cada atributo herdado de Xj, 1 j n, do lado direito de uma produo, A X1X2...Xn depende somente: 1. Dos atributos dos smbolos X1X2...Xj-1 (smbolos a esquerda de Xj). 2. Dos atributos herdados de A.

Traduo Top-Down
S E {imprimir (E.val)} E T {E.h = T.val} E {E.val = E.s} E +T {E1.h = E.h + T.val} E1 {E.s = E1.s} E {E.s = E.h} T F {T.h = F.val} T {T.val = T.s} T * F{T1.h = T.h * F.val} T {T.s = T1.s} T {T.s = T.h} F const {F.val = const.lexval} F ({push(T.h); push(E.h)} E {E.h = pop(); T.h = pop()})

Anlise Semntica
D var S S 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}

Anlise Semntica
E E T T F F F E1 + T {if (E1.tipo = T.tipo) then E.tipo = E1.tipo else error()} T {E.tipo = T.tipo} T1 * F {if (T1.tipo = F.tipo) then T.tipo = T1.tipo else error()} F {T.tipo = F.tipo} id {F.tipo = consultaTipo(id.lexval);} constInt {F.tipo = Inteiro} constReal {F.tipo = Real}

Obs: Em uma situao real as regras semnticas devem implementar a coero dos tipos.

Expresses Lgicas e Relacionais


B B1 or M C {corrigir(B1.listaf, M.label); B.listav = merge(B1.listav, C.listav); B.listaf = C.listaf;} {corrigir(B1.listav, M.label); B.listaf = merge(B1.listaf, C.listaf); B.listav = C.listav;} {B.listav = C.listav; B.listaf = C.listaf;} {C.listav = C1.listaf; C.listaf = C1.listav;} {C.listav = B.listav; C.listaf = B.listaf;} {C.listav = criaLista(proxInst); C.listf = criaLista(proxInst+1);} gerar(if E1.local rel E2.local goto _); gerar (goto _); {M.label = novolabel()}

B B1 and M C

B C C C

C not C1 (B) E1 rel E2

Comandos de Seleo e Repetio


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); corrigir(N.listav, novoLabel();} S while M1 (B) M2 S {corrigir(B.listav, M2.label); gerar(goto M1.label); corrigir(B.listaf, novolabel();} N {N.listav = criarLista(ProxInstr); gerar(goto _);}

Organizao da Memria
Endereo 0
No usado

Cdigo

Dados estticos Heap

Dados Dados dinmicos


Pilha

Dados Estticos
A rea de memria reservada no incio da execuo do programa e liberada apenas no fim de sua execuo (e.g. variveis globais e variveis locais declaradas com o modificador static em linguagem C).

Dados Dinmicos
Pilha rea de armazenamento temporrio onde armazenado o registro de ativao das funes. Heap rea reservada para alocao dinmica, permite ao programador alocar e liberar espaos de memria quando necessrio (e.g. reas de memria reservadas pelas funes malloc e liberadas pela funo free em linguagem C).

Registro de Ativao
As informaes necessrias para execuo de uma funo/procedimento so gerenciadas utilizando um bloco de memria chamado registro de ativao, fazem parte do registro de ativao: parmetros, endereo de retorno e variveis locais.

Chamadas de Funes/Procedimentos
int fat (int n) { if (n >= 1) return 1; return n * fat(n-1); }
fat: pushl %ebp movl %esp, %ebp movl 8(%ebp), %ebx cmpl $1, %ebx jl L1: movl $1, %eax movl %ebp, %esp popl %ebp ret L1: subl $1, %ebx pushl %ebx call fat subl $4, %esp movl 8(%ebp), %ebx imull %ebx, %eax movl %ebp, %esp popl %ebp ret fat: pushl %ebp movl %esp, %ebp movl 8(%ebp), %ebx cmpl $1, %ebx jl L1: movl $1, %eax jmp L3 L1: subl $1, %ebx pushl %ebx call fat movl 8(%ebp), %ebx imull %ebx, %eax L3: movl %ebp, %esp popl %ebp ret

Chamadas de Funes/Procedimentos
int fat (int n) { if (n >= 1) return 1; return n * fat(n-1); } Int main() { int x; x = fat(3); }
%ebp = 960 %ebp+8 n %ebp = 972 %ebp+8 n %ebp = 984 %ebp+8 n %ebp-4 x %ebp = 1000 972 ret 1 984 ret 2 1000 ret 3 %ebp-ant

960 964 968 972 976 980 984 988 992 996 1000