You are on page 1of 10

Compiladores 1

Introduo
Linguagens de programao so notaes para se descrever computaes para pessoas e para mquinas. Todo software executado em todos os computadores foi escrito em alguma linguagem de programao. As linguagens de programao podem ser classificadas em cinco geraes: 1) Linguagens de mquina: permitem a comunicao direta com o computador em termos de bits, registradores e operaes de mquina bastante primitivas. 2) Linguagens simblicas (Assembly): projetadas para minimizar as dificuldades da programao em notao binria.Utiliza mnemnicos. 3) Linguagens orientadas ao usurio (Fortran, Pascal, Basic, etc): linguagens procedurais, isto , um programa especifica uma sequncia de passos a serem seguidos para solucionar o problema, e linguagens declarativas que se baseiam na teoria das funes recursivas (funcionais) e de lgica matemtica (lgicas). 4) Linguagens orientadas aplicao (Excel, SQL, Framework, etc): visam facilitar a programao de computadores, apressar o processo de desenvolvimento de aplicaes, facilitar a manuteno de aplicaes, reduzindo custos, minimizar problemas de depurao e gerar cdigos sem erros a partir de requisitos de expresses de alto nvel. 5) Linguagens de conhecimento: usadas principalmente na rea de Inteligncia Artificial. Facilitam a representao do conhecimento que essencial para a simulao de comportamentos inteligentes. Mas, antes que possa rodar, um programa primeiro precisa ser traduzido para um formato que lhe permita ser executado por um computador. Os sistemas de software que fazem essa traduo so denominados compiladores. Compiladores so programas de computador que traduzem de uma linguagem para outra. Um programa recebe como entrada um programa escrito na linguagem-fonte e produz um programa equivalente na linguagem-alvo. Geralmente, a linguagem-fonte uma linguagem de alto nvel, como C ou C++, e a linguagem-alvo um cdigo-objeto (cdigo de mquina) para a mquina-alvo. Programa fonte COMPILADOR Programa objeto

Tradutores de Linguagens de Programao


Os tradutores de linguagens de programao podem ser classificados em: Montadores (assemblers): um tradutor para a linguagem de montagem (Assembly) de um computador em particular. Geralmente uma instruo de linguagem simblica (de montagem) para uma instruo de mquina. Por vezes um compilador ir gerar uma linguagem de montagem como sua linguagem-alvo e, em seguida, contar com um montador para concluir a traduo para o cdigo-objeto. Compiladores: so tradutores que mapeiam programas escritos em linguagem de alto nvel para programas equivalentes em linguagem simblica ou de mquina.

2 Introduo Pr-compiladores (pr-processadores): so processadores que mapeiam instrues escritas numa linguagem de alto nvel estendida para instrues da linguagem de programao original, ou seja, so tradutores que efetuam converses entre duas linguagens de alto-nvel. um programa separado, ativado pelo compilador antes do incio da traduo. Ele pode apagar comentrios, incluir outros arquivos e executar substituies de macros. Interpretadores: um tradutor de linguagens, assim como um compilador. A diferena que o interpretador executa o programa-fonte de imediato, em vez de gerar um cdigo-objeto que seja executado aps o trmino da traduo. Os interpretadores processam uma forma intermediria do programa fonte e dados ao mesmo tempo. A interpretao da forma interna do fonte ocorre em tempo de execuo, no sendo gerado um programa objeto. O intervalo de tempo no qual ocorre a converso de um programa fonte para um programa objeto chamado de tempo de compilao. O programa objeto executado no intervalo de tempo chamado tempo de execuo. O programa fonte e os dados so processados em momentos distintos, respectivamente, tempo de compilao e tempo de execuo. Os interpretadores so, geralmente, menores que os compiladores e facilitam a implementao de construes complexas de linguagens de programao. O tempo de execuo de um programa interpretado maior que o tempo necessrio para executar um programa compilado equivalente. O cdigo objeto compilado dez ou mais vezes mais rpido que o cdigo fonte interpretado.

A estrutura de um tradutor
Os tradutores de linguagens de programao (compiladores, interpretadores) so constitudos internamento por passos (fases) para operaes lgicas distintas. No processo de traduo existem duas partes: anlise e sntese. A anlise (front-end) subdivide o programa fonte em partes constituintes e impe uma estrutura gramatical sobre elas. Depois, usa essa estrutura para criar uma representao intermediria do programa fonte. A anlise detecta m formao sinttica e erros semnticos, oferecendo mensagens esclarecedoras, para que o usurio possa tomar a ao corretiva. A anlise tambm coleta informaes sobre o programa fonte e as armazena em uma estrutura de dados chamada tabela de smbolos. A sntese (back-end) constri o programa objeto a partir da representao intermediria e das informaes na tabela de smbolos.
Anlise Lxica

O objetivo desta fase identificar sequncias de caracteres que constituem unidades lxicas (tokens, lexemas). O analisador lxico l o fluxo de caracteres que compem o programa fonte e os agrupa em sequncias significativas (lexemas). O analisador lxico verifica se os caracteres lidos pertencem ao alfabeto da linguagem, identificando tokens e desprezando comentrios e brandos desnecessrios. Os tokens constituem classes de smbolos tais como palavras reservadas, delimitadores, identificadores, etc. Para cada lexema, o analisador lxico produz como sada um token no formato: <nome-token, valor-atributo> que ele passa para a fase de anlise sinttica. Palavras reservadas, operadores e delimitadores so representados pelos prprios smbolos.

Compiladores 3

O analisador lxico, em geral, inicia a construo da tabela de smbolos e envia mensagens de erro caso identifique unidades lxicas no aceitas pela linguagem em questo. Exemplo 1: Suponha que um programa fonte contenha o comando de atribuio position = initial + rate * 60 Os caracteres nessa atribuio poderiam ser agrupados nos seguintes lexemas e mapeados para os seguintes tokens passados ao analisador sinttico: Lexema Smbolo Significado Entrada Token position id <id, 1> identificador 1 = <=> initial id <id, 2> identificador 2 + <+> rate id <id, 3> identificador 3 * <*> 60 nmero 4 <nmero, 4> inteiro Aps a anlise lxica a representao do comando de atribuio fica como uma sequncia de tokens: <id, 1> <=> <id, 2> <+> <id, 3> <*> <nmero, 4> Exemplo 2: Considere a linha de cdigo a seguir, que poderia pertencer a um programa em C. a [index] = 4 + 2 Esse cdigo contm 12 caracteres diferentes de espao, mas somente 8 marcas: Lexema Smbolo Significado Entrada Token a id <id, 1> identificador 1 [ <[> index id <id, 2> identificador 2 ] <]>

4 Introduo Lexema Smbolo Significado Entrada Token = <=> 4 nmero 3 <nmero, 3> inteiro + <+> 2 nmero 4 <nmero, 4> inteiro Os caracteres nessa atribuio poderiam ser mapeados para os seguintes tokens passados para o analisador sinttico: <id, 1> <[> <id, 2> <]> <=> <nmero, 3> <+> <nmero, 4> Exemplo 3: Seja o seguinte texto fonte em Pascal. while i < 100 do i := j + i ; Os caracteres nessa atribuio poderiam ser mapeados para os seguintes tokens passados para o analisador sinttico: Lexema Smbolo Significado Entrada Token while <while> i id <id, 1> identificador 1 < <<> 100 nmero 1 <nmero, 1> inteiro do <do> i id 1 <id, 1> identificador := <:=> j id <id, 2> identificador 2 + <+> i id <id, 1> identificador 1 ; <;> Aps a anlise lxica da instruo ter-se ia a seguinte cadeia de tokens:
<while> <id, 1> <<> <nmero, 1> <do> <id, 1> <:=> <id, 2> <+> <id, 1> <;>

Anlise sinttica

Essa fase tem por funo verificar se a estrutura gramatical do programa est correta. O analisador sinttico utiliza os primeiros componentes dos tokens produzidos pelo analisador lxico para criar uma representao intermediria tipo rvore (rvore de derivao), que mostra a estrutura gramatical da sequncia de tokens. Outra funo dos reconhecedores sintticos a deteco de erros de sintaxe identificando clara e objetivamente a posio e o tipo de erro percorrido. O analisador sinttico deve tentar recuperar os erros encontrados, prosseguindo a anlise do texto restante. Exemplo 1: Essa rvore mostra a ordem em que as operaes do comando de atribuio position = initial + rate * 60 deve ser realizada. = id, 1 + id, 2 = id, 3 Nmero, 4

Compiladores 5

Exemplo 2: Considere a linha de cdigo em C a [index] = 4 + 2 que representa um elemento estrutural denominado expresso (uma expresso de atribuio), composta por uma expresso indexada esquerda e uma expresso aritmtica de inteiros direita. Esta estrutura pode ser representada em uma rvore de anlise sinttica (rvore sinttica) da seguinte forma:
expresso

expresso de atribuio

expresso

expresso

expresso indexada

Expresso aritmtica

expresso

expresso

expresso

expresso

id, 1

id, 2

Nmero, 3

Nmero, 4

Exemplo 3: Considere o seguinte comando Pascal. while <expresso> do <comando>; Nesse caso, a estrutura <expresso> deve apresentar-se sintaticamente correta, e sua avaliao deve retornar um valor do tipo lgico. Considerando o comando while do exemplo, o analisador sinttico produzir a rvore de derivao a partir da sequncia de tokens liberada pelo analisador lxico.
<while> <expresso> <id, 1> <<> <nmero, 1> <do> <id, 1> <comando> <:=> <+> <id, 3>

<id, 2> Anlise semntica

o significado de um programa, contrastando com sua sintaxe ou estrutura. O analisador semntico utiliza a rvore de sintaxe e as informaes na tabela de smbolos para verificar a consistncia semntica do programa fonte com a definio da linguagem. Ele tambm rene informaes sobre os tipos e as salva na rvore de sintaxe ou tabela de smbolos, para uso subsequente durante a gerao de cdigo intermedirio. Na verificao de tipo o compilador verifica se cada operador possui operandos compatveis. A especificao da linguagem pode permitir algumas converses de tipos chamada coeres. Por exemplo, se um operador for aplicado a um nmero de ponto

6 Introduo flutuante e a um inteiro, o compilador pode converter ou coagir o inteiro para um nmero de ponto flutuante. Exemplo 1: No exemplo da expresso em C a[index] = 4+2 as informaes de tipos tpicas que poderiam ser obtidas antes de analisar essa linha seriam: a um vetor de valores inteiros com ndices de um intervalo de inteiros index uma varivel de inteiros O analisador semntico anota na rvore sinttica com os tipos de todas as subexpresses e verifica se as atribuies fazem sentido para esses tipos, caso contrrio declara um erro de divergncia entre tipos.
expresso de atribuio

expresso indexada inteiro identificador a vetor de inteiros identificador index inteiro

expresso de adio inteiro

nmero 4 inteiro

nmero 2 inteiro

Exemplo 2: Suponha: position = initial + rate * 60 que position, initial e rate foram declaradas como nmeros de ponto flutuante, e que o lexema 60 tenha a forma de um inteiro. O verificador de tipos no analisador semntico descobre que o operador * aplicado a um nmero de ponto flutuante rate e a um inteiro 60. Nesse caso, o inteiro pode ser convertido em um nmero de ponto flutuante. = id, 1 + id, 2 = id, 3 intfloat 60

Gerao de cdigo intermedirio

No processo de traduzir um programa fonte para um cdigo objeto, um compilador pode produzir uma ou mais representaes intermedirias. As rvores de sintaxe denotam uma forma de representao intermediria. Esta fase gera como sada uma sequncia de cdigo, que pode, eventualmente, ser o cdigo objeto final, mas, na maioria das vezes, constitui-se num cdigo intermedirio. A representao intermediria explcita de baixo nvel (linguagem de mquina) um programa para uma mquina abstrata. Essa representao intermediria deve ter duas propriedades importantes:

Compiladores 7

ser facilmente produzida e ser facilmente traduzida para a mquina alvo. A traduo de cdigo fonte para objeto em mais de um passo apresenta algumas vantagens: possibilita a otimizao de cdigo intermedirio, de modo a obter-se o cdigo objeto final mais eficiente; resolve, gradualmente, as dificuldades da passagem de cdigo fonte para cdigo objeto (alto nvel para baixo nvel), j que o cdigo fonte pode ser visto como um texto condensado que explode em inmeras instrues elementares de baixo nvel. Exemplo 1: Para o comando de atribuio position = initial + rate * 60 o gerador de cdigo intermedirio, recebendo a rvore de derivao, produziria a seguinte sequncia de instrues: t1 = inttofloat(60) t2 = id3 * t1 t3 = id2 + t2 id1 = t3 Consideramos uma forma intermediria, chamada cdigo de trs endereos, que consiste em uma sequncia de instrues do tipo assembler com trs operandos por instruo. Cada operando pode atuar como um registrador. A sada do gerador de cdigo intermedirio consiste em uma sequncia de instrues ou cdigo de trs endereos. Exemplo 2: Para o comando while apresentado anteriormente, o gerador de cdigo intermedirio, recebendo a rvore de derivao, poderia produzir a seguinte sequncia de instrues: L0 if i < 100 goto L1 goto L2 L1 t := j + i i := t goto L0 L2 ... H vrios tipos de cdigo intermedirio: qudruplas, triplas, notao polonesa ps-fixada, etc. A linguagem intermediria do exemplo acima chamada cdigo de trs endereos (cada instruo tem no mximo trs operandos). Exemplo 3: Um cdigo de trs endereos para a expresso a[index] = 4+2 em C poderia ficar assim: t = 4 + 2 a[index] = t Observe o uso de uma varivel temporria adicional t para armazenar o resultado intermedirio. Vrios pontos precisam ser observados em relao aos cdigos de trs endereos: 1) Cada instruo de atribuio de trs endereos possui no mximo um operador do lado direito. Assim, essas instrues determinam a ordem em que as operaes devem ser realizadas. 2) O compilador precisa gerar um nome temporrio para guardar o valor computador por uma instruo de trs endereos. 3) Algumas instrues de trs endereos possuem menos de trs operandos.

8 Introduo
Otimizao de cdigo

Tem por objetivo otimizar o cdigo intermedirio em termos de velocidade de execuo e espao de memria. Esta fase independente das arquiteturas de mquina faz algumas transformaes no cdigo intermedirio com o objetivo de produzir um cdigo objeto melhor. Melhor significa mais rpido, cdigo menor, que consuma menos energia. Exemplo 1: O otimizador de cdigo melhoraria o cdigo a[index] = 4 + 2 em dois passos, inicialmente computando o resultado da adio t = 6 a[index] = t e depois substituindo t por seu valor, para obter a declarao de trs endereos a[index] = 6 Exemplo 2: Na atribuio position = initial + rate * 60 o otimizador pode deduzir que a converso do valor inteiro para ponto flutuante pode ser feita de uma vez por todas durante a compilao. Alm do mais, t3 usado apenas uma vez na atribuio de seu valor para id1, portanto o otimizador pode elimin-lo transformando em uma sequncia de cdigo menor. t1 = id3 * 60.0 id1 = id2 + t1 Exemplo 3: Considerando o cdigo intermedirio do exemplo do comando while, o cdigo otimizado poderia ser: L0 if i 100 goto L2 i := j + i goto L0 L2 ... O nmero de otimizaes de cdigo realizadas por diferentes compiladores varia muito. Quanto mais otimizaes, mais tempo gasto nessa faze. Existem otimizaes simples que melhoram significativamente o tempo de execuo do programa objeto sem atrasar muito a compilao.
Gerao de cdigo

Tem como objetivos: produo de cdigo objeto, reserva de memria para constantes e variveis, seleo de registradores, etc. Um aspecto crtico da gerao de cdigo est relacionado cuidadosa atribuio dos registradores s variveis do programa. Nessa fase da compilao as propriedades da mquina-alvo tornam-se o fator principal. Exemplo 1: Para a expresso em C, a [index] = 4 + 2 precisamos decidir como armazenar inteiros para gerar o cdigo de indexao de matrizes. Uma sequncia de cdigo possvel para a expresso dada poderia ser: MOV R0, index // valor de ndex R0 MUL R0, 2 // dobra valor em R0 MOV R1, &a // endereo de a R1 ADD R1, R0 // adiciona R0 a R1 MOV *R1, 6 // constante 6 endereo em R1

Compiladores 9

&a o endereo de a, o endereo inicial da matriz. *R1 significa o endereamento indireto de registro, a ltima instruo armazena o valor 6 no endereo contido em R1. Nesse cdigo assumimos que a mquina efetua endereamento de bytes e que inteiros ocupam dois bytes de memria. No cdigo alvo so possveis diversas melhorias. Usar a instruo de deslocamento para substituir a multiplicao na segunda instruo Usar um modo de endereamento indexado para armazenar a matriz. Com essas duas otimizaes o cdigo-alvo fica assim: MOV R0, index // valor de ndex R0 SHL R0 // dobra valor em R0 MOV &a [R0], 6 // constante 6 endereo a + R0 Exemplo 2: Na atribuio position = initial + rate * 60 usando os registradores R1 e R2, o cdigo intermedirio poderia ser traduzido para o cdigo de mquina LDF R2, id3 // carrega o contedo do endereo id3 no registrador R2 MULF R2, R2, #60.0 // multiplica pela constante de ponto flutuante 60.0 LDF R1, id2 // move id2 para o registrador R1 ADDF R1, R1, R2 // soma o valor contido no registrador R1 com o valor previamente
calculado no registrador R2

STF

id1, R1 // o valor no registrador R1 armazenado no endereo id1 O F diz que a instruo manipula nmeros de ponto flutuante. O # significa que o valor 60.0 deve ser tratado como uma constante imediata. A gerao de cdigo ignorou a questo relativa alocao de espao na memria para os identificadores do programa fonte. A organizao de memria em tempo de execuo depende da linguagem sendo compilada. Decises sobre a alocao de espao podem ser tomadas em dois momentos: durante a gerao de cdigo intermedirio ou durante a gerao do cdigo. Exemplo 3: A partir do cdigo intermedirio otimizado para o comando while apresentando como exemplo, obter-se-ia o cdigo objeto final baseado na linguagem simblica de um microprocessador PC 8086. L0 MOV AX, i // move o contedo do endereo i para o registrador AX CMP AX, 100 // compara 100 com o contedo do registrador AX JGE L2 // faz um salto condicional para L2 MOV AX, j // move o contedo do endereo j para o registrador AX MOV BX, i // move o contedo do endereo i para o registrador BX ADD BX // adiciona o contedo do registrador BX MOV i, AX // move o contedo do registrador AX para o endereo i JMP L0 // faz um salto incondicional para L0 L2 ...

Exerccios
1. No contexto de implementao de linguagem de programao, d o significado dos seguintes termos: compilador, interpretador, montador e pr-compilador. 2. Aponte vantagens e desvantagens dos interpretadores em relao aos compiladores. 3. Explique o processo de compilao: fases e seu inter-relacionamento. 4. Dada a declarao em C a[i+1] = a[i] + 2

10 Introduo desenhe uma rvore de anlise sinttica e uma rvore sinttica para a expresso. 5. Por exemplo, o cdigo em C x = 4; y = x + 2; faa a otimizao.

Bibliografia
Compiladores: princpios, tcnicas e ferramentas Aho, Alfred. Lam, Monica. Sethi, Ravi. Ullman, Jeffrey D. So Paulo: Pearson Addison-Wesley, 2008. Compiladores: princpios e prticas Louden, Kenneth C. So Paulo: Pioneira Thomson Learning, 2004 Implementao de linguagens de programao: Compiladores Price, Ana. Toscani, Simo Porto Alegre: Bookman: Instituto de Informtica da UFRGS, 2008.

You might also like