Sunteți pe pagina 1din 42

Construo de Compiladores

Parte 1
Introduo
Linguagens e Gramticas
F.A. Vanini
IC Unicamp
Klais Solues
Motivao
Porque compiladores ?
So ferramentas fundamentais no processo de
desenvolvimento de software e sua compreenso
contribui para um uso melhor.
Reunem conhecimentos de vrias reas
(linguagens formais, estruturas de dados,
algoritmos, arquitetura de computadores) num
nico produto.
Oferecem excelentes oportunidades de aplicao
de conceitos de engenharia de software como pro
exemplo orientao a objetos, design patterns.
Contedo
O processo de compilao
Descrio de linguagens
Anlise sinttica
Anlise semntica
Organizao de programas em tempo
de execuo
Estrutura geral de um compilador
Gerao de cdigo
Bibliografia
T. Kowaltowski, Implementao de Linguagens de
Programao, Guanabara Dois, 1983
A. Aho, R. Sethi, J. D. Ullman, Compilers -
Principles, Techniques and Tools, Addison-Wesley,
1986 ( existe tambm a edio em portugus:
Compiladores Princpios, Tcnicas e Ferramentas,
LTC, 1995)
A. W. Appel, Modern Compiler Implementation in
Java, Cambridge University Press, 1997
N. Wirth, Compiler Construction, Addison-Wesley,
1996

O processo de compilao
Compilador
cdigo
fonte
cdigo
executvel
linguagem
fonte (java,
C++, vb, etc)
linguagem
de mquina
O processo de compilao
A compilao de um programa
tipicamente envolve o seguinte:
Anlise lxica
Anlise Sinttica
Anlise Semntica
Traduo
Anlise Lxica
A anlise lxica responsvel por
Ler o texto fonte, caracter a caracter
Identificar os elementos lxicos da
linguagem: identificadores, palavras
reservadas, constantes, operadores
Ignorar comentrios, brancos, tabs
Processar includes (se for o caso)
Anlise Sinttica
A anlise sinttica responsvel por
identificar na seqencia de elementos
lxicos as construes da linguagem.
Exemplo : para a sequncia abaixo, em Pascal,

if a > b then a:=a-b else b:=b-a

A anlise sinttica deve idenfic-la como um comando
condicional, para a qual a condio a > b e
ao qual esto associados os comandos a := a-b e
b := b-a.
Anlise Semntica
A anlise semntica tem por objetivo
verificar se as construes identificadas
pela anlise sinttica esto em acordo
com as regras semnticas da linguagem
sendo compilada.
Exemplo: em Pascal existe uma regra dizendo que todas
as variveis de um programa devem ser declaradas
antes do seu uso. funo da anlise semntica
verificar se as variveis usadas no programa foram
devidamente declaradas.
Anlise Lxica x Anlise Sinttica
A anlise lxica e a anlise sinttica tem
papis parecidos, j que as duas tratam
de sequncias de smbolos.
A separao das duas em dois nveis de
descrio e tratamento simplifica no s a
descrio da linguagem como tambm a
implementao do compilador.
Gramticas e Linguagens
O conceito de gramtica ser usado
inicialmente como ferramenta para
descrever uma linguagem e
posteriormente como base para a
construo dos analisadores lxico
sinttico.


Definies Iniciais


alfabeto - conjunto finito no vazio de smbolos (denotado por E).

cadeia (ou sentena) sobre um alfabeto E : uma seqncia finita
de smbolos de E.

cadeia nula, denotada por (no contm nenhum smbolo)

comprimento de uma cadeia o ( |o| ) : nmero de smbolos que
compem o.
concatenao (produto) de duas cadeias o e |, denotado por o|:

se o = x
1
x
2
... x
n
e

| = y
1
y
2
... y
m


ento o|= x
1
x
2
... x
n
y
1
y
2
... y
m



a concatenao de cadeias associativa: o (| ) = (o|)

Exemplos


