Sie sind auf Seite 1von 95

Motivao

Conhecimento das estruturas e algortmos usados na implementao de linguagens: noes importantes sobre uso de memria, eficincia, etc. Aplicabilidade freqente na soluo de problemas que exigem alguma forma de traduo entre linguagens ou notaes. Implementao de linguagens para um domnio especfico. Geradores e analisadores de cdigo.

Motivao
A disciplina de compiladores faz uso de um grande nmero de conceitos estudados em outras disciplinas do curso: linguagens de programao, algortmos, linguagens formais, arquitetura, engenharia de software.

Compilador
Programa que l um programa escrito em uma linguagem (fonte) e o traduz para uma outra linguagem (destino), reportando erros quando eles ocorrem. As tcnicas bsicas de construo de compiladores podem ser usadas tambm para:
formatadores de texto interpretadores de queries (consultas a banco de dados)

Evoluo das Linguagens


Cronologicamente, as L. P.'s so classifcadas em cinco geraoes: (1a) linguagens de mquina; (2a) linguagens simblicas (Assembly); (3a) linguagens orientadas ao usurio (Fortran, Cobol, C, e declarativas como Lisp); (4a) linguagens orientadas aplicao (Excel, Visicalc) e (5a) linguagens de conhecimento inteligncia artificial.

Linguagens
Linguagem fonte: C, Pascal, Java, Fortran, etc. Linguagem destino: linguagem de mquina (assembler) de um processador, de uma mquina virtual (e.g. Java ou .NET), ou qualquer outra linguagem (e.g. C).

Processadores de Linguagens: Compilador

Programa fonte

Compilador
Programa destino

Execuo de um programa

entrada

Programa destino

sada

Processadores de Linguagens: Interpretador

Programa fonte Interpretador entrada sada

Compilador Hbrido
Programa fonte

Tradutor Mquina Virtual


(exemplo: Java Virtual Machine)

Programa intermedirio
entrada

sada

Sistema de processamento de uma linguagem


Programa fonte preprocessador Programa fonte modificado assembler

Cdigo objeto (relocvel)

compilador

Linker / Loader

Bibliotecas / cdigo objeto

Programa em assembler

Cdigo objeto (executvel)

Programas auxiliares do processo de compilao


Preprocessadores: processam macros, incluem de arquivos, suportam compilao condicional e extenso de linguagens. Assemblers: servem como uma pequena abstrao da arquitetura da mquinadestino. So na realidade um tradutor /compilador simples, de dois passos, que gera cdigo relocvel.

Programas auxiliares do processo de compilao (cont.)


Carregadores (loaders) e linkeditores (linkers)
Ajustam o cdigo relocvel, resolvem referncias externas.

Compilao: Anlise e Sntese


Anlise: quebra o cdigo fonte em suas partes, e cria uma representao intermediria do programa. Verifica erros e constri tabela de smbolos.

Sntese: Constroi o programa-destino a partir da representao intermediria.

Fases de um compilador
stream de caracteres Analisador lxico stream de tokens Analisador sinttico rvore sinttica Ger. de cdigo intermedirio representao intermediria Otimizador de cdigo

rvore sinttica
Analisador semntico

representao intermediria
Gerador de cdigo Cdigo de mquina

Anlise: front-end do compilador (at gerao de cdigo intermedirio) Sntese: back-end do compilador

Anlise do programa fonte


Anlise lxica l a seqencia de caracteres e a organiza como tokens sequencias de caracteres com algum significado Anlise sinttica agrupa caracteres ou tokens em uma estrutura hierrquica com algum significado Anlise semntica verifica se os componentes de um programa se encaixam de forma a ter um significado adequado.

Anlise lxica ou Scanning


L os caracteres de entrada e agrupa-os em sequencias chamadas lexemas. Para cada lexema o analisador lxico produz como sada um token da forma <nome do token, valor do atributo> que passado para a fase seguinte.

Anlise sinttica ou parsing


A partir dos tokens cria uma estrutura em rvore (rvore sinttica) que representa a estrutura gramatical do programa. Exemplo:

Anlise semntica
Verifica o programa em relao a possveis erros semnticos e guarda informaes adicionais Fundamentalmente, a anlise semntica trata os aspectos sensveis ao contexto da sintaxe das linguagens de programao. Por exemplo, no possvel representar em uma gramtica livre de contexto uma regra como Todo identificador deve ser declarado antes de ser usado", e a verificao de que essa regra foi aplicada cabe anlise semntica.

No existe uma fronteira definida entre o que deve ser tratado pelo analisador sinttico e o que deve ser tratado pelo analisador semntico, cabendo ao programador do compilador a escolha, segundo suas preferncias.

Exemplo: verificao de tipos


A expresso x = x + 3.0 est sintaticamente correta, mas pode estar semanticamente certa ou errada, dependendo do tipo de x.

Tabela de Smbolos
Estrutura de dados usada para guardar identificadores e informaes sobre eles:
alocao de memria, tipo do identificador, escopo (onde vlido no programa) se for um procedimento ou funo: nmero e tipo dos argumentos, forma de passagem dos parmetros e tipo do resultado.

Tabela de Smbolos
identificador 1 2 position initial tipo

rate

Cdigo intermedirio
Idealmente deve ser fcil de produzir e tambm de traduzir para a linguagem-destino. Na prtica, se est gerando cdigo para uma mquina abstrata. Por exemplo, Three-address-code: usa trs operandos por instruo, cada um como se fosse um registrador.

Otimizao de cdigo
Realiza transformaes no cdigo visando melhorar sua performance em aspectos de tempo de execuo, uso de memria, tamanho do cdigo executvel etc.

Gerao de cdigo
Realiza a alocao de registradores (se necessria) e a traduo do cdigo intermedirio para a linguagem-destino, normalmente de cdigo em linguagem assembly ou de cdigo em linguagem de mquina.

Organizando fases em passos


Fases: viso lgica de um compilador Em uma implementao as fases podem ser agrupadas em um ou mais passos Passos: nmero de vezes em que se passa pelo mesmo cdigo. Por exemplo, em um assembler so necessrios pelo menos dois passos.

Separao entre front-end e back-end para criao de mltiplos compiladores


Pascal Fortran Front-end

C
Front-end Front-end cdigo intermedirio

C#
Front-end

Back-end

x86

Separao entre front-end e back-end para criao de mltiplos compiladores


Pascal
Front-end cdigo intermedirio Back-end Back-end ARM x86 .NET Back-end MIPS Back-end

Separao entre front-end e back-end para criao de mltiplos compiladores


Pascal Fortran Front-end

C
Front-end Front-end cdigo intermedirio Back-end Back-end ARM x86 .NET Back-end

C#
Front-end

Back-end MIPS

Ferramentas para a construo de compiladores


Scanner generators, baseados em expresses regulares. Exemplo: lex Parser generators, baseados em gramticas livres de contexto. Exemplo: yacc Engenhos de traduo dirigida por sintaxe, geram rotinas para navegar na parse tree e gerar cdigo intermedirio Geradores de geradores de cdigo (template matching) Toolkits de construo de compiladores

Classificaes: Paradigma
Imperativo como Conceito de estado e comandos que mudam o estado C, C++, C#, Java Declarativo (e.g. funcional, lgico) o qu ML, Haskell, Prolog

A LINGUAGENS E SUAS REPRESENTAES

Smbolos e alfabetos
Um alfabeto um conjunto finito no vazio smbolos.
Apenas alfabetos finitos. Smbolos dependem da aplicao: {0, 1}, {a, b}, {program, begin, end, if, then, else, }

Uma cadeia de smbolos em um alfabeto uma funo s:[n] , com domnio [n], e com contradomnio .
Exemplo: para = {a, b, c}, a sequncia "abbc" se define como a funo s:[4] , representada por s(1) = a, s(2) = b, s(3) = b, s(4) = c

A concatenao das sequncias x e y a sequncia xy, ou xy, composta pelos smbolos de x, seguidos pelos smbolos de y, nessa ordem. Formalmente, dadas duas sequncias x:[m] e y:[n] , definimos a sequncia xy:[m+n] , por:
Naturalmente, |xy| = |x| + |y|. No caso n = 0, se trata da sequncia vazia .

o elemento neutro (identidade) da concatenao: x


= x = x.

Dado um alfabeto , uma linguagem em um conjunto de sequncias de smbolos de .

Assim, como * inclui todas as sequncias de smbolos de , incluindo , temos, com essa notao, que uma linguagem L qualquer em um subconjunto de *, ou seja, L *. Linguagens so conjuntos, portanto se L e M so linguagens em temos:
unio: L M = { x | x L ou x M } interseo: L M = { x | x L e x M } diferena: L - M = { x | x L e x M } complemento: L = * - L = { x * | x L }

E ainda a concatenao, que j foi definida para seqncia:


L M = { xy | x L e y M } A linguagem I = { } o elemento neutro (identidade) da concatenao de linguagens.

Gramticas
So compostas por regras de produo, ou regras de re-escrita, atravs das quais possvel obter todos os elementos da linguagem a partir de um smbolo inicial. Definimos uma gramtica G como sendo uma construo <N, , P, S>, onde
N um alfabeto de smbolos auxiliares, chamados de smbolos no terminais. o alfabeto no qual a linguagem definida, cujos elementos so os smbolos terminais P o conjunto de regras de re-escrita, chamadas simplesmente de regras ou produes, cuja notao habitual . S o smbolo inicial. Definirmos o vocabulrio de G, como sendo V = N . Ento P V* V*, correspondendo cada regra individual ao par de cadeias (, ).

Relao (deriva em um passo). Podemos definir a aplicao de uma regra atravs de uma relao: dizemos que see . * Deriva em zero ou mais passos, ou, simplesmente, deriva. Linguagem de uma gramtica G = <N, , P, S> definida por L(G) = { x * | S * x }. A hierarquia das gramticas segundo Chomsky:
Gramticas tipo 0: Sem restrio. Gramticas tipo 1: Sensveis ao contexto, ou gsc. Gramticas tipo 2: Livres de contexto, ou glc. Regras da forma A , onde A um smbolo no terminal, e uma sequncia qualquer de V*, possivelmente vazia. Gramticas tipo 3 (gramticas regulares). S podem ter regras dos trs tipos descritos a seguir:
A a B, onde A e B so no terminais, e a um terminal; A a, onde A um no terminal, e a um terminal; A , onde A um no terminal.

hierarquia de Chomsky

Especificao de uma linguagem


Foi dito que uma linguagem L qualquer subconjunto de sentenas sobre um alfabeto . Mas, qual subconjunto esse, como defini-lo? Uma gramtica um dispositivo formal usado para definir qual subconjunto de * forma determinada linguagem. A gramtica define uma estrutura sobre um alfabeto de forma a permitir que apenas determinadas combinaes de smbolos sejam consideradas sentenas. O que GRAMTICA? um sistema gerador de linguagens; um sistema de reescrita; uma maneira finita de descrever uma linguagem; um dispositivo formal usado para especificar de maneira finita e precisa uma linguagem infinita.

Front-end de um compilador
Programa fonte Analisador lxico tokens Parser Tabela de Smbolos

rvore sinttica
Ger. de cdigo intermedirio

Three-address code

Definio de uma linguagem


Linguagem = sintaxe + semntica Sintaxe = forma Semntica = significado

Definio de uma linguagem


Especificao da sintaxe:
gramtica livre de contexto, BNF (Backus-Naur Form)

Especificao da Semntica:
normalmente informal (textual) formal: uso de semntica operacional, denotacional, de aes, etc.

Exemplo: if-else
if ( expression ) statement else statement

Exemplo: if-else
if ( expression ) statement else statement stmt g if ( expr ) stmt else stmt

Gramtica Livre de Contexto


Um conjunto de tokens, smbolos terminais Um conjunto de smbolos no-terminais Um conjunto de produes, cada produo consiste de um no-terminal, uma seta, e uma sequencia de tokens e/ou no terminais Um no terminal designado como smbolo inicial

Exemplo 1
list g list + digit list g list - digit list g digit

digit g 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Exemplo 1a
list g list + digit | list - digit | digit

digit g 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Exemplo 2
call g id ( optparams ) optparams g params | params g params , param | param

Derivaes
Uma gramtica deriva strings a partir do seu smbolo inicial e repetidamente substituindo no-terminais pelo corpo de sua produo As sequencias de terminais produzidas desta forma formam a linguagem definida pela gramtica Exemplos: 9, 9 - 5, 9 - 5 + 2

Parsing
Problema de pegar uma string de terminais e verificar como deriv-la a partir do smbolo inicial da gramtica; caso no seja possvel, reportar erros de sintaxe.

Processo de procurar uma parse-tree para uma dada sequencia de terminais.

Parse Trees
Mostra graficamente como o smbolo inicial de uma gramtica deriva uma string da linguagem. Para uma produo A g XYZ
A X Y Z

Parse Trees
A raiz o smbolo inicial Cada folha um terminal ou Cada n interior um no-terminal Se A um no-terminal e X1, X2,...,Xn so labels de filhos deste n, tem que haver uma produo A g X1 X2 ... Xn

Exemplo
9 5 + 2
list
list digit digit list digit

Ambiguidade
Parse-tree gera uma string, mas uma string pode possuir vrias parse-trees, se a gramtica for ambgua. Soluo: usar sempre gramticas noambguas, ou gramticas ambguas com informaes adicionais sobre como resolver ambiguidades.

Ambiguidade - Exemplo
string g string + string | string - string |0|1|2|3|4|5|6|7|8|9

Exemplo: Duas parse trees


9 5 + 2
string string + string 2 string 9 5 2 string string

string
9

string
5

string

+ string

Associatividade de Operadores
+, , * e / so associativos esquerda, na maioria das linguagens de programao: 9 5 + 2 equivalente a (9-5)+2 Atribuio em C e exponenciao so associativos direita: a=b=c 2**3**4

Associatividade direita
right g letter = right | letter letter g a | b | | z

Precedncia de operadores
9+5*2 * tem maior precedncia do que + Usaremos dois no-terminais para representar os dois nveis de precedncia em expresses e um outro para gerar as unidades bsicas de expresses.

Precedncia de operadores
expr g expr + term | expr term | term term g term * factor | term / factor | factor factor g digit | ( expr ) digit g 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Exemplo
stmt g id = expression ; | if ( expression ) stmt | if ( expression ) stmt else stmt | while ( expression ) stmt | do stmt while ( expression ) ; | { stmt } stmts g stmts stmt |

Traduo dirigida por sintaxe


Traduo dirigida associa regras ou trechos de programa s produes de uma gramtica.

Exemplo
expr g expr1 + term

traduza expr1; traduza term; trate + ;

Conceito: Atributo
Um valor associado a um construtor do programa. Exemplos:
Tipo em uma expresso; Nmero de instrues geradas; Localizao da primeira instruo gerada por um construtor;

Conceito: Esquema de traduo (dirigida pela sintaxe)


Notao para associar trechos de programa a produes de uma gramtica Os trechos de programa so executados quando a produo usada durante a anlise sinttica O resultado da execuo desses trechos de programa, na ordem criada pela anlise sinttica, produz a traduo desejada do programa fonte

Parsing
Processo de determinar como uma string de terminais pode ser gerada por uma gramtica Conceitualmente a construo da parse tree Mas a parse tree pode no ser efetivamente construda durante a compilao.

Top-down ou bottom-up parsers


Refere-se ordem em que os ns da parse tree so criados. Top-down: mais fceis de escrever mo Bottom-up: suportam uma classe maior de gramticas e de esquemas de traduo; so freqentemente usados/gerados pelas ferramentas de gerao automtica de parsers.

Anlise Lxica
Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como sada uma seqncia de tokens que o parser vai usar para anlise sinttica.

Analisador lxico
Programa fonte
token

Analisador lxico
getNextToken

parser

tabela de smbolos

Construindo um analisador lxico


Especificar tokens e lexemas da linguagem Implementar (ou gerar atravs de ferramenta) o analisador a partir da especificao

Outras possveis tarefas do analisador lxico


Tratamento de espaos em branco e comentrios Tratamento de mensagens de erro (localizao/impresso) Tratamento de macros

Organizao
s vezes dividido em
scanning remoo de comentrios e espaos em branco duplicados Anlise lxica propriamente dita parte mais complexa, onde o scanner produz a sequencia de tokens

Analisador lxico x Parser


Design mais simples misturar anlise lxica com sinttica torna o parser bem mais complicado Eficincia separao possibilita construir processadores lxicos e sintticos mais eficientes. Portabilidade variaes de dispositivos podem ficar restritas ao analisador lxico.

Tokens, Padres e Lexemas


Tokens: par com o nome do token e atributos opcionais. Padro: descrio da forma dos lexemas que um token pode ter Lexema: sequencia de caracteres que casam com o padro de um token. Uma instncia de um token.

Tokens, padres e lexemas


Existem conjuntos de strings na entrada que geram o mesmo token. Elas so descritas por padres associados ao token O padro casa cada string do conjunto Um lexema uma seqncia de caracteres do programa fonte que casa com um padro de um token. Tokens so smbolos terminais da linguagem.

Tokens, padres e lexemas


Tokens normalmente so Palavras-chave, operadores, identificadores, constantes, strings literais e smbolos de pontuao, como parenteses e vrgulas. Padres normalmente so especificados por expresses regulares. Variaes de expresses regulares so usadas em vrios outros contextos:
Linguagens de programao: sed, awk, perl Shells de sistemas operacionais: sh, csh, command

Tokens, padres e lexemas


token
if

exemplo
if

descrio
Caracteres i, f

else
comp id

else
<,<=,=,<>,> pi, count, D2

Caracteres e, l, s, e
< ou <= ou Letra seguida de letras e/ou dgitos Constante numrica Quaisquer caracteres entre exceto e

num
literal

3.1416, 0, 6.02E23
core dumped

Dificuldades na implementao de um analisador lxico


Linguagens que requerem determinados construtores em posies (colunas) especficas da linha de entrada (e.g. Fortran). Tratamento de espaos em branco. Ausncia de palavras reservadas.

Atributos de um token
Ao reconhecer um token num relevante saber se seu valor zero ou um, por exemplo. Geralmente associado a um token existe um atributo. Uso da tabela de smbolos para guardar informaes auxiliares sobre tokens.

Atributos de um token - Exemplo


E = M * C ** 2 <id, apontador p/posio de E na tabela de smbolos> <assign_op,> <id, apontador p/posio de M na tabela de smbolos> <mult_op,> <id, apontador p/posio de C na tabela de smbolos> <exp_op,> <num, valor 2>

Erros de anlise lxica


Relativamente raros. Geralmente o analisador tenta recuperar do erro, ignorando caracteres.

Opes de Implementao de um analisador lxico


Uso de um gerador de analisadores lxicos, como lex ou flex, que produzem um analisador lxico a partir de uma especificao em expresses regulares. Escrever o analisador em uma linguagem de programao convencional, usando as facilidades de E/S da linguagem para ler a entrada.

Especificao de Tokens
Baseado em Teoria de Linguagens: Alfabetos, strings e linguagens Operaes sobre linguagens Exemplo: seja L o conjunto (de letras) {A,B,,Z,a,b,,z} e D o conjunto (de dgitos) {0,1,,9}.

Operaes sobre linguagens Exemplo


LD LD conjunto composto de letras e dgitos conjunto de strings compostas de letras seguidas de dgitos L4 conjunto de todas as strings com 4 letras L* conjunto de todas as strings de letras, inclusive a string vazia D+ conjunto de strings de um ou mais dgitos. L(L D)* conjunto de strings que comeam com letra e seguem com letra ou dgito

Expresses regulares
Permitem a definio de linguagens a partir de definies de expresses regulares mais simples. Exemplos:
Identificadores em pascal: letter (letter | digit) * a|b (a | b) (a | b) a* (a|b)* a | a*b

Exemplo - Pascal
letter gA | B | | Z | a | b | | z digit g0 | 1 | | 9 id gletter (letter | digit)* digits gdigit digit* opt_fraction g. digits | opt_exponent g(E (+|-|) digits) | num gdigits opt_fraction opt_exponent

Abreviaes
+ ? [] uma ou mais instncias. Zero ou uma instncia classes de caracteres, ex: [A-Za-z][A-Za-z0-9]*

Reconhecimento de Tokens
Gerar diagramas de transio e depois implementar uma mquina de estados. Implentar autmatos finitos determinsticos e nodeterminsticos.

Lex
Linguagem (e compilador) para especificar analisadores lxicos.

Organizao
Programa fonte
lex.l

Compilador lex (lex ou flex)

Lex.yy.c

lex.yy.c

C compiler

a.out

Entrada

a.out

Sequencia de tokens

Programas Lex - estrutura


Declaraes variveis, constantes, defs.regulares %% regras de traduo expr.regulares e aes em C Padro { Ao } %% procedimentos auxiliares

Lex - exemplo
%{ /* definio de constantes LT, LE, EQ, NE,*/ %} delim [ \t\n] ws {delim}+ letter [A-Za-z] digit [0-9] id {letter}({letter}|{digit})* number {digit}+(\.{digit}+)? (E[+\-]?{digit}+)? %%

Lex exemplo (cont.)


{ws} if then else {id} {number} {/* no action and no return */} {return(IF);} {return(THEN);} {return(ELSE);} {yylval=install_id();return(ID);} {yylval=install_num(); return(NUMBER);} {yylval = LT; return(RELOP);} {yylval = LE; return(RELOP);}

< <= %%

Lex exemplo (cont.)


int install_id() { Copia lexema para a tabela de smbolos. Primeiro caracter do lexema apontado pela varivel yytext e o comprimento definido pela varivel yyleng. } Int install_num() { }

Lex - implementao
Transforma o programa de entrada em um programa em C que implementa um Autmato Finito

NFA Nodeterministic Finite Automata DFA Deterministic Finite Automata Reconhecem a mesma linguagem, linguagens regulares, expressas por expresses regulares

Das könnte Ihnen auch gefallen