alfabeto - E = { a, b, c }

cadeias (sentenas) sobre E : abc, aaa, cabc, caaaa, aaacccbbb, ...

comprimento da cadeia:
| abc | = 3 | caaaa | = 5 | aaacccbbb | = 9
| cabc | = 4 | | = 0 | a | = 1

concatenao (ou produto): para o = abc , | = aaa e = cabc

o| = abcaaa |o = aaaabc
o = o = o = abc
o (| ) = (o|) = abcaaacabc
o
1
= o = abc o
2
= abcabc
o
3
= abcabcabc o
0
=
o
n
= o
n-1
o (para n > 0)



Linguagem


Se E um alfabeto ento

E
*
representa todas as cadeias sobre E
E
+
representa todas as cadeias sobre E com
comprimento maior ou igual a 1 (E
+
= E
*
- {}).

Uma linguagem sobre um alfabeto E um subconjunto
de E
*
.



Gramtica


Define-se uma gramtica G como G= (T,N,P,S) onde:

T - alfabeto denominado vocabulrio terminal de G
N - alfabeto denominado vocabulrio no-terminal de
G (T e N so disjuntos e E = T N o vocabulrio
de G)
P um conjunto de regras da forma X o nas quais
X e N e o e E
*
( X o indica X pode ser substitudo
por o )

S e N (S chamado smbolo inicial de G).


Um exemplo


G = ( N, T, P, E ) onde

N = { E, O } T = { a, b, c, +, *, (, ) }
P = { E a, E b, E c, E ( E O E ),
O *, O + }

P = {
E a,
E b,
E c,
E (E O E),
O *,
O + ,
}
Notao alternativa: regras com o mesmo
smbolo no terminal esquerda podem
ser fatoradas atravs do uso do meta-
smbolo |. Por exemplo, as regras com o
smbolo E esquerda podem ser
reescritas como:

E a | b | c | (E O E)

Derivaes


Derivao direta: o| se o da forma X, X e N, |
da forma , eE
*
e X e P

Informalmente: a sentena o deriva diretamente a
sentena | se | pode ser obtida a partir de o atravs da
aplicao de uma das regras de substituio de P.

Exemplo: na gramtica do exemplo anterior,

( E O E ) ( E + E ) aplicando-se a regra O +
( E + E ) ( a + E ) aplicando-se a regra E a
( a + E ) ( a + b ) aplicando-se a regra E b

Derivaes


Derivao em um ou mais passos:
o
+
| se existem
1

2
...
n
tais que
o
1
,
1

2
, ...
n
|

Informalmente: a sentena o deriva diretamente a
sentena | se | pode ser obtida a partir de o atravs da
aplicaes sucessivas das regras de substituio de P.

Exemplo: Pelo exemplo anterior,
( E O E )
+
( a + b )

Derivao em um ou mais passos:
o
*
| se o = | ou o
+
|
Linguagem gerada por uma
gramtica
Forma sentencial:
o uma forma sentencial em G se S
*
o

Linguagem gerada por G:
L(G) = { o | o e T
*
e S
*
o }
Informalmente: a linguagem gerada por uma gramtica
G corresponde ao conjunto de sentenas formadas por
smbolos terminais, derivadas do smbolo inicial.

Um Exemplo
G = (N,T,P,E) onde
T = { (, ), +, *, a, b, c } N = { E, O, E }
P = { E ( E O E ) | a | b | c
O + | *
}

L(G ) = conjunto de expresses delimitadas por
parnteses, como p. ex. (a+((a+c)*b))

Outro Exemplo
G = (N,T,P,Z) onde
N = { Z, S, D, M }
T = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, - }
P = { Z SM | M, M D| DM, S + | -
D 0 | 1| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
}

L(G ) = conjunto das representaes em decimal dos
nmeros inteiros.
Limitaes da Gramtica
Uma gramtica G, da forma como foi definida, no
consegue descrever todas as situaes que ocorrem
numa linguagem de programao.
O tipo de gramtica apresentado chamado na literatura
de gramtica livre de contexto (context free grammar)
porque uma regra pode ser aplicada a um no terminal,
independentemente do contexto em que ele ocorre na
forma sentencial.
Um exemplo: em muitas linguagens, para que uma
varivel possa ser usada num programa, necessrio
que a mesma tenha sido declarada.


O Problema da Anlise Sinttica
O problema da anlise sinttica consiste
em:
Dada uma gramtica G = (T,N,P,S) e uma
sentena o
Determinar se o L(G)
Determinar a sequncia de regras de P tal que
S
+
o
A sequncia de regras usada na derivao de o define
a estrutura da sentena, que num compilador a
base para o processo de traduo.
O Problema da Anlise Sinttica
Uma tentativa: verificar se uma sentena o e L(G)

C
0
= {S}
i = 0;
repita
i = i+1;
C
i
= { | | | para algum e C
i-1
e | | | o | } ;
at (C
i
= { }) ou (o e C
i
) ;

O algoritmo acima pode ser estendido para manter a
sequncia de regras aplicadas a cada elemento de C
i
.
No prtico (um bom exerccio verificar se o algoritmo
acima tem um comportamento polinomial ou exponencial).
Anlise sinttica na prtica
Para que a anlise sinttica seja usada
num compilador real, em geral o que se faz

Restringir as regras da gramtica, com
eventuais restries s linguagens geradas
pelas mesmas.
Relaxar a definio da linguagem, deixando
algumas verificaes para a fase de verificao
semntica.
rvore de Derivao
A rvore de derivao de uma sentena descreve
univocamente como a mesma gerada.
Exemplo:

E

( E O E )
| | |
a + ( E O E )
| | |
b * c
Derivaes Cannicas I

A seqencia de derivaes diretas pode ser usada
para descrever a forma pela qual uma sentena
gerada.

Exemplo:
E ( E O E ) ( E + E ) ( a + E ) ( a + b )

Essa seqencia no nica uma vez que nela existem
formas sentenciais com mais de um smbolo no
terminal e existe pelo menos uma substituio possvel
para cada um.


Derivaes Cannicas II

As derivaes cannicas so derivaes nas quais a
substituio aplicvel a um nico smbolo no
terminal.

numa derivao (cannica) mais esquerda, a
substituio sempre aplicada ao no terminal mais
esquerda da forma sentencial.

numa derivao (cannica) mais direita, ...

Uma derivao cannica corresponde biunivocamente
a uma rvore de derivao.
Gramtica Ambgua


Uma gramtica ambgua se existe pelo menos uma
sentena para a qual existem pelo menos duas rvores de
derivao (ou ainda, existem pelo menos duas derivaes
mais esquerda ou pelo menos duas derivaes mais
direita).

Exemplo:
G = ( N, T, P, E ) onde
N = { E } T = { a, b, c, +, * }
P = { E a | b | c | E + E | E * E }

E E + E E * E + E a * E + E a * b + E a*b+c
E E * E a * E a * E + E a * b + E a*b+c

Ambiguidade x Compilador
Num compilador, o processo de traduo baseado na
derivao da sentena (programa).
Se a gramtica que define a linguagem sendo
compilada for ambgua, existir pelo menos um
programa para o qual so possveis pelo menos duas
tradues.
Um exemplo clssico, em Pascal (o mesmo problema
existe em C e Java):
C a | if b then C else C | if b then C


if a <> b then if a > b then a:=a-b else b:=b-a
Ambiguidade x Compilador
Num compilador a ambiguidade deve ser
evitada.
A primeira idia para se evitar construes
ambguas alterar a gramtica.
Nem sempre a gramtica alterada adere s
restries impostas pelo analisador sinttico.
Em alguns casos, a ambiguidade
contornada atravs de regras que
complementam a gramtica.

Gramticas Reduzidas
Uma gramtica reduzida se satisfaz s seguintes
restries:
Para qualquer smbolo X e E,
S
*
oX| para algum o e |
X
*
w para algum w e T
*



Em outras palavras: todo smbolo X derivvel a partir
do smbolo inicial e todo smbolo leva a uma cadeia
formada apenas por terminais. A gramtica no contm
regras ou smbolos inteis.

Anlise Sinttica
A anlise sinttica ou parsing de uma sentena w, numa
gramtica G, consiste em verificar se w e L(G) e em caso
positivo, determinar a estrutura sinttica de w em G.
A estrutura sinttica de w pode ser descrita por uma rvore
de derivao de w em G ou por uma derivao cannica de
w em G.
Existem duas grandes famlias de mtodos de anlise
sinttica:
anlise sinttica descendente
anlise sinttica ascendente


Linguagens Regulares
Uma linguagem chamada linguagem regular se ela
pode ser descrita por uma gramtica cujas regras so da
forma:
A a ou A aB
onde A e B so no terminais e a um terminal.
Exemplo:
G = { {S,A,B,C}, { 0, 1}, P, S} onde
p = { S aS | bB, B bB | cC | c , C cC | c }
L(G) = { w | w = a
i
b
j
c
k
e i > 0, j > 1, k > 1 }
Autmato de Estados Finitos
Um autmato de estados finitos definido por
A = ( E, T, M, E
i
, F) :

E - conjunto de estados E, finito
T - um alfabeto T
M - funo de transio M que associa pares de
E T aos elementos de E
E
i -
um estado E
i
e E, dito estado inicial
F - conjunto de estados finais ( F _ E ).
Um exemplo I
A = ( {E
1
, E
2
, E
3
, E
4
}, {a,b,c}, M, E
1
, {E
4
} ), onde M
definida por

M(E1,a) = E2 M(E1,b)= E3 M(E1,c) = E4
M(E2,a) = E2 M(E2,b) = E3 M(E2,c) = E4
M(E3,b) = E3 M(E3,c) = E4
M(E4,c) = E4

Um exemplo II
Representao grfica:
E
1
E
2
E
3
E
4
a
b
c
c
b
a
c
b
Linguagem
Uma sentena w = x
1
x
2
.. x
k
aceita por um autmato
de estados finitos se existe uma sequncia de
transies da forma:

M(E
1
,x
1
) = E
2
,
, M(E
2
,x
2
) = E
3
, ... M(E
k
,x
k
) = E e F.

A linguagem aceita por um autmato de estados finitos
uma linguagem regular.
Autmato e Anlise Lxica
O conjunto de smbolos lxicos de uma
linguagem de programao so descritos por
uma linguagem regular, que pode ser
reconhecida por um autmato de estados
finitos.



Implementao I
Dirigido por Tabela: Uma tabela M[E,x] descreve a
funo de transio e um programa genrico dirigido
pela mesma:
E= EstadoInicial;
repita
{
ch=PrximoCaracter; E = M[E,ch];
se (E == EstadoIndefinido
{
erro(caracter invlido)
}
} at FimDeEntrada;
Implementao II
Programa Dedicado
O analisador lxico dirigido por tabela tem a vantagem
de ser genrico e a desvantagem de ser difcil de se
contruir manualmente.
Na prtica, o tratamento lxico da maioria das
linguagens de programao pode ser feita atravs de
um programa dedicado.
Normalmente o analisador lxico implementado
como uma funo que devolve o cdigo do prximo
smbolo da entrada. Essa funo chamada pelo
analisador sinttico cada vez que este necessita de
um smbolo.
Um exemplo
Reconhecimento de inteiros e identificadores:
funo proximo_smbolo () {
enquanto (caracter == ) leia caracter;
caso caracter seja{
a..z: enquanto (a s caracter s z)
leia caracter;
retorne ident;
0..9: enquanto(0 s caracter s 0)
leia caracter;
retorne numero;
outro: erro( caracter invlido);
}
}

S-ar putea să vă placă și