Você está na página 1de 58

Compiladores2012 , Apresentao

0-1

UNIVERSIDADE TCNICA DE LISBOA


INSTITUTO SUPERIOR TCNICO

Objetivos
Compreender e denir informalmente uma linguagem livre de contexto. Desenvolver a capacidade de resolver problemas que obrigam traduo entre linguagens ou notaes, utilizando os mtodos de anlise (front-end) e sntese (back-end) mais usados pelos compiladores. Conhecimento dos processos, ferramentas, algoritmos e estruturas de dados utilizados na manipulao de linguagens, sejam de programao ou no. Experimentao de produo de software na realizao de um compilador para uma linguagem de programao simples. A disciplina faz uso de grande nmero de conceitos lecionados anteriormente: fundamentos de programao, sistemas digitais, teoria da computao, arquitetura de computadores, algoritmos e estruturas de dados, sistemas operativos, programao por objetos.

COMPILADORES
Pedro Reis dos Santos
Departamento de Engenharia Informtica
14 de fevereiro de 2012

Compiladores2012 , Apresentao

0-2

Compiladores2012 , Apresentao

0-3

Resultados
Compreender as linguagens, de programao ou no, nomeadamente a sua estrutura (sintaxe), semntica e limitaes. [FP, PO] Assimilar as tcnicas de anlise de linguagens, ou qualquer formato de dados com estrutura predenida. [TC, AED] Tomar conhecimento das estruturas de dados e tcnicas envolvidas na gerao de cdigo mquina. [SD, AC, SO]

Gramticas
Uma linguagem a expresso de pensamentos por frases e palavras. Uma gramtica de uma linguagem um conjunto de regras que permitem denir a linguagem. Pode haver mais de uma gramtica para a mesma linguagem: gramticas equivalentes. Hierarquia das gramticas propostas por Noam Chomsky em 1956: tipo 0: Sem restries (portugus, por exemplo) tipo 1: Sensveis ao contexto tipo 2: Livres de contexto tipo 3: Regulares

Compiladores2012 , Apresentao

0-4

Compiladores2012 , Apresentao

0-5

Compiladores
Compilador: programa que l um programa descrito numa linguagem (fonte) e o traduz para outra linguagem (destino), reportando os erros quando eles ocorrem. Processo de compilao: designa o conjunto de tarefas que o compilador deve realizar para poder gerar uma linguagem a partir de outra. Fases do processo de compilao: anlise (lexical, sinttica e semntica) e sntese (gerao e otimizao de cdigo). Fase de anlise: quebra o cdigo fonte nas suas partes, e cria uma representao intermdia do programa (tabela de smbolos e rvore de parsing). Fase de sntese: constroi o programa-destino a partir de uma representao intermdia (rvore, DAG ou dirigido pela sintaxe).

Ambiente de desenvolvimento
O ambiente de desenvolvimento utilizado na disciplina de Compiladores utiliza o sistema operativo linux em processadores i386 (e derivados Pentium ...). O compilador desenvolvido em C++. Biblioteca de runtime cdigo i386, podendo ser escrita em C, C++ ou a linguagem de projeto se o compilador j estiver operacional. A escolha da linguagem a usar deve ter em conta a experincia de programao em cada uma das linguagens e as caractersticas especcas de cada linguagem. Existe suporte para desenvolvimento em Windows mas a avaliao nal do projeto
efetuada em linux.

Compiladores2012 , Apresentao

0-6

Compiladores2012 , Apresentao

0-7

Ferramentas de desenvolvimento
Bsicas: editores de texto (vi/emacs), linguagem de comando (sh/csh), compilador de C++ (g++) ou C (gcc). Depurador de cdigo ou debugger: gdb, ddd. Controlo de verses: cvs. Controlo de conguraes: gmake. Assembler (gerao de cdigo relocatvel): nasm. Edio de cheiros objeto (cdigo relocatvel): ld, ar. Manipulao de cheiros objeto: nm, size, strip, strings, od, objdump, ... Monitores (debug e otimizao): strace, gprof.

Qualidade do cdigo
Os nomes das funes e variveis devem ser autoexplicativos. Quando o cdigo e respetivos comentrios discordam, provavelmente esto ambos errados - Norm Schreyer A legibilidade mais importante que a ecincia, nmero de linhas, etc.
int i;main(){for(;i["]<i;++i){--i;}"];read(---,i+++"hell\ o, world!\n",///));}read(j,i,p){write(j/p+p,i---j,i/i);} Dishonorable mention, Obfuscated C Code Contest, 1984. Author requested anonymity.

As rotinas de biblioteca utilizadas devem existir nas normas: ANSI C (ANSI X3.159-1989), ISO C99 (ISO/IEC 9899:1999) ou POSIX (POSIX 1003.1). O C combina o poder do assembly com a portabilidade do assembly - Bill Thacker alegadamente O ambiente de trabalho linux-elf-i386, logo as linhas no terminam em CR-LF nem os cheiros em Z sem CR, por exemplo.

Compiladores2012 , Apresentao

0-8

Compiladores2012 , Apresentao

0-9

Programa
Ambiente de desenvolvimento: ferramentas. Linguagens regulares e anlise lexical. Linguagens livres de contexto e gramticas atributivas. Anlise sinttica: descendente e ascendente. Anlise semntica: esttica e dinmica. Gerao de cdigo: intermdio e nal. Seleo e escalonamento de instrues. Reserva de registos. Otimizao de cdigo: anlise de uxo, otimizao local e global.

Avaliao
Informao: pgina da disciplina no fnix
no se tiram dvidas de matria por mail.

Avaliao: 40% projeto e 60% exame. Terica (min. 9,5): 2 testes (24 maro e 4 junho) + repescagem (29 de junho) Projeto (min. 9,5): em grupos de 2 elementos, com teste prtico individual. 2 entregas no fnix (16 abril e 21 maio) e teste prtico (22 maio).
proj=min(cod;pra)+sqrt(diff(cod;pra)) onde cod=(p1+p2+2*docente)/4. acesso ao teste prtico tem nota mnima de 8 valores.

Aulas prticas: realizao pelos alunos de exerccios de exame, com acompanhamento do docente.
poca especial (40% proj e 60% exame) tem projeto especco.

Compiladores2012 , Apresentao

0-10

Compiladores2012 , Apresentao

0-11

Projeto
Manual de Referncia descreve a linguagem. Enunciado do Projeto descreve o contedo de cada entrega e o processo para o produzir. Entregas feitas no fnix at s 12h (hora do servidor): intermdia: lex e yacc, at 16 de abril. nal: semntica e gerao de cdigo, at 21 de maio. Testes prticos a 22 de maio. Repetentes so obrigados a repetir toda a avaliao, incluindo o projeto.

Bibliograa
Compiladores: da teoria prtica, Pedro Reis dos Santos, IST 2006 Compiladores: ferramentas de desenvolvimento, Pedro Reis dos Santos, 4a edio,
IST 2006

Compilers: Principles, Techniques, and Tools, Alfred V. Aho, Ravi Sethi, Jeffrey
D. Ullman, Addison-Wesley, 1986, 0-201-10088-1

Processadores de linguagens: da concepo implementao, Rui Gustavo


Crespo, IST press, 2a edio, 2001, 972-8469-18-7

lex & yacc,

John R. Levine, Tony Mason, Doug Brown, OReilly & Associates, 2a edio, 1992, 1-56592-000-7

Compiladores2012 , Introduo

1-1

Compiladores2012 , Introduo

1-2

Introduo
Compilador: programa que l um programa descrito numa linguagem (fonte) e o traduz para outra linguagem (destino), reportando os erros quando eles ocorrem. Processo de compilao: designa o conjunto de tarefas que o compilador deve realizar para poder gerar uma linguagem a partir de outra. Fases do processo de compilao: anlise (lexical, sinttica e semntica) e sntese (gerao e otimizao de cdigo). Fase de anlise: quebra o cdigo fonte nas suas partes, e cria uma representao intermdia do programa. Fase de sntese: constri o programa-destino a partir de uma representao intermdia.

Compilador
Vericador: verica se o formato de entrada obedece a um determinado formato. A resposta , em geral, sim ou no. Exemplos: syntax highlighting em editores de texto, vericao de normas. Interpretador: executa o cdigo, depois de o vericar, produzindo a partir de uma entrada de dados (distinta da entrada de cdigo) um conjunto de resultados. O processo permite, segundo o cdigo, executar clculos, atualizar bases de dados, construir estruturas de dados, ... Exemplos: emuladores, interpretadores e simuladores. Tradutor: traduz uma determinada linguagem de entrada numa linguagem de sada. Quer a linguagem de entrada como a de sada podem ser de nvel mquina, assembly ou de alto nvel. Exemplos: compiladores, beauty printers.

Compiladores2012 , Introduo

1-3

Compiladores2012 , Introduo

1-4

Gerao de um compilador
gcc X.c X gcc
caracteres

Processo de compilao
analisador lexical tokens analisador sintctico

cdigo fonte pilha/rvore

tabela de

c2x

smbolos

analisador semntico

X.x X x
sequencial pilha/rvore

X.x Xx
cdigo mquina

(assembly)

cdigo final e optimizador

sequencial (C3E ou stack)

cdigo intermdio

Compiladores2012 , Introduo

1-5

Compiladores2012 , Introduo

1-6

Anlise lexical
Agrupa os carateres em smbolos e verica se pertencem linguagem: palavras reservadas, identicadores, literais, operadores, delimitadores, comentrios e separadores. int { printf return } Erro lexical (ortogrco): A bolaxa comeu uma Joo ( 0 Hello world\n ; ) ; main ( )

Anlise sinttica

NADA PERCEBER SEM ISTO TENTAR LER A ESTOU QUE TEMPO ALGUM J H

Compiladores2012 , Introduo

1-7

Compiladores2012 , Introduo

1-8

Anlise sinttica
Verica se as sequncias de smbolos so vlidas na linguagem. O emparelhamento das regras resulta numa rvore sinttica:
tipo identificador delimitador argumentos delimitador delimitador funo declaraes corpo keyword main ( int

Anlise semntica

identificador ) delimitador { argumentos call argumento ) string "Hello world\n" ( printf

instruo delimitador

delimitador ; keyword

instrues return inteiro 0 delimitador } instruo delimitador retorno expresso ;

Erro sinttico: A bolacha comeu uma Joo

Compiladores2012 , Introduo

1-9

Compiladores2012 , Introduo

1-10

Anlise semntica
Verica se as entidades podem desempenhar as funes pretendidas e determina como as devem desempenhar. manipulao de identicadores: visibilidade, alcance, tabelas de smbolos Tipicao (vericao de tipos): equivalncia, subtipicao, polimorsmo. rvores de ativao (chamadas a procedimentos): gesto de memria, registos de ativao (stack frames), ligao de nomes (binding). Por exemplo, em C pode incluir: break fora de ciclos, return em funes void, nmero ou tipo dos argumentos das funes incorreto, retirar endereo de constantes, atribuies a constantes, utilizao de variveis no declaradas, redenio de funes ou variveis, etc. Erro semntico: A bolacha comeu o Joo

Tratamento e recuperao de erros


O objetivo a correo: no interessa quanto tempo se gasta para obter uma resposta a um erro! Todos os erros no texto so sintticos, mas muitos erros no podem ser tratados por linguagens independentes do contexto. Erros no detectveis, ou dicilmente detectveis, com a tecnologia atual so processados pela anlise semntica esttica. Tipos de respostas a um erro: inaceitveis (incorretas ou de pouca utilidade) e aceitveis. Tratamento de erros atravs da insero na gramtica de regras especcas.

Compiladores2012 , Introduo

1-11

Compiladores2012 , Introduo

1-12

Interpretao
Processamento das instrues de um programa por uma aplicao e no pelo processador da mquina. A cada primitiva da linguagem corresponde um pedao de cdigo no interpretador. Interpretao pode ser: direta, linha a linha, do texto do programa. dirigida pela sintaxe (em gramticas simples). dirigida pela rvore sinttica (100x a 1000x mais lento). execuo de cdigo para mquina virtual ou threading (10x a 100x). Cdigo intermdio para processadores ideais, com zero ou innitos registos, pode ser interpretado ou usado para gerar cdigo nal.

Gerao de cdigo
Produo de cdigo para um processador especco, tendo em conta as suas caractersticas particulares. Tipos de processadores podem ser: Stack machines: B5000, HP-3000 ou mquinas virtuais Java, e .net. Accumulator machines: PDP-9, M6809, 68HC11. Load-store machines (RISC): ARM, RS/6000, MIPS-R, HP-PA, SPARC. Memory machines (CISC): Register-memory architecture: i80x86, IBM-RT, M68k, IBM360. Memory-memory architecture: VAX, PDP-11. Compilao JIT a partir de um formato intermdio ou compilao object-code a partir de cdigo nal.

Compiladores2012 , Introduo

1-13

Compiladores2012 , Introduo

1-14

Cdigo i386 assembly


Cdigo em assembly (formato nasm) do hello world:
segment .rodata $str segment .text extern printf global main main: push call add mov ret db hello world,10,0

Cdigo i386 objeto


Resultado no cheiro objeto (binrio):
Disassembly of section 00000000 <str>: 0: 68 65 6c 6c 6f Disassembly of section 00000000 <main>: 0: 68 00 00 00 00 5: e8 fc ff ff ff a: 81 c4 04 00 00 10: b8 00 00 00 00 15: c3 .rodata: (13 bytes)

20 77 6f 72 6c 64 0a 00 .text: (22 bytes) push call add mov ret $0x0 <str> 6 <printf> $0x4,%esp $0x0,%eax

dword $str printf esp, 4 eax, 0

00

Compiladores2012 , Introduo

1-15

Compiladores2012 , Introduo

1-16

Otimizao de cdigo
preservar o signicado do programa original (controlabilidade e observabilidade). em mdia, deve melhorar visivelmente o tempo de execuo, uso da memria ou espao ocupado pelo programa. deve ter uma boa relao custo benefcio. processo: anlise do uxo de controlo, anlise do uxo de dados, transformaes, ... otimizaes: alto nvel (programador), local, peephole, global.

Cdigo i386 otimizado


Resultado no cheiro objeto otimizado para espao:
Disassembly of section .rodata: (13 bytes) 00000000 <str>: 0: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 Disassembly of section .text: (14 bytes) 00000000 <main>: 0: 68 00 00 00 00 push $0x0 <str> 5: e8 fc ff ff ff call 6 <printf> a: 58 pop %eax b: 31 c0 xor %eax,%eax d: c3 ret

Clocks (80C386): push imm (3), pop reg (5), call imm (7), ret (11), add imm (3), xor reg (2). Ocupa menos 8 bytes mas gasta mais 2 ciclos de relgio (mov vs. pop).

Compiladores2012 , Introduo

1-17

Compiladores2012 , Introduo

1-18

Desenvolvimento de compiladores de compiladores


Compiladores de compiladores so ferramentas em que so elas que geram o cdigo do compilador (C/C++). O programador escreve uma descrio de mais alto nvel. Analisadores lxicos: lex, Jlex, ex , ... Analisadores sintticos: yacc, Jcup, bison, byacc , precc, antlr, ... Avaliadores de atributos: ox, rie, ... Seleco de instrues: iburg, pburg , lburg, ...

Projeto de Compiladores em C
compilador compilao de um exemplo

exemplo.lang

lang.l lang.y code.c


node.c node.h tabid.c tabid.h postfix.h

flex l byacc d gcc c gcc c gcc c

lex.yy.c y.yab.c y.tab.h

gcc c gcc c

lex.yy.o y.tab.o

gcc lang

code.o node.o exemplo.asm tabid.o nasm felf exemplo.o

lib.asm linux.asm sys.asm real.o

nasm felf nasm felf nasm felf gcc c

lib.o linux.o sys.o funcs.o

ar liblang.a ld exemplo

funcs.c
biblioteca de runtime

dados
execuo de um exemplo

resultados

Compiladores2012 , Introduo

1-19

Compiladores2012 , Ferramentas de desenvolvimento

2-1

Compilador Orientado por Objetos

Controlo de verses
Mantm as diversas verses de um cheiro, numa estrutura em rvore, guardando apenas as diferenas entre verses consecutivas.

Node

Compiler *

Tabid

Mantm uma histria dessas alteraes, ligando-as ao autor, data e respetiva justicao. Permite linhas de desenvolvimento paralelas, podendo ser fundidas em determinada altura.
I386

String Unary Var Uminus Ternary Ifelse

Int List Binary While Add

Real

Interp Compact 1

Postfix

1 1 Parse

Debug Yylex Sparc

Mais de um utilizador pode modicar a mesma verso: deteta conictos e dispe de mecanismos para os eliminar (automticos e manuais). Permite a identicao automtica dos cheiros: data, verso, autor, ... Cada utilizador tem uma rea de trabalho (sand-box) a partir da qual faz check-out e check-in, de e para o repositrio (ou base de dados).

Compiladores2012 , Ferramentas de desenvolvimento

2-2

Compiladores2012 , Ferramentas de desenvolvimento

2-3

Sistemas de controlo de verses


Entidade manipulada: Ficheiro: cada cheiro manipulado individualmente pelo utilizador (RCS). Projeto: o utilizador manipula projetos completos (CVS). Controlo de acesso: Pessimista: necessrio reservar o acesso para escrita no check-out (RCS). Otimista: todas as cpias so modicveis, os conictos so resolvidos no check-in (CVS).
usar o projecto cvs checkout cvs import cvs init

CVS
criar repositrio ( start here ) criar um novo projecto gerar diferenas

editar compilar ....

cvs rdiff

cvs add cvs commit cvs delete

Interao com o sistema de controlo de conguraes: Direto: o controlo de conguraes gere as verses (RCS). Inverso: o controlo de verses gere as conguraes (CVS).
cvs release

cvs update

cvs export projecto sem ficheiros CVS

cvs tag

Compiladores2012 , Ferramentas de desenvolvimento

2-4

Compiladores2012 , Ferramentas de desenvolvimento

2-5

Controlo de conguraes
Controla e automatiza a produo de cheiros gerveis mecanicamente: baseado em regras simples. Regra: se b gerado a partir de a, ento quando a modicado b tem de ser gerado. O controlo efetuado por datas de modicao (mtime): as datas mostradas no ls -l.
fonte compilador de compiladores

Grafo de dependncias
* .l
compact.l

* .y
compact.y

* x

ficheiro sob o controlo de verses (editado pelo utilizador) ficheiro sob o controlo de configuraes (gerado pelo make)

*
declaraes

x .h
compact.h y.tab.h

* .h
emit.h

* .h
nasm.h

* .h
stack.h

.h

x .c
lex.yy.c

x .c
y.tab.c

* .c
code.c

* .c
emit.c

Uma congurao uma receita (Makefile) onde se indica quem depende de quem, e como fazer quando as dependncias falham. O processo de desenvolvimento, uma vez construda a congurao, resume-se a: pensar editar make testar.
objecto

x .o
lex.yy.o

x .o
y.tab.o

x .o
code.o

x .o
emit.o

x
executvel

a.out
compact

Compiladores2012 , Ferramentas de desenvolvimento

2-6

Compiladores2012 , Ferramentas de desenvolvimento

2-7

Regras
Componentes de uma regra: objetivo : o que se pretende fazer (make), pode no ser um cheiro. dependente : de quem depende o objetivo, devendo os comandos ser executados se a sua data for posterior ao objetivo. operao : sequncia de comandos a ser executados quando a regra ativada. Sintaxe da regra: objetivo: [ dependentes... [ ; operaes... ] ] ou numa notao mais legvel: objetivo : dependente-1 dependente-2 ... dependente-N operao-1 operao-2 ... operao-N

Denies
Uma denio uma diretiva de substituio, no uma atribuio segundo o modelo de von-Newmann: ID = valores A substituio efetuada com $(ID) ou ${ID}, exceto se for uma nica letra $ID. Variveis de ambiente do shell so acessveis dentro da Makele. As denies dinmicas so relativas regra onde se incluem: $<, $?, $@, $, $ , $+, etc. A substituio de uma denio segue a ordem: linha de comando, makele, variveis de ambiente, predenies. Denies com padres: $(var:b1%s1=b2%s2) substitui b1%s1 por b2%s2 em var, onde % representa zero ou mais carateres.

Compiladores2012 , Ferramentas de desenvolvimento

2-8

Compiladores2012 , Ferramentas de desenvolvimento

2-9

Regras implcitas
Um regra implcita estabelece uma dependncia entre conjuntos de cheiros, no entre cheiros individuais. Regras implcitas por extenso: .cpt.asm: ; compact $< > $@ Regras implcitas por padres: % : %.asm ; nasm -felf $< ; ld $.asm -o $@ Ordem de emparelhamento das regras: explcitas, implcitas na Makele, implcitas predenidas. Em caso de conito no emparelhamento, ou quando se introduzem novos suxos, make usa a ordem de suxos no pseudo-objetivo .SUFFIXES: .SUFFIXES: .cpt .c .p .f .asm .s .o

Makele
Linhas podem ser continuadas se terminarem com \. Comentrios iniciam-se com # e terminam no m da linha. regras sem dependentes executam sempre que ativadas. O objetivo principal a regra chamada all, ou a primeira regra no implcita do cheiro, caso no exista a regra all. YFLAGS=-d LEX=flex -l OBJ=gram.o scan.o code.o emit.o compiler: $(OBJ) $(LINK.c) -o $@ $^ scan.o: gram.y $(OBJ): defs.h

Compiladores2012 , Ferramentas de desenvolvimento

2-10

Compiladores2012 , Ferramentas de desenvolvimento

2-11

Compilador de C
preprocessador compilador [gcc S]

gcc

.c
(cpp) fonte

.i
(gcc) [gcc E] (as)

.s

assembly

[gcc E]
assemblador

[gcc S] compilador (cc1) assemblador (as)

[gcc c] loader (ld)

[gcc o] execuo (a.out) a.out executvel proc

preprocessador
.h
declaraes fich objecto

.o
[gcc c]

(cpp)

.c
[gcc o]

.i
prprocessado

.s
assembly

.o
fich objecto

.c

.o

arquivador

fonte
(a.out) proc execuo

(ar)

.a
bib esttica

loader a.out (ld) executvel

.c

.o

.a .h
bib esttica

.so
bib dinmica

.c

.o

loader (ld)

declaraes
.so
bib dinmica

.c

.o

Compiladores2012 , Ferramentas de desenvolvimento

2-12

Compiladores2012 , Ferramentas de desenvolvimento

2-13

Depurao de cdigo
debugger (adb/gdb): execuo controlada, passo a passo, permitindo inspecionar as instrues mquina executadas, bem como ler e modicar valores em posies de memria (dados). debugger simblico (gdb): debugger onde as instrues so as linhas do cheiro fonte e as variveis so referidas por nome. Programas monitores: programas que permitem observar o comportamento de outros sem interferir (supostamente) no seu funcionamento. trace (strace): intercetor de chamadas ao sistema. time: tempo de execuo e recursos do sistema operativo. prof (gprof): numero de chamadas e tempo gasto por rotina do programa.

Objetos e executveis
Um cheiro objeto relocatvel o resultado de uma compilao onde os endereos dos smbolos so relativos origem do segmento. Um editor de ligaes (linker, designado ld em UNIX) permite combinar objetos relocatveis resolvendo os smbolos comuns. Um objeto relocatvel pode ser criado atravs de ligao de diversos outros objetos relocatveis, resolvendo os smbolos comuns. [ld -r ] Um executvel um cheiro, com um ponto de entrada, sem smbolos indenidos e no relocatvel (endereos absolutos). Um executvel com ligaes estticas contm o cdigo de todas as funes que necessita. [ld -Bstatic ]

Compiladores2012 , Ferramentas de desenvolvimento

2-14

Compiladores2012 , expresses regulares

3-1

Bibliotecas
Uma biblioteca (esttica) uma coleo de cheiro objetos relocatveis, mantidos independentemente. [ar t libZ.a ] Uma biblioteca dinmica um objeto no relocatvel com uma tabela de smbolos dinmica. [ld -E -shared ] Um executvel que use bibliotecas dinmicas no as inclui, apenas as refere. No incio da execuo as bibliotecas so carregadas logo aps o executvel. Uma biblioteca dinmica pode referir smbolos globais do executvel em que se integra. [ld -E -Bsymbolic -shared ] Um executvel pode ter a capacidade de carregar bibliotecas dinmicas durante a execuo, se tiver uma tabela de smbolos dinmica. [ld -E ] ( ou [gcc -rdynamic -ldl ] )

Linguagens regulares
alfabeto: conjunto nito de smbolos, designados por palavras. frase: sequncia nita de palavras de um dado alfabeto. sintaxe: conjunto de regras que delimita o subconjunto de frases constituintes de uma linguagem. linguagem regular: descrita por uma expresso regular. expresso regular: dene uma linguagem com base nas regras:
uma expresso regular que dene a linguagem vazia. uma expresso regular que dene a linguagem que consiste na frase nula {}. um smbolo do alfabeto um expresso regular que dene a linguagem formada pela frase constituda por esse smbolo. um conjunto de operadores sobre expresses regulares.

Compiladores2012 , expresses regulares

3-2

Compiladores2012 , expresses regulares

3-3

Operadores das expresses regulares


Uma expresso regular pode ser formada pelos seguintes operadores, considerando duas expresses regulares p, q: escolha: designado por p|q comutativo e associativo, representando a unio das expresses regulares originais. concatenao: designado por p q associativo e distributivo em realo escolha e mais prioritrio que a escolha. elemento neutro na concatenao. fecho de Kleene: designado por p idempotente ( p = p ) e mais prioritrio que a concatenao e representa o conjunto de frases constitudas por zero ou mais repeties das frases de p. Alm disso p = (p|). parnteses: permite alterar a prioridade dos operadores anteriores.

Extenses aos operadores das expresses regulares


opo: designado por p? designa zero ou uma ocorrncias de p. equivalente a p|. fecho transitivo: designado por p+ designa uma ou mais ocorrncias de p. p+ equivalente a p p, e p equivalente a p + |. parnteses retos: designado por [pq] ou [p q] designam p|q e os smbolos de ordem entre p e q (inclusiv), respetivamente.

Compiladores2012 , expresses regulares

3-4

Compiladores2012 , expresses regulares

3-5

Diagrama de transio
O reconhecimento de linguagens regulares, frases geradas por expresses regulares, pode ser modelado por autmatos nitos. Um autmato nito pode ser representado por um diagrama de transio: um conjunto de estados, representados por crculos. transies entre estados representadas por setas etiquetadas por smbolos de entrada. um ou mais estados nais, representados por crculos duplos concentricos. um estado inicial, indicado por uma seta sem origem em outro estado.

Autmato nito no determinista: AFND


Num autmato nito no determinista onde podem existir transies sem smbolo de entrada, sendo etiquetadas por . Num AFND pode existir mais de uma sequncia de transies que permita atingir um estado nal a partir do estado inicial. A procura de soluo num AFND no determinista, pelo que pode ser necessrio recuar algumas transies para procurar alternativas ( backtracking ). A construo de um AFND a partir de uma expresso regular algoritmica: algoritmo de Thompson.

Compiladores2012 , expresses regulares

3-6

Compiladores2012 , expresses regulares

3-7

Algoritmo de Thompson
a > smbolo a ou

Exemplo de AFND
Autmato nito no determinista construdo segundo o algoritmo de Thompson para a expresso regular (a|b) (ab|ba):
a

N(a)

N(a) > escolha N(a|b) i

3 8


N(b)

2 0

10


4 b 5


11 b 12 a

14

13

> concatenao

N(ab)

N(a)

N(b)

> fecho de Kleene N(a*) i

N(a)

Compiladores2012 , expresses regulares

3-8

Compiladores2012 , expresses regulares

3-9

Autmato nito determinista: AFD


Num autmato nito determinista no podem existir transies vazias ( etiquetadas por ). Em cada estado existe, no mximo, uma s transio etiquetada com determinado smbolo de entrada. Num AFD s existe uma sequncia de transies que permite atingir um estado nal a partir do estado inicial. A construo de um AFD a partir de um AFND algoritmica: construo de sub-conjuntos ( f echo para cada smbolo de entrada em todos os estados ). O processamento de um AFD baseado numa tabela, sendo simples e eciente, em termos de tempo de execuo e espao ocupado.

Construo de um AFD a partir de um AFND


f echo (i0 ) a partir do estado inicial do AFND i0 determinar o conjunto de todos os estados que podem ser atingidos apenas atravs de transies vazias ( f echo (i0 ) ), este o estado inicial do AFD I0 . ( notar que i0 I0 ) move(I0 , a) para cada smbolo de entrada, calcular o conjunto dos estados do AFND que podem ser atingidos com uma transio etiquetada com esse smbolo. f echo (move(I0 , a)) para cada conjunto dos estados identicados na alnea anterior calcular o respetivo f echo at no haver novos estados.

Compiladores2012 , expresses regulares

3-10

Compiladores2012 , expresses regulares

3-11

Exemplo de construo de um AFD

Tabela de transio

estado I0 I0 I1 I1 I2 I2 I3 I3 I4 I4

entrada a b a b a b a b a b

move 0 3, 9 5, 12 3, 9 5, 10, 12 3, 9, 13 5, 12 3, 9, 13 5, 12 3, 9 5, 10, 12

f echo \move 1, 2, 4, 7, 8, 11 6, 1, 2, 4, 7, 8, 11 6, 1, 2, 4, 7, 8, 11 ... 14 , 6, 1, 2, 4, 7, 8, 11 14 , 6, 1, 2, 4, 7, 8, 11 ... ... ... ... ...

novo estado I0 I1 I2 (I1 ) I3 I4 I2 (I4 ) (I2 ) (I1 ) (I3 ) est I0 I1 I2 I3 I4 a I1 I1 I4 I4 I1 b I2 I3 I2 I2 I3

a 1 a 0 b b 2 b a a b 3 b a 4

Compiladores2012 , expresses regulares

3-12

Compiladores2012 , expresses regulares

3-13

Minimizar os estados de um AFD


o nmero de estados obtidos pelo algoritmo de converso de AFND para AFD no o mnimo. algoritmo de minimizao do nmero de estados de um DFA: 1. construir uma partio inicial com 2 grupos: um grupo contm todos os estados nais e o outro grupo os restantes estados. 2. construir uma nova partio agrupando os estados de cada grupo de partida que, para cada smbolo de entrada, tm transies para estados de um mesmo grupo de partida, qualquer que seja o smbolo de entrada. 3. repetir a alnea anterior at que no seja possvel criar mais grupos.

Gramtica regular
do autmato nito determinista minimizado pode-se obter diretamente uma gramtica regular. a gramtica regular contm tantos smbolos no terminais quantos os estados do autmato. cada transio (qi , a) = qj produz numa regra Si aSj cada estado nal qf produz uma regra Sf . a tabela de anlise e gramtica regular de (a|b) abb estado 0 1 3 4 a 1 1 1 1 b 0 3 4 0 S0 S1 S3 S4 a S1 | b S0 a S1 | b S3 a S1 | b S4 a S1 | b S0 |

Compiladores2012 , expresses regulares

3-14

Compiladores2012 , expresses regulares

3-15

Analisadores hardcoded
abordagem baseada em saltos (gotos), do estado 4:
state4: in = *input++; if (in == a) goto state1; if (in == b) goto state0; if (in == 0) return 1; /* s para estados finais */ goto error; /* termina cada estado */

Analisador lexical
O estado inicial inclui transies vazias para os estados iniciais das expresses regulares. Na busca da maior expresso possvel, como iro existir diversos estados terminais, deve-se avanar at um erro ou m dos dados e procurar o ltimo estado terminal aceite. A anlise recomea no estado inicial global, no carter seguinte ao que conduziu ao estado nal aceite. Na minmizao, a partio inicial coloca em grupos diferentes os estados terminais de cada uma das expresses regulares.

abordagem baseada em funes:


static int state4() { register char in = *input++; if (in == a) return s1(); if (in == b) return s0(); return 1; /* estados no finais retornam 0 */ }

Compiladores2012 , expresses regulares

3-16

Compiladores2012 , anlise lexical

4-1

Tempo de computao e ocupao de memria


O tempo de computao e a ocupao de memria dos autmatos nitos depende do comprimento da expresso regular |r| e do comprimento da cadeia a reconhecer |x|. Num AFND o tempo de reconhecimento O(|r| |x|) e o espao ocupado O(|r|). Num AFD o tempo de reconhecimento O(|x|) e o espao ocupado O(2|r| ). Contudo, num AFD o nmero de estados pode crescer exponencialmente, por exemplo, em (a|b)a(a|b)(a|b)(a|b) . . . (a|b) se existirem n1 ocorrncias de (a|b) so necessrios 2n estados. Atravs de lazy transition evaluation os estados e as transies so calculados durante a execuo, sendo apenas guardadas as transies usadas. Este mtodo complexo mas supera os anteriores em espao e tempo.

Analisador lexical
Um analisador lexical produz os elementos lexicais de um programa com base numa linguagem regular: modularidade: permite separar a sintaxe em duas fases distintas: anlise lexical e sinttica. legibilidade: expresses regulares so, em geral, mais legveis. simplicidade: permite simplicar signicativamente o analisador sinttico. ecincia: separao lexical e sinttica permite que ambos os analisadores sejam mais ecientes (usa autmato sem pilha auxiliar). portabilidade: variaes entre ambientes, dispositivos ou sistemas operativos podem car contidos no analisador lexical.

Compiladores2012 , anlise lexical

4-2

Compiladores2012 , anlise lexical

4-3

Tarefas do analisador lexical


Identicao de elementos lexicais (tokens): literais, palavras reservadas, identicadores, operadores, separadores e delimitadores. Tratamento de carateres brancos e comentrios. Manipulao dos atributos de alguns dos elementos lexicais. Utilizao da tabela de smbolos para classicar e guardar informao auxiliar de alguns elementos lexicais. Anlise do grasmo (posicionamento do elementos em linha e coluna) do programa. Processamento de macros. Tratamento de erros, em geral ignorando os carateres, embora este tipo de erros seja raro.

Formato do cheiro lex


Ficheiro, com a extenso .l, dividido em trs zonas separadas por uma linha contendo apenas %%: declaraes: de macros, de agrupamentos e declaraes da linguagem de apoio entre %{ e %}. regras: expresso regular separada da ao semntica por um ou mais espaos brancos. A ao semntica uma instruo da linguagem ou bloco delimitado por chavetas. cdigo: realizao de funes, algumas das quais declaradas acima. Gerar um analisador lexical, designado por lex.yy.c, com o comando lex xxx.l e compilado com o auxlio da biblioteca -ll. ( O ex usa a biblioteca -lfl )

Compiladores2012 , anlise lexical

4-4

Compiladores2012 , anlise lexical

4-5

Expresses regulares
x x \x x$ x x? x+ x xy x|y [az] [a-z] [ a-z] x{n} x{m, n} x/y . (x) << EOF >> O carcter x O carcter x, mesmo que seja um carcter especial O carcter x, mesmo que seja um carcter especial O carcter x no m da linha O carcter x no incio da linha Zero o uma ocorrncia de x Uma ou mais ocorrncia de x Zero ou mais ocorrncia de x O carcter x seguido do carcter y O carcter x ou o carcter y O carcter a ou o carcter z Do carcter a ao carcter z Qualquer carcter exceto de a a z n ocorrncias de x de m a n ocorrncias de x x se seguido por y (s x faz parte do padro) Qualquer carcter exceto \n O mesmo que x, parenteses alteram a prioridade dos operadores Fim do cheiro

Tratamento de expresses regulares


Identicao da ao semntica a executar, quando mais de uma expresso regular vlida: A sequncia de entrada mais comprida a escolhida. Em caso de igualdade de comprimento usada a que se encontra primeiro no cheiro de especicao. Notar que no se trata da expresso regular maior, mas da sequncia de entrada maior: %% dependente [a-z]+ printf("Encontrei dependente\n"); ECHO;

Compiladores2012 , anlise lexical

4-6

Compiladores2012 , anlise lexical

4-7

Funes
int yylex(void) : rotina, gerada pelo lex, que realiza a anlise lexical. Devolve o nmero do elemento lexical encontrado ou 0 (zero) quando atnge o m do processamento. int yywrap(void) : rotina, escrita pelo programador, que quando um cheiro chega ao m permite continuar o processamento noutro cheiro. Caso no haja mais cheiros a processar yywrap() devolve 1 (um), caso contrrio atualiza a varivel yyin para o cheiro seguinte e devolve 0 (zero). void yymore(void) : rotina, invocada numa ao semntica, que permite salvaguardar o texto reconhecido pela expresso regular para seja concatenado com a expresso regular seguinte. void yyless(int n) : rotina, invocada numa ao semntica, que permite considerar apenas os primeiros n carcteres de yytext, sendo os restantes reconsiderados para processamento.

Variveis globais
char yytext[ ] : cadeia de carateres que contm o texto reconhecido pela expresso regular. int yyleng : comprimento da cadeia de carateres que contm o texto reconhecido. int yylineno : nmero de linha do cheiro de entrada onde se encontra o ltimo carcter reconhecido pela expresso regular. Em ex usar a opo -l ou incluir %option yylineno ou %option lex-compat no cheiro .l. FILE *yyin : ponteiro para o cheiro de onde so lidos os carcteres a analisar. FILE *yyout : ponteiro para o cheiro de onde escrito o texto atravs da macro ECHO, ou outro texto que o programador deseje. YYSTYPE yylval : varivel que transporta o valor do elemento lexical reconhecido para outra ferramenta.

Compiladores2012 , anlise lexical

4-8

Compiladores2012 , anlise lexical

4-9

Macros predenidas
ECHO : imprime o texto reconhecido ( ou seja, yytext ) pela expresso regular, ou acumulado de outras regras atravs de sucessivas invocaes a yymore(). Na realidade est denido como #define ECHO fwrite(yytext, yyleng, 1, yyout) REJECT : depois de processada a ao semntica que inclui a chamada ao REJECT o processamento recomea no incio do texto reconhecido pela regra mas ignorando a regra atual.

Acesso direto a funes de entrada/sada


int input(void) : esta rotina permite ler o carcter seguinte, a partir do cheiro de entrada, sem que seja processado pelo analisador lexical. O valor -1 ( m de cheiro ) apenas devolvido no m do precessamento, pois a rotina yywrap() chamada se necessrio. void output(int) : imprime o carcter em yyout. Esta rotina no suportada pelo ex. void unput(int) : recoloca o carcter passado como argumento para processamento pelas expresses regulares seguintes. Notar que caso se pretenda recolocar diversos carateres este devem ser recolocados pela ordem inversa.

Compiladores2012 , anlise lexical

4-10

Compiladores2012 , anlise lexical

4-11

Substituies
As substituies permitem simplicar a escrita as expresses regulares. Expresso regular, na zona das declaraes seguida do identicador da substituio. Usa-se, em expresso regulares subsequentes, entre chavetas. DIG [0-9] INT {DIG}+ EXP [Ee][+-]?{INT} REAL {INT}"."{INT}({EXP})?

Agrupamentos
Grupos de expresses regulares ativadas por aes BEGIN e identicadas por %s na zona das declaraes. As expresses regulares do agrupamento so precedidas do identicador entre < e >. O agrupamento INITIAL identica as regras globais, permanentemente ativas. Em cada instante apenas esto ativas as regras globais e um dos agrupamentos, se tiver sido executada uma ao BEGIN. %s IN %% <IN>.|\n ECHO; <IN>^"%%" BEGIN INITIAL; ^"%%" BEGIN IN; .|\n ;

Compiladores2012 , anlise lexical

4-12

Compiladores2012 , anlise lexical

4-13

Ligao ao yacc
elementos a ignorar : comentrios ou espaos brancos, por exemplo. elementos lexicais teis (tokens) : descritos por tipo : nmero inteiro devolvido ( instruo return na ao semntica ) pela rotina yylex() e que descreve o token encontrado: valores de 1 a 255 para carateres isolados ASCII e > 256 para conjuntos de carateres. ( devolve 0 para m e 256 para erro ) valor : quantidade a guardar na varivel global yylval para alguns tokens, por exemplo inteiros, identicadores ou cadeia de carateres. descrio dos tokens necessrios : produzido pelo yacc, com a opo -d, no cheiro y.tab.h. Contm as constantes > 256 a varivel yylval e seu tipo, devendo ser includo nas declaraes.

Extenses do flex
modo mais compatvel com lex : gerar com ex -l ou incluir %option lex-compat nas declaraes. acesso a yylineno : usar o modo de compatibilidade com lex ou incluir %option yylineno nas declaraes. agrupamentos exclusivos : apenas as regras do agrupamento ativo esto vlidas, no incluindo as globais, usando %x em vez de %s. modo debug : gerar com ex -d e colocar a varivel yy_ex_debug a 1.

Compiladores2012 , anlise lexical

4-14

Compiladores2012 , gramtica livre de contexto

5-1

Ecincia de processamento
tempo de processamento do autmato proporcional dimenso do cheiro a processar e no ao nmero de expresses regulares usadas ( pode inuir no nmero de estados e logo na espao ocupado ). utilizar o mais possvel expresses regulares e fazer o mnimo em C. regras mais especcas no princpio da especicao ( palavras reservadas, por exemplo )e regras mais genricas no m especicao ( identicadores, por exemplo ).

Denio e compilao de uma linguagem


Uma linguagem um alfabeto e um conjunto de frases. Uma linguagem pode ser denida por: sintaxe: gramtica livre de contexto, BNF (Backus-Naur Form). semntica: informal (textual), operacional, denotacional, por aes. Compilao de um programa descrito numa linguagem: objetivo: traduzir expresses inxadas em postxadas. aplicabilidade: computao baseada em pilha de dados.

Compiladores2012 , gramtica livre de contexto

5-2

Compiladores2012 , gramtica livre de contexto

5-3

Gramtica como descrio sinttica


Uma gramtica d uma explicao precisa e fcil de compreender da sintaxe de uma linguagem. Para algumas classes de gramticas possvel gerar automaticamente um analisador sinttico eciente. Analisadores da gramtica identicam ambiguidades e outras construes difceis de serem reconhecidas e que passam despercebidas. A gramtica tem relao direta com a estrutura da linguagem usada, facilitando a anlise, traduo e compilao. Uma gramtica de fcil extenso e atualizao, garantido maior durabilidade do analisador sinttico.

Notao BNF: Backus-Naur Form


um conjunto de smbolos terminais (tokens), onde cada um representa um elemento lexical extrado do programa a analisar. um conjunto de smbolos no terminais, onde cada smbolo no terminal expandido em pelo menos uma produo. um conjunto de produes, onde cada produo representa a expanso de numa sequncia de smbolos numa outra sequncia de smbolos, eventualmente vazia: uma produo: produes alternativas 1 , 2 , . . . , n so representadas por 1 |2 | . . . |n . uma produo nula: . um dos smbolos no terminais designado por smbolo inicial.

Compiladores2012 , gramtica livre de contexto

5-4

Compiladores2012 , gramtica livre de contexto

5-5

Gramtica livre de contexto


Uma gramtica livre de contexto possui apenas produes com um s smbolo no terminal do lado esquerdo. Tudo o que pode ser descrito por uma expresso regular pode ser descrito por uma gramtica livre de contexto. Extenses ao BNF (EBNF): {} [] () a+ a/b para representar zero ou mais repeties de smbolos. para representar elementos opcionais. para agrupar smbolos. para representar uma ou mais repeties de smbolos. para representar repeties de a atravs de b.

Mtodos de anlise gramtical


Mtodos de parsing universais: funcionam para qualquer gramtica, mas so muito inecientes (inviveis para uso prtico). Mtodos de processamento deterministico com leitura da esquerda para a direita (L?), um smbolo de cada vez: descendentes (LL ou top-down): constroem as rvores sintticas da raiz para as folhas. ascendetes (LR ou botton-up): constroem as rvores sintticas das folhas para a raiz. Estes mtodos funcionam para um conjunto limitado de gramticas, que na prtica so sucientes para a maioria das linguagens usadas em computao (em particular as linguagens de programao).

Compiladores2012 , gramtica livre de contexto

5-6

Compiladores2012 , gramtica livre de contexto

5-7

Derivaes
Considerando a gramtica: S L (L) L, S | | a S

rvores sintticas
rvores sintticas so representaes grcas das derivaes:
S (L) ( L,S , a )

Derivao: substituio de uma sequncia de smbolos, que estejam do lado esquerdo de uma produo, pelos smbolos do lado direito de uma produo. Derivao mais esquerda: expande-se o no terminal mais esquerda. Por exemplo, S 1 (L) 3 (L, S) 4 (S, S) 2 (a, S) 2 (a, a) Derivao mais direita: expande-se o no terminal mais direita. Por exemplo, S 1 (L) 3 (L, S) 2 (L, a) 4 (S, a) 2 (a, a) Derivao imediata: S (L) Derivao de um ou mais passos: S + (a, a)

n: smbolo no terminal. ramo: derivao. folha: smbolo terminal.


S a

A construo da rvore pode ser descendente ou ascendente.

Compiladores2012 , gramtica livre de contexto

5-8

Compiladores2012 , gramtica livre de contexto

5-9

Recursividade e ambiguidade
Uma gramtica diz-se recursiva se existir: uma derivao recursiva esquerda: + . Por exemplo, num num digit. uma derivao recursiva direita: + . Por exemplo, num digit num. Uma gramtica diz-se ambgua se produz mais de uma rvore sinttica, para a mesma frase. Por exemplo, para a gramtica E E E|int existem duas rvores sintticas que resultam de derivaes mais esquerda da frase 3 5 7: E E E E E E int3 E E int3 int5 E int3 int5 int7 , ou seja, (3 5) 7 = 9. E E E int3 E int3 E E int3 int5 E int3 int5 int7 , ou seja, 3 (5 7) = 5.

Prioridade e associatividade
Cada nvel de prioridade inclui os operadores de igual prioridade e os smbolos no terminais associados mesma prioridade ou superior. A associatividade denida pela recursividade das produes. Por exemplo, E E+T T T F F U F U P P (E) | | | | | ET T /F U P int | | T F

id

Compiladores2012 , anlise sinttica descendente LL(1)

6-1

Compiladores2012 , anlise sinttica descendente LL(1)

6-2

Conjuntos FIRST
O conjunto FIRST de um smbolo no terminal o conjunto de smbolos terminais situados mais esquerda em todas as derivaes possveis. O smbolo s pertence ao conjunto FIRST de se existir uma derivao + . 1. X F IRST () se X X terminal. 2. (F IRST () \ {}) F IRST () se X no terminal. 3. F IRST () se .
+

Conjuntos FOLLOW
O conjunto FOLLOW de um smbolo no terminal o conjunto de smbolos terminais derivados imediatamente aps a identicao desse smbolo no terminal. 1. $ F OLLOW (S) se S o smbolo inicial. 2. (F IRST () \ {}) F OLLOW () se X . 3. F OLLOW () F OLLOW () se X. 4. F OLLOW () F OLLOW () se X X + . Por exemplo, F OLLOW (Y ) = {a, b, $} em: S X Y SaY X|c bX| 0|1

4. F IRST () F IRST () se X X + . Por exemplo, F IRST (S) = {a, b, c, d, } em: S X Y a|Xb|XY Xc| dY |

Compiladores2012 , anlise sinttica descendente LL(1)

6-3

Compiladores2012 , anlise sinttica descendente LL(1)

6-4

Conjuntos LOOKAHEAD
A relao LOOKAHEAD permite identicar os smbolos terminais que permitem a expanso da regra: LOOKAHEAD(A ) = F IRST (A) (F OLLOW () + ) A relao LOOKAHEAD permite vericar se a gramtica pode ser processada por um analisador preditivo descendente por tabela.

Autmatos de pilha
linguagens regulares podem ser modeladas por autmatos nitos: a transio para um estado s depende do estado atual e do smbolo de entrada. linguagens no regulares necessitam de autmato de pilha: a transio para um estado depende do estado atual, do smbolo de entrada e do contedo da pilha. T abela @ P ilha  @ R @ F rase$ ?

Analisador

- Sada

Compiladores2012 , anlise sinttica descendente LL(1)

6-5

Compiladores2012 , anlise sinttica descendente LL(1)

6-6

Gramticas LL(1)
Uma gramtica independente do contexto diz-se LL(1) se: no possui recursividades esquerda. em todas as regras com o mesmo smbolo do lado esquerdo, X e X , verica-se a condio: LOOKAHEAD(X ) LOOKAHEAD(X ) = Dada uma gramtica pode ser possvel identicar outra gramtica equivalente que seja LL(1), atravs de transformaes como: eliminao da recursividade esquerda. fatorizao esquerda. Uma gramtica LL(1) pode ser processada por um analisador preditivo descendente por tabela.

Eliminao de produes no atingveis


Um smbolo no terminal que nunca consegue ser atingdo a partir do smbolo inicial da gramtica, inatingvel e, deve ser retirado. Se o smbolo no terminal nunca aparece do lado direito das regras ento inatingvel, mas pode tambm haver ciclos de regras inatingveis. S A B C D A D C

onde apenas as primeiras duas regras so atingveis.

Compiladores2012 , anlise sinttica descendente LL(1)

6-7

Compiladores2012 , anlise sinttica descendente LL(1)

6-8

Fatorizao esquerda
Para uma gramtica poder ser processada por um analisador preditivo descendente por tabela necessrio ser possvel identicar qual a regra a expandir quando um smbolo terminal lido. Por exemplo, em X 1 |2 , a leitura de no permite escolher uma das regras. Fatorizao esquerda substitui X 1 |2 por: X X X 1 |2

Substituio de cantos esquerda


Numa produo A B o smbolo A designado por um canto esquerda. As produes vazias () no tm cantos. Numa substituio de cantos esquerda, os smbolos no terminais que sejam cantos esquerda de uma produo podem ser substitudos pelas produes do smbolo no terminal em questo. Por exemplo, A B A |B | | |

produz necessitando ainda de fatorizao.

Compiladores2012 , anlise sinttica descendente LL(1)

6-9

Compiladores2012 , anlise sinttica descendente LL(1)

6-10

Substituio de singularidades
Se um smbolo no terminal deriva uma s regra, ento pode ser substitudo nas regras onde referido. Estas produes singulares (uma s regra) reduzem a dimenso da gramtica e respetivas tabelas, bem como menor nmero de passos na anlise das sequncias de entrada. A BB B resume-se a A

Eliminao de ambiguidade
Produes ambguas so aquelas que possuem mais de uma ocurrncia de um determinado smbolo no terminal do lado direito da produo. A ambiguidade pode ser retirada dando precedncia a uma das ocurrncias face s outras. Numa regra A A A |1 | . . . |n optando pela associatividade direita A A A A |A 1 | . . . |n ou esquerda A A A A |A 1 | . . . |n

Se a gramtica inclui vrias regras ambguas, eliminar a ambiguidade passo a passo comeando pelas regras de menor prioridade.

Compiladores2012 , anlise sinttica descendente LL(1)

6-11

Compiladores2012 , anlise sinttica descendente LL(1)

6-12

Eliminao da recursividade esquerda


Para uma gramtica poder ser processada por um analisador preditivo descendente por tabela no podem existir derivaes esquerda A + A. Para eliminar recursividades esquerda substitui-se as regras do tipo A A| por: A A A A |

Construo da tabela de anlise


A tabela de anlise de um analisador preditivo descendente por tabela construda por uma coluna por cada smbolo terminal mais o smbolo $, e por uma linha por cada smbolo no terminal. Cada regra A da gramtica includa na tabela em: tab[A, a] : se a F IRST (). tab[A, b] : se F IRST () b F OLLOW (A). tab[A, $] : se F IRST () $ F OLLOW (A). Todas os elementos no preenchidos da tabela correspondem a um erro.

Compiladores2012 , anlise sinttica descendente LL(1)

6-13

Compiladores2012 , anlise sinttica descendente LL(1)

6-14

Exemplo de tabela LL(1)


Eliminao da recursividade: S (L) | a L L, S | S S L L (L) SL , SL | | a

Anlise preditiva por tabela


Considerando X o smbolo no topo da pilha e a o smbolo de entrada: se X = a = $ ento o analisador chegou ao m de uma sequncia correta. se X = a = $ ento o analisador retira o smbolo X do topo da pilha e avana para o smbolo seguinte na sequncia de entrada. se X terminal e X = a ento trata-se de um erro sinttico. se X no terminal ento a regra em tab[X, a] utilizada: se tab[X, a] estiver vazia ento trata-se de um erro sinttico. se tab[X, a] contiver X U V W ento os smbolo do lado direito da regra so colocados na pilha, com U no topo.

Determinao dos conjuntos FIRST, FOLLOW e LOOKAHEAD: FIRST FOLLOW LOOKAHEAD S (L) | a (a $, ) ( | a L SL (a ) (a L , SL | , ) , | ) Construo da tabela: ( ) S S (L) L L SL L L , a Sa L SL $

L , SL

Compiladores2012 , anlise sinttica descendente LL(1)

6-15

Compiladores2012 , anlise sinttica descendente LL(1)

6-16

Exemplo das aes do analisador LL(1)


pilha S$ (L)$ L)$ SL )$ aL )$ L )$ , SL )$ SL )$ aL )$ L )$ )$ $ entrada (a, a)$ (a, a)$ a, a)$ a, a)$ a, a)$ , a)$ , a)$ a)$ a)$ )$ )$ $ regra L (L) ( ( L SL Sa a a L , SL , , Sa a a L ) ) $ $ (accept)

Recuperao de erros em analisadores LL(1)


conjunto de sincronizao onde os membros do conjunto so smbolos que terminam blocos de cdigo: 1. retirar elementos da pilha at car no topo um dos elementos do conjunto de sincronizao. A recuperao no possvel se a pilha no contiver elementos do conjunto; 2. ler elementos lexicais at o smbolo de anteviso coincidir com o topo da pilha. Se estiver no m do cheiro, a recuperao falhou, caso contrrio o processamento continua. pilha de sincronizao auxiliar onde conjuntos de sincronicao, denidos regra a regra, so colocados quando a regra derivada. Simultaneamente, retirase o smbolo a derivar, coloca-se uma marca e os smbolos derivados na pilha do analisador. Quando essa marca ca no topo da pilha, retira-se a marca e o conjunto de sincronizao. Em caso de erro, usa-se o conjunto de sincronizao no topo da pilha auxiliar.

Compiladores2012 , anlise sinttica descendente LL(1)

6-17

Compiladores2012 , anlise sinttica descendente LL(1)

6-18

Recuperao de erro nas aes do analisador LL(1)


Sync = { ) } pilha S$ (L)$ L)$ )$ $ entrada (, a)$ (, a)$ , a)$ )$ $ regra L (L) ( ( (syntax error) ) ) $ $

Compresso de tabelas: double-offset indexing


Arrumam-se as linhas da tabela(t) original num vetor(v), de tal forma que no haja sobreposio de elementos no nulos, minimizando o nmero de posies nulas. Heurstica (problema NP-completo): comear pelas linhas de maior densidade. Cada posio no vetor contm o valor e a linha original a que pertence. Uma tabela de coluna(c) indica o incio de cada coluna no vetor. Se v[c[i] + j].line == i ento v[c[i] + j].value contm o valor da tabela original, caso contrrio um elemento nulo.
L t W Q U X P R =c 2 2 2 0 +v W 4 X 4 L 1 Q 2 U 3 P 1 R 2

Compiladores2012 , anlise sinttica descendente LL(1)

6-19

Compiladores2012 , anlise sinttica descendente LL(1)

6-20

Analisadores LL(1) hardcoded


A codicao explcita de analisadores descendentes preditivos simples e usa a pilha do processador para guardar o caminho.
static void symbL2() { if (la == ,) { la = yylex(); symbS(); symbL2(); return; } if (la == )) { return; } error(); }

Analisadores LL(k) com k>1


A utilizao de mais de um smbolo de anteviso permite superar alguns dos problemas das gramticas LL(1). Os conjuntos FIRSTk , FOLLOWk e LOOKAHEADk so calculados utilizando k smbolos terminais (tokens) para todos smbolos no-terminais (N T ) da gramtica. Por exemplo, FIRST2 ser constitudo pelas possveis combinaes de sequncias de 2 smbolos de entrada, para a regra em anlise. Ou seja, se w a x| a y|z pode ser FIRST2 (regra) = { a b, a c, z b }. Contudo, a dimenso tabela de anlise tem um crescimento exponencial pois N T tokensk , pelo que se torna impraticvel para gramticas vulgares.

A recuperao de erro possvel, com recurso a excepes (longjmp/setjmp), mas mais complicada de realizar. A avaliao de atributos sintetizados (ver a seguir) simples e direta, mas a utilizao de atributos herdados exige uma pilha auxiliar.

Compiladores2012 , anlise sinttica descendente LL(1)

6-21

Compiladores2012 , Gramticas atributivas

7-1

Analisadores Strong LL(k)


Como nem todas as regras de uma gramtica necessitam de mais de um smbolo de anteviso, a soluo passa por utilizar mais smbolos de anteviso apenas quando necessrio. A determinao da regra l o nmero necessrio de smbolos de anteviso at determinar a produo a selecionar. O processamento da produo selecionada que vai, efetivamente, consumir os smbolos anteriormente lidos, tal como no caso LL(1). A determinao da regra na soluo hardcoded efetuada atravs de sequncias de instrues switch aninhadas, em os case incluem apenas as solues possveis (e o erro detetado pelo default. (ferramenta antlr) A determinao da regra pode recorrer a um AFD, onde as transies correspondem a possveis sequncias de smbolos e os estados terminais identicam as regras a selecionar. Uma marca na tabela de anlise LL(1) identica, em certas combinaes [N T, token] que necessitam de k > 1, no um token mas um AFD.

Gramticas atributivas
Gramtica atributiva: gramtica independente do contexto onde smbolos (terminais e no terminais) recebem valores manipulados por regras semnticas. Regras semnticas: so funes da forma b = f (c1 , c2 , . . . , cn ), onde os ci so literais, valores de atributos dos smbolos da produo ou funes puras (sem efeitos colaterais). Atributo sintetizado: na regra A o valor b um atributo sintetizado de A. Atributo herdado: na regra A o valor b um atributo herdado de , se os ci dependem de atributos de A ou de .

Compiladores2012 , Gramticas atributivas

7-2

Compiladores2012 , Gramticas atributivas

7-3

Exemplo de gramtica atributiva


num seq seq seq1 dig { { seq.pos = 0; num.val = seq.val; } seq1 .pos = seq.pos + 1; dig.pos = seq.pos; seq.val = seq1 .val + dig.val; } dig.pos = seq.pos; seq.val = dig.val; } dig.val = 0; } dig.val = 2dig.pos ; }

Avaliao dirigida pela sintaxe


A avaliao dirigida pela sintaxe quando os valores dos atributos so calculados quando se identica a derivao das regras sintticas.
+ anlise mais simples e rpida, num nico passo. + poupa memria, pois no exige a construo de uma rvore sinttica. - s se pode aplicar em gramticas simples. - pode obrigar a modicaes signicativas na gramtica.

| dig |

dig 0 1

{ { {

Denio de S-atributos: gramtica atributiva onde todos os atributos so sintetizados. Denio de L-atributos: gramtica atributiva onde os atributos so sintetizados ou herdados dos irmos mais velhos (na regra A 1 2 3 4 os atributos de 3 podem depender dos atributos de 1 , 2 ou A, mas no de 4 .

no-terminal dig tem 2 atributos: pos representa a posio do digito no nmero binrio ( herdado dig.pos ). val representa a valor do digito no nmero binrio ( sintetizado dig.val ). atributos com o mesmo signicado em seq ( pos e val ) e em num ( val ).

Compiladores2012 , Gramticas atributivas

7-4

Compiladores2012 , Gramticas atributivas

7-5

Grafos de dependncias
rvore sinttica anotada: rvore sinttica onde os ns incluem os atributos e seus valores. Grafo de dependncias: grafo dirigido acclico que determina a ordem de avaliao dos atributos.

rvore sinttica anotada


num
val = 5

seq

pos = 0 val = 5

seq

pos = 1 val = 4

seq

pos = 0 val = 1

Avaliao de atributos: Avaliam-se, primeiro, os atributos herdados, descendo a rvore. Avaliam-se, seguidamente, os atributos sintetizados, subindo a rvore.
seq
pos = 2 val = 4

seq

pos = 2 val = 4

seq

pos = 1 val = 0

dig

pos = 0 val = 1

dig

pos = 1 val = 0

dig

pos = 2 val = 4

Compiladores2012 , Gramticas atributivas

7-6

Compiladores2012 , Gramticas atributivas

7-7

Grafos de dependncias
num
val = 5

Eliminao de atributos herdados


Identidades algbricas: utilizaes de expresses equivalentes que, usando apenas atributos sintetizados, permitem obter o mesmo resultado nal. Por exemplo, nos nmeros binrios: 2n = 2 2n1 .

seq

pos = 0 val = 5

seq

pos = 1 val = 4

seq

pos = 0 val = 1

Alterao sinttica: os smbolos que denem o valor do atributo herdado so deslocados para produes que o consomem. Por exemplo, declarao de variveis em C. Deslocamento de regras semnticas: atrasar a avalio de atributos herdados atravs de estruturas semnticas auxiliares, em geral, rvores sintticas. (Deixa de poder ser considerado como dirigido pela sintaxe) Por exemplo, declarao de variveis em Pascal. (Generalizvel atravs da utilizao de rvores sintticas)

seq

pos = 2 val = 4

seq

pos = 1 val = 0

dig

pos = 0 val = 1

seq

pos = 2 val = 4

dig

pos = 1 val = 0

dig

pos = 2 val = 4

Compiladores2012 , Gramticas atributivas

7-8

Compiladores2012 , Gramticas atributivas

7-9

Esquemas de avaliao de atributos


descendente: eliminao da recursividade esquerda obriga a introduzir: um atributo herdado transmite os atributos dos smbolos que faziam parte da mesma regra. um atributo sintetizado transmite o resultado na direco da raiz. ascendente: denies de L-atributos em analisadores ascendentes: aces internas: so equivalentes a regras vazias, pelo que reduzem a anteviso do analisador. ( i IF {. . .} ( | IF y ( ) atributos herdados na pilha: quando um analisador LR explora Y , na regra A X Y , os atributos de X j esto na pilha, podendo ser utilizados na regra Y . . .. Contudo, Y pode aparecer em outras regras no precedido por X.

Atributos na eliminao da recursividade esquerda


Considere-se a gramtica seguinte onde cada smbolo tem um atributo sintetizado e f e g so funes: A | A1 Y X {A.a = g(A1 .a, Y.y); } {A.a = f (X.x); }

Removendo a recursividade esquerda camos com um novo smbolo R inclui um atributo herdado h e um sintizado s: A R | X R Y R1 {R.h = f (X.x); } {A.a = R.s; } {R1 .h = g(R.h, Y.y); } {R.s = R1 .s; } {R.s = R.h; }

Compiladores2012 , yacc

8-1

Compiladores2012 , yacc

8-2

Formato do cheiro
Formato idntico ao do cheiro lex, trs zonas separadas por %%: declaraes: token, union, type, left, right, nonassoc, start e declaraes da linguagem entre %{ e %}. regras: a produo separada por : (em vez de ), as alternativas por | e as aes semnticas so includas entre chavetas. cdigo: realizao de funes, algumas das quais declaradas acima. Declaraes: %start: delara o smbolo no terminal objetivo (o smbolo inicial) da gramtica. Caso esta declarao seja omitida, assumido o primeiro smbolo na zona das regras.

Elementos lexicais, valores e tipos


%token: declara os elementos lexicais, no constitudos por carateres isolados, a ser utilizados na gramtica como smbolos terminais. Podem existir diversas declaraes %token, sem ordem relevante, para declarar todos os elementos lexicais. %union: dene os tipos de dados a ser guardados na pilha do analisador sinttico. Os dados so associados. quer a smbolos terminais (transportados do analisador lexical), quer a smbolos no terminais. %type< x >: associa um tipo de dados aos smbolos declarados. O x representa o noma da varivel na union. %token< x >: declara o token e respetivo tipo numa s declarao.

Compiladores2012 , yacc

8-3

Compiladores2012 , yacc

8-4

Prioridade e associatividade
Embora possa ser resolvida gramaticalmente, a prioridade e associatividade das regras podem ser descritas por declaraes: %left: lista de smbolos que designam regras (aparecem nessas regras) com operadores associativos esquerda. %right: idem, mas associativo direita. %nonassoc: idem, mas no associativo. A ordem das declaraes dene as prioridades relativas, das menos prioritrias (acima), para as mais prioritrias (abaixo). Todos os smbolos na mesma diretiva designam regras com a mesma prioridade.

Aes semnticas
Os valores dos atributos so referidos pela posio dos respetivos smbolos na regra: $$: designa o smbolo objetivo da regra, smbolo do lado esquerdo. $1: designa o primeiro smbolo do lado direito da regra. Os restantes smbolos so numerados por ordem crescente. $< type > 0: designa o primeiro smbolo associado a um atributo herdado. O tipo necessrio pois o smbolo no existe na regra e pode no ser univocamente dedutvel. Os restantes smbolos na pilha so designados por valores negativos. Aes internas podem devolver valores que podem ser utilizados em aes semnticas posteriores, na mesma regra, e ocupam uma posio na regra. Por exemplo, X > Y {$$ = 3; }Z{$$ = $1 $2 + $3}.

Compiladores2012 , yacc

8-5

Compiladores2012 , yacc

8-6

Ambiente do analisador sinttico


O analisador sinttico realizado pela rotina int yyparse();, que devolve 0 se no foram encontrado erros sintticos e devolve 1, caso contrrio. Sempre que encontrado um erro sinttico, a funo int yyerror(char*s); chamada pelo analisador e a varivel int yynerrs; incrementada. As variveis int yystate; e int yychar; designam o estado atual do analisador de acordo com a tabela LALR(1) e o cdigo do elemento lexical corrente. A ferramenta yacc gera o cheiro y.tab.c contendo o cdigo do analisador sinttico e respetivas tabelas. As opes -d e -v permitem gerar os cheiros y.tab.h ( para ligao ao lex ) e y.output ( tabela LALR(1) legvel ). Na gerao do compilador, produz-se primeiro o analisador sinttico ( com o yacc ) e depois o analisador lexical ( com o lex ). Na edio de ligaes ( link ), indica-se primeiro a biblioteca do yacc, designada por -ly, e depois a biblioteca do lex, designada por -ll ( ou -l no caso do ex ).

Tratamento de erros de sintaxe


Relatar a presena de erros sintticos com clareza e preciso. Permitir a recuperao de situaes de erro, por forma a permitir a identicao de mais erros. O processamento de erros no deve prejudicar signicativamente o processamento de programa corretos, pelo compilador. A introduo de regras gramaticais especcas para tratamento de erros o procedimento mais comum.

Compiladores2012 , yacc

8-7

Compiladores2012 , yacc

8-8

Tratamento de erros em YACC


O smbolo no-terminal (reservado) error permite absorver situaes de erro, consumindo os smbolos terminais at encontrar um dos seus follows. A macro YYERROR pode ser utilizada, nas aes semnticas, para gerar erros sintticos semanticamente. A funo yyerror(char*s); chamada sempre que tratado um erro sinttico, mesmo quando originrio da semntica por YYERROR. A macro yyerrok pode ser utilizada, nas aes semnticas, para continuar o processamento aps um erro sinttico. A macro yyclearin pode ser utilizada, nas aes semnticas, para forar o analisador a reler o elemento lexical de lookahead, caso na recuperao de erros se tenha manipulado o cheiro de entrada (por exemplo, em utilizaes interativas).

Depurao gramatical (debug)


Anlise esttica: gerar o analisador sinttico com a opo -v (yacc -v gram.y) e analisar o cheiro y.output que contm os estados do analisador e as transies com os respetivos smbolos. Anlise dinmica: compilar o analisador sinttico com a constante YYDEBUG (gcc -c -DYYDEBUG y.tab.c, ou #define YYDEBUG 1 na gramtica) e colocar a varivel yydebug a 1 (um) no incio da execuo do programa (no main). Notar que s se garante que a varivel exista se YYDEBUG estiver denido.

Compiladores2012 , yacc

8-9

Compiladores2012 , yacc

8-10

Conitos na gramtica LALR(1)


determinar os itens das regras determinam os estados da gramtica. Em X AB existem 3 itens: X : .AB, X : A.B e X : AB., onde o ponteiro . representa a posio corrente no processamento da regra. pode existir mais de um ponteiro em cada instante, mas se no momento da reduo de um ponteiro (ltimo item da regra) existirem mais ponteiros com o mesmo smbolo de anteviso, existe um conito. os conitos so reportados aos pares e podem ser: reduo/reduo: os dois ponteiros esto no m das respetivas regras. deslocamento/reduo: um dos ponteiros est no m da regra, mas o outro ainda est a meio da regra. um smbolo de lookahead distinto elimina conitos, em gramticas LALR(1).

Conitos de reduo/reduo
o YACC reduz a primeira regra no ficheiro e ignora as restantes regras. identicar, no y.output, as regras envolvidas no conito e determinar os smbolos que geram o conito. S : A|B; fatorizar as regras comuns: A : X|Y ; B : X|Z; S : A|B|X; A:Y; B : Z;

agrupar as regras e resolver a ambiguidade nas aes semnticas (Por exemplo, operaes polimrcas)

Compiladores2012 , yacc

8-11

Compiladores2012 , Anlise ascendente

9-1

Conitos de deslocamento/reduo
o YACC desloca em vez de reduzir. identicar, no y.output, as regras envolvidas no conito e determinar os smbolos que geram o conito. introduzir prioridades nas regras. (expresses ou if-else, por exemplo) enumerar as diversas alternativas. (chamada a funo ou for, por exemplo) juntar regras, aplicando a propriedade distributiva, para evitar redues desnecessrias. (blocos com declaraes e instrues)

Aes de um analisador ascendente


deslocamento (shift): consumo de um elemento lexical (smbolo terminal), colocando na pilha o smbolo e o respetivo estado. reduo (reduce): identicao de uma regra, substituindo na pilha todos os smbolos dessa regra e respetivos estados pelo smbolo no terminal reduzido. salto (goto): determinao do estado seguinte aps uma reduo, colocando-o na pilha. aceitao (accept): sucesso na anlise sinttica. erro (error): erro na anlise sinttica.

Compiladores2012 , Anlise ascendente

9-2

Compiladores2012 , Anlise ascendente

9-3

Exemplo de tabela ascendente


S L 0 1 2 3 4 5 6 7 8 ( s2 s2 r2 s6 r4 r1 s2 r3 r3 r2 s7 r4 r1 s3 ) , (L) L, S a s3 s3 r2 r1 8 | | $ acc 4 5 a S L S 1

Reconhecimento de uma frase


pilha 0 0(2 0(2a3 0(2S 0(2S5 0(2L 0(2L4 0(2L4, 7 0(2L4, 7a3 0(2L4, 7S 0(2L4, 7S8 0(2L 0(2L4 0(2L4)6 0S 0S1 entrada (a, a)$ a, a)$ , a)$ , a)$ , a)$ , a)$ , a)$ a)$ )$ )$ )$ )$ )$ $ $ $ ao shift-2 shift-3 reduce-2 goto-5 reduce-4 goto-4 shift-7 shift-3 reduce-2 goto-8 reduce-3 goto-4 shift-6 reduce-1 goto-1 accept

Compiladores2012 , Anlise ascendente

9-4

Compiladores2012 , Anlise ascendente

9-5

Autmato no determinista LR(0), SLR(1) ou LALR(1)


Construir a gramtica aumentada equivalente, acrescentando a regra S S$, onde S o smbolo inicial. Os estados do autmato no determinista so os estados da gramtica e correspondem aos itens das regras. Em X AB existem 3 itens: X : .AB, X : A.B e X : AB., onde o ponteiro . representa a posio no processamento da regra. A transies entre estados de uma regra so etiquetadas com o smbolo, terminal ou no terminal, que analisado entre dois estados consecutivos. Por exemplo, X : .AB A X : A.B. As transies vazias ( ) so construdas de um estado onde o ponteiro precede um no terminal para o primeiro estado de todas as regras que derivam esse no terminal. Por exemplo, X : .AB A : .Y Z.

Transporte dos LOOKAHEAD no fecho- do LALR(1)


Sempre que se atinge um item do tipo X : .Ab, o LOOKAHEAD b introduzido nos primeiros itens das regras que derivam A. Notar que se A : .Bv entao este item tem como LOOKAHEAD b mas introduz apenas v nos primeiros itens das regras que derivam B. Num item do tipo X : a.B, os LOOKAHEAD so transportados deste item para os primeiros itens das regras que derivam B. Numa transio que consome um smbolo, os LOOKAHEAD so transportados da transio que a antecede para a seguinte, sem alterao. Sempre que um estado se repete, i.e. contm os mesmos itens, necessrio vericar se os LOOKAHEAD de todos os seus itens so iguais ao original. Caso no sejam, necessrio adicion-los e propag-los a todos os estados dele derivados, que tenham sido determinados entretanto.

Compiladores2012 , Anlise ascendente

9-6

Compiladores2012 , Anlise ascendente

9-7

Tabela LR(0), SLR(1) ou LALR(1)


Determinar o autmato determinista a partir do autmato no determinista ( com LOOKAHEAD no caso do LALR(1) ). A tabela tem tantos estados quantos os estados do autmato determinista e tantas colunas quantos os smbolos terminais e no terminais da gramtica, incluindo o $. Deslocamentos: se goto(I0 , a) = I2 , onde I0 e I2 so estados do autmato determinista, preencher na linha 0 coluna a da tabela shif t 2, ou seja tab[0, a] = s2. Saltos: se goto(I4 , S) = I1 preencher na linha 4 coluna S da tabela goto 1, ou seja, tab[4, S] = 1. Redues: a colocao das redues depende do mtodo a utilizar: LR(0), SLR(1) ou LALR(1).

Tabela de redues LR(0), SLR(1) e LALR(1)


Determinar, para cada regra da gramtica, os estados do autmato determinista que correspondem aos estados do autmato no determinista que representam o ltimo item dessa regra. Incluir na tabela uma reduo dessa regra, nas linhas correspondentes aos estados do atmato determinista calculado acima e nas colunas: LR(0): preencher a reduo em todos os smbolos no terminais, exceto o accept que preenchido apenas no $. SLR(1): preencher a reduo em todos os f ollows do smbolo no terminal que deriva essa regra. LALR(1): preencher a reduo apenas nos LOOKAHEAD associados ao ltimo item da regra. Nota: nestes mtodos, um erro pode ser apenas detetado no prximo shift.

Compiladores2012 , Anlise ascendente

9-8

Compiladores2012 , Anlise ascendente

9-9

Utilizao determinista de gramticas ambguas


Conitos shift-reduce: a denio de prioridade e associatividade entre regras: optar pelo shift quando o smbolo de anteviso est associado a uma regra de maior prioridade, ou pelo reduce no caso contrrio. nos casos de igual prioridade optar por: shift: se a regra for associativa direita; reduce: se a regra for associativa esquerda; error: se a regra no for associativa. Conitos reduce-reduce: colocar a regra mais especca primeiro, para que seja preferida em caso de conito. A regra mais geral ser reduzida nos restantes casos. Se as duas regras forem de igual aplicabilidade, uma delas car sempre por reduzir e nunca ser utilizada.

Compactao de tabelas LR
Separar a tabela de deslocamento/reduo da tabela de saltos e agrupar as linhas idnticas, usando uma tabela de indireo. Redues unitrias: substitui sequncias de redues unitrias ( um s smbolo na produo ) por uma s regra, caso no existam aes semnticas nas regras intermdias, dependendo do smbolo de anteviso ( utilizado em geral na precedncia de operadores ). Propagao de redues para uniformizar a tabela (ver a seguir).

Compiladores2012 , Anlise ascendente

9-10

Compiladores2012 , Anlise ascendente

9-11

Compactao por propagao de redues


Os estados que contm apenas redues de uma s regra ( e erros ) podem ser eliminados: os shift para esses estados so substitudos por redues tipo L dessa regra. Redues quase nicas: estados com vrios shift e redues de uma s regra ( e erros ) passam a ter um comportamento por omisso. As redues e os erros passam a default ( valor zero ) e o vetor default passa a incluir a reduo. Para os estados com mais de uma reduo, estas no so substitudas, cando error no vetor default. Vantagem: a tabela ca mais esparsa, logo mais compactvel. A substituio de situaes de erro por redues, apenas atrasa a deteo dos erros at ao prximo deslocamento, no comprometendo a correo do analisador.

Analisadores LALR(1) hardcoded


Os analisadores LALR(1) hardcoded so 2 a 6 vezes mais rpidos que os baseados em tabelas, mas o cdigo duplica de dimenso. A construo efetuada a partir das mesmas tabelas depois de compactadas. Redues so codicadas como:
reduce_M: ao semntica associada regra M stack -= n; stack->semantic = yyredval; goto nonterminal_P;

As transies dos no-terminais so codicadas como:


nonterminal_J: switch ((stack-1)->state) { case K: goto state_L; ...

Compiladores2012 , Anlise ascendente

9-12

Compiladores2012 , Anlise ascendente

9-13

Aes em analisadores LALR(1) hardcoded


As aes baseiam-se no conceito de shift state - estados de destino de operaes de deslocamento, efetuando o deslocamento no destino. (por exemplo, se existe s2 ento o estado 2 um shift state) As aes so codicadas como:
state_N: stack->state = N; stack->semantic = yylval; token = yylex(); // se shift state if (++stack == EOS) goto stack_overflow; state_action_N: switch (token) { case Q: goto state_X; case R: goto reduce_Y; case S: goto error_handler; case T: YYACCEPT; default: goto error_handler; // ou reduce_Z

Recuperao de erros: smbolo erro


o utilizador inclui na gramtica regras para recuperao de erros em locais especcos, utilizando um smbolo de erro especial nessas regras. em caso de erro ( acesso a uma posio da tabela sem uma operao vlida ): 1. vericar se existe um deslocamento do smbolo de erro para esse estado, caso no exista retirar sucessivamente smbolos da pilha at atingir um estado que desloque o smbolo de erro. 2. avanar sucessivamente na sequncia de entrada at atingir um smbolo de anteviso para exista uma ao que no seja de erro. 3. se a ao for uma reduao possvel que o smbolo de anteviso venha a causar novo erro, pelo que devem ser evitadas regras cuja derivao seja apenas o smbolo de erro. cuidado: aes semnticas com efeitos secundrios podem car por executar.

Compiladores2012 , Anlise ascendente

9-14

Compiladores2012 , Anlise ascendente

9-15

Recuperao de erros: panic-mode


recuperao de erros em analisadores ascendentes difcil, pois a pilha contm os elementos lidos, mas no inclui informao sobre o que esperado. Uma tcnica, designada por panic-mode, usa a prpria tabela: 1. guardar uma cpia da pilha do analisador; 2. retirar o elemento do topo e vericar se existe uma entrada vlida na tabela. Se existir a recuperao est concluda; 3. se no existir entrada vlida voltar a 2. at esvaziar a pilha; 4. quando a pilha ca vazia, avanar um elemento lexical, repor uma cpia da pilha inicial (antes do erro) e voltar a 2.; 5. se se atingiu o m do cheiro (ltimo elemento lexical), no foi possvel recuperar do erro. Devido ao risco de erros em cascata, no imprimir mensagens nos 4 a 5 passos (deslocamentos ou redues) que se seguem ao erro.

LR cannico: LR(1)
O autmato LR(1) construdo a partir da gramtica aumentada, replicando os itens de cada regra para todos os smbolos de f ollow do smbolo no terminal que deriva. As transies vazias ( ) so construdas apenas para os itens cujo f ollow corresponde ao lookahead desse no terminal no item de origem da transio. Por exemplo, X : .Ab, $ A : .Y Z, b, onde $ e b so os f ollows dos itens. A tabela de redues construda individualizando os smbolos de f ollow de cada regra. Agrupamento de estados LALR(1): dois estados do analisador LR(1) so agrupados se tiverem os mesmos itens e estes itens diferirem apenas nos smbolos de anteviso.

Compiladores2012 , Anlise ascendente

9-16

Compiladores2012 , Anlise ascendente

9-17

Analisadores quase LALR(1)


Se gramtica for LR(1) mas no for LALR(1) podemos contruir um analisador quase LALR(1): Construir o analisador LR(1) e agrupar os estados: ao agrupar dois estados compatveis podemos forar outros estados no compatveis a serem agrupados, provocando um conito reducereduce. em caso de gerar conito fazer backtrack e tentar outros agrupamentos. a ordem de agrupamento pode inuir no nmero nal de estados ( o nmero mnimo s pode ser obtido depois de tentadas todas as ordenaes ). Agrupar os estados medida que vo sendo identicados: algoritmo de Pager.

Algoritmo de Pager
Compatibilidade fraca: agrupar 2 estados, s e s, com o mesmo ncleo se para todos os pares de conjuntos de anteviso dos seus itens: L1 L2 = L1 L2 = L1 L2 = L1 L2 = Compatibilidade forte: agrupar estados rejeitados pela compatibilidade fraca mas onde o potencial conito nunca atingido: vericar se as regras, cujos itens incluem os smbolos que geram o conito, fazem parte dos mesmos estados at respetiva reduo. usar o algoritmo de backtracking nos estados do analisador quase LALR(1) gerado.

Compiladores2012 , Anlise ascendente

9-18

Compiladores2012 , Anlise ascendente

9-19

Analisadores LR(k), k > 1


utilizam os conjuntos f irstk e f ollowk para determinar o k-simo smbolo dos no terminais para os analisadores SLR(k), LALR(k) e LR(k). estas generalizaes aumentam as classes de gramticas que podem ser processadas: LR(0) LR(1) . . . LR(k) LR(k + 1) onde LR(k) designa designa o conjunto de gramticas processveis por uma tcnica LR com k smbolos de anteviso. para cada tcnica LR com k smbolos de anteviso temos ainda que: LR(k 1) SLR(k) LALR(k) LR(k) SLR(k + 1). contudo a dimenso das tabelas cresce rapidamente com k. as gramticas que exigem k > 1 podem ser transformadas em SLR(1). todas as linguagens analisveis deterministicamente tm gramticas SLR(1).

Analisadores ascendentes LR
nem todas as gramticas livres de contexto so LR. uma gramtica ambgua nunca LR. como o nmero de smbolos de anteviso xo, apenas linguagens e gramticas deterministicas podem ser tratadas. contudo, um analisador LR : eciente: proporcional dimenso da entrada. correto: deteta todas as entradas no vlidas e produz resultados corretos para entradas vlidas. no ambguo: produz resultados deterministas. linear no espao e no tempo face ao nmero de tokens de entrada.

Compiladores2012 , semntica

10-1

Compiladores2012 , semntica

10-2

rvore sinttica
Uma rvore sinttica uma representao sinttica, mas a sua construo , em geral, considerada semntica pois efetuada por aces semnticas. Cada n da rvore, modelado como uma estrutura com vrios campos, designa um operador ou operando da linguagem. Cada operador identicado por um atributo no n da rvore, incluindo este n ponteiros para os seus operandos. Os ns podem conter espao para conter informao adicional sobre o operador e o seu contexto de utilizao.

Construo da rvore sinttica


A rvore constituda por valores literais nas folhas e operadores nos ns, todos designados pela estrutura N ode. Cada N ode permite associar um atributo, que descreve a funcionalidade, e um ponteiro para uso genrico (user). Na impresso pode ser fornecida uma tabela de cadeias de carateres contendo a designao dos atributos. Por exemplo, onde tab[OP add] == add. O tipo e o atributo de cada n podem ser alterados independentemente, desde que o tipo coincida com os valores armazenados, permitindo substituir: um argumento formal de uma rotina pela sua posio. uma cadeia de carateres pelo nmero do label que a identica.

Compiladores2012 , semntica

10-3

Compiladores2012 , semntica

10-4

Construo da rvore sinttica


Construo dos ns da rvore: sem valor: N ode nilN ode(int attrib) inteiro: N ode intN ode(int attrib, int value) real: N ode realN ode(int attrib, double value) string: N ode str(int attrib, char value) dados opacos: N ode dataN ode(int attrib, int size, void data) operadores: N ode subN ode(int attrib, int nops, ...) N ode addN ode(N ode base, N ode node, unsigned pos); Funes auxiliares dados auxiliares: void userN ode(N ode p, void user) libertar recursivamente o sub-ramo: void f reeN ode(N ode p) imprimir a rvore: void printN ode(N ode p, F ILE f p, char tab[])

Exemplo de construo da rvore sinttica


... %union { int i; char *s; Node *n; } %token<i> INT %token<s> ID STRING %type<n> expr decls ... %% file: decls { printNode($1, 0); freeNode($1); } ... expr: expr + expr { $$ = subNode(OPadd, 2, $1, $3); } | - expr { $$ = subNode(OPuminus, 1, $2); } | INTEGER { $$ = intNode(OPint, $1); } | STRING { $$ = strNode(OPstr, $1); } | ID { $$ = strNode(OPid, $1); } ...

Compiladores2012 , semntica

10-5

Compiladores2012 , semntica

10-6

Manipulao de nomes
visibilidade: capacidade em aceder ao valor de uma varivel atravs do seu nome: esttica ou lxica: determinvel em tempo de compilao. dinmica: determinvel em tempo de execuo. alcance: capacidade em aceder ao valor de uma varivel. tempo de vida: tempo que media entre a criao da varivel e a sua destruio: global: desde o incio da execuo at ao m. local: desde o incio do bloco/funo at ao m. heap: criado pelo utilizador e libertado por este ou por garbage collector. nome do smbolo

Registo de alcance
Registo de alcance: permite a determinao das caractersticas de um smbolo:

classe do smbolo: label, funo, varivel, array, ... tipo do smbolo: inteiro, oat, double, ... informao especca do tipo: limites do array, nmero e tipo dos argumentos de uma funo, ... endereo onde o smbolo reside, se j estiver denido. lista de locais onde foi referido e ainda no foi colocado o endereo.

Compiladores2012 , semntica

10-7

Compiladores2012 , semntica

10-8

Tabela de smbolos
Tabela de smbolos: estrutura que permite determinar, em cada ponto do programa, os smbolos visveis: por alcance: uma rvore onde os ns incluem os smbolos com o mesmo alcance (correspode aos blocos da maioria das linguagens de programao). global: uma lista nica onde cada registo inclui informao sobre o incio e m do alcance de um smbolo. tipos de tabelas de smbolos: tabela, lista, rvore ou tabela de disperso (hash table). forward declaration: torna visvel um smbolo ( varivel/funo ) que est no alcance da declarao. (permite o acesso a nomes no locais)

tabid: uma tabela de smbolos linear


Denido nos cheiros tabid.h e tabid.c: int IDnew(int tipo, char smbolo, int atributos): introduz um novo smbolo no nvel corrente com o tipo e atributos indicados. Devolve 1 se j existir neste nvel e 0 caso contrrio. void IDpush(void): cria um novo nvel (bloco). void IDpop(void): retira o ltimo nvel. int IDnd(char smbolo, int atributo): procura um smbolo desde o nvel atual at ao primeiro nvel (global). Devolve 0 caso o smbolo no seja encontrado ou o tipo passado em IDnew. Caso o ltimo argumento seja no nulo preenchido com os atributos do smbolo. void IDroot(void swap): troca a origem da tabela, devolvendo a antiga raiz.

Compiladores2012 , semntica

10-9

Compiladores2012 , semntica

10-10

Tipos de dados
tipo de dados: um conjunto de entidades caracterizadas por uma representao estrutural e um conjunto de operaoes que lhe conferem um comportamento comum. tipo de dados abstrato: denido apenas pelas operaes que oferece. consistncia de tipos: regras que determinam se uma operao pode atuar sobre um tipo. fraca: o sistema de tipos adapta implicitamente o tipo existente ao tipo necessrio. forte: os tipos devem ser compatveis (podem ser sub-tipos). A converso deve ser efetuada pelo programador atravs de funes ou casts. equivalncia de tipos: quando dois tipos so considerados o mesmo tipo (estrutural ou por nome).

Tipos das linguagens


tipos bsicos: tipos de dados dendos na maioria dos processadores: carateres: sem operaes especiais alm de cpia. inteiros: artimtica bsica e eciente. vrgula utuante: operaes matemticas complexas e lentas. tipos construdos: derivados dos tipos bsicos com suporte no processador: ponteiros: acesso indireto a posies de memria (um inteiro com uma interpretao diferente). vetores: operaes de referenciao e desreferenciao. funes: sequncias de carateres com instrues e dados imediatos do processador. tipos compostos: classes, estruturas, enumerados e unies.

Compiladores2012 , semntica

10-11

Compiladores2012 , semntica

10-12

Tipicao
tipicao: ato de vericao de consistncia de tipos: esttica: executada no momento da compilao. dinmica: executada durante a execuo, no momento do acesso. (message not understood em Smalltalk) subtipo: um tipo diz-se subtipo de outro tipo se realizar todas as suas operaes com a mesma semntica, podendo acrescentar estrutura e operaes. sub-tipicao: denio de um tipo a partir de outro: explcita: por extenso atravs da especializao explcita de um tipo existente; ajuda a menter a semntica mas no a garante (herana). implcita: relacionamento entre dois tipos quaisquer onde um tipo subtipo de outro (mais geral e exvel, mas mais perigoso).

Polimorsmo
Polimorsmo: os valores, variveis e funes podem ter mais de um tipo simultaneamente. Reduz a complexidade (menos nomes de funes) e melhora a abstraco (o mesmo nome usado para a mesma operao em entidades distintas). sobreposio (overloading): escolha do mtodo que realiza a operao depende do nmero e tipo de argumentos (muti-mtodos). coero: converso de tipos explcita (casts) ou implcita (tipicao fraca). incluso (overriding): escolha do mtodo que realiza a operao depende do tipo de objeto criado e no do tipo declarado. Apesar da tipicao esttica o binding no pode ser esttico. paramtrico (ou genericidade): o tipo determinado por um parmetro atual na instanciao. A declarao construda custa de um tipo formal (abstrato).

Compiladores2012 , semntica

10-13

Compiladores2012 , semntica

10-14

Binding (resoluo de nomes)


Binding determinao da realizao a utilizar por um smbolo: Quando o programa escrito Quando o programa compilado Quando o programa editado, mas antes do seu carregamento (biblioteca esttica) Qaundo o programa carregado (biblioteca dinmica) Quando um registo de base, usado para endereamento, carregado (Objectoriented) Quando a instruo contendo o endereo executada.

Vericaes estticas
Tudo o que poder ser vericado em tempo de compilao no deve ser deixado para a execuo: Vericao de tipos: determinao da compatibilidade entre dados e operaes. Vericaes de uxo de controle: break dentro de switch e ciclos, etc. Vericaes de existncia e unicidade: de identicadores e labels. Vericaes de contexto: tags no incio e m dos blocos em Ada ou Visual basic.

Compiladores2012 , semntica

10-15

Compiladores2012 , semntica

10-16

rvores de ativao
A denio de uma rotina constituda por um nome, um conjunto de parmetros formais e um corpo. Uma ativao de uma rotina, ou chamada rotina, constituda por um nome e um conjunto de parmetros atuais. A rvore de ativao o conjunto de ativaes em uso num determinado instante. Uma rotina recursiva permite criar mais de uma ativao dessa rotina na rvore. (a recurso pode ser indireta) Se duas ativaes, de rotinas distintas, no se sobrepoem na rvore ento as rotinas no so aninhadas. a pilha, quando existe, a forma mais usada para construir a rvore de ativao das rotinas.

Registo de ativao (stack frame)


Valores dos parmetros atuais. Podem ser endereos (passagem por referncia), nomes (passagem por nome), etc. Contador do nmero de argumentos, se for desconhecido no momento da compilao Endereo de retorno rotina chamadora. Valores de retorno (em C as rotinas retornam no mximo um s lavor e o retorno feito no acumulador) e sua localizao (registos, pilha ou memria). Endereo do registo de ativao anterior (frame pointer) Variveis locais da rotina chamada. Compilao separada implica que a construo do registo de ativao feito em colaborao pelas duas rotinas.

Compiladores2012 , semntica

10-17

Compiladores2012 , semntica

10-18

Passagem de argumentos
valor: o valor (rvalue) do parmetro colocado no registo de ativao. As modicaes efetuadas na rotina chamada no afetam o valor original. referncia: o endereo (lvalue) do parmetro colocado no registo de ativao. As modicaes efetuadas na rotina chamada afetam diretamente o valor original. copy-restore: passagem por valor em que o resultado copiado de volta para a varivel aps o retorno da funo. Idntico passagem por referncia, mas imune aos efeitos laterais (side effects). call-by-name: a rotina comporta-se como uma macro sendo expandido no local da chamada. (#define do C) call-by-need: idntico ao call-by-name mas preservando o compartilhamento de avaliaes, ou seja, evita avaliaes repetidas. (inline do C++)

Convenes de chamada
Existem diversas convenes de chamada denidas por linguagens, compiladores e sistemas operativos (para system calls), mas as mais comuns so: Cdecl: argumentos so avaliados da esquerda para a direita, mas colocados na pilha da direita para a esquerda (primeiro argumento no topo). A rotina chamadora responsvel por retirar os argumentos da pilha e o valor de retorno devolvido no acumulador. Pdecl: mesma ordem de avaliao, mas os argumentos so colocados na pilha da esquerda para a direita. A rotina chamada responsvel por retirar os argumentos da pilha e colocar o resultado no acumulador. STDdecl: igual ao Cdecl mas quem retira os argumentos a rotina chamada.

Compiladores2012 , semntica

10-19

Compiladores2012 , sntese

11-1

Reserva de memria
esttica: com tempo de vida igual durao da execuo do programa podem ser iniciadas (.data), no iniciadas (.bss), constantes (.text), pilha: com tempo de vida igual durao da execuo da rotina podem ser argumentos, variveis locais e temporrias, e reserva dinmica (ver adiante). heap: o tempo de vida controlado pelo programador atravs de chamadas especcas (new/delete), podendo a libertao ser controlada por um garbage collector. a reserva dinmica na pilha (alloca em C) permite criar variveis de comprimento determinado em tempo de execuo, no redimensionveis (o custo de libertao nulo). endereos de entidades criadas na pilha no podem ser devolvidos da rotina que criou essas entidades (dangling pointers).

Sntese
Traduo do programa analisado para um formato de destino, retendo a semntica original da linguagem. Formas mais comuns de sntese: interpretao. traduo dirigida pela sintaxe. traduo dirigida pela rvore sinttica. traduo dirigida por DAG. A sntese , em geral, realizada em trs passos: gerao de cdigo intermdio (processador simplicado imaginrio). gerao de cdigo nal (para um processador especco). otimizao de cdigo (no cdigo intermdio e nal).

Compiladores2012 , sntese

11-2

Compiladores2012 , sntese

11-3

Interpretao
Execuo de um programa por outro programa (o interpretador), em vez do processador da mquina utilizada. Interpretao linha a linha: s para gramticas muito triviais. while(gets(buf)) execute(buf); Interpretao dirigida pela sintaxe: s para linguagens muito simples (sem ifs ou whiles). Interpretao dirigida pela rvore sinttica: muito lento. Interpretao por mquina virtual (Threading): o mais rpido e usado comercialmente. Interpretao de processadores reais (emulao): complexo e lento, quando efetuado exclusivamente por software.

Interpretao dirigida pela sintaxe


Utiliza os dados disponveis na pilha de dados do analisador sinttico: expr: | | | | INTEGER { $$ = $1; } IDENTIFIER { $$ = getValue($1); } IDENTIFIER = expr { setValue($1, $$ = $3); } expr + expr { $$ = $1 + $3; } - expr { $$ = - $2; }

Aproveita a pilha de dados do analisador sinttico para transportar os valores intermdios da interpretao das operaes.

Compiladores2012 , sntese

11-4

Compiladores2012 , sntese

11-5

Interpretao dirigida pela rvore sinttica


Constri a rvore dirigida pela sintaxe e depois interpreta a rvore gerada. Interpretao da rvore: int eval(Node *n) { ... switch(n->type) { ... case OPinteger: return n->value.i; case OPident: return getValue(n->value.s); case OPassign: { int ret = eval(n->value.sub.n[1]); setValue(n->value.sub.n[0].value.s, ret); return ret; } case OPadd: return eval(n->value.sub.n[0]) + eval(n->value.sub.n[1]); case OPuminus: return -eval(n->value.sub.n[0]);

Construo da rvore sinttica


A rvore sinttica construda usando as aces da traduo dirigida pela sintaxe: expr: INTEGER { $$ = intNode(OPinteger, $1); } | IDENTIFIER { $$ = strNode(OPident, $1); } | IDENTIFIER = expr { $$ = subNode(OPassign, 2, strNode(OPident, $1), $3); } | expr + expr { $$ = subNode(OPadd, 2, $1, $3); } | - expr { $$ = subNode(OPuminus, 1, $2); }

Compiladores2012 , sntese

11-6

Compiladores2012 , Postx

12-1

Interpretao por mquina virtual (Threading)


As operaes a executar esto codicadas sob a forma de endereos smblicos, ou sob a forma de cdigos (bytecodes) que representam deslocamentos numa tabela que contm esses endereos. O interpretador executa cada uma dessas operaes em sequncia: routine threading: cada operao codicada numa rotina. case threading: cada operao uma opo da instruo switch do interpretador (s para bytecodes). direct threading: cada operao identicada por um label e, no m da qual, existe um salto direto para a opero seguinte. indirect threading: idntica anterior, mas o salto indireto (esta forma mais vulgar de threading).

Notao postxada: Postx


Notao em que os operandos precendem os operadores (tambm conhecida como reverse polish notation). Por exemplo, (2 + 3) 4 + 5 passa a car 2 3 + 4 5+ ou 5 4 2 3 + + Muito utilizada em como formato intermdio de linguagens, por exemplo, PostScript, Forth, Java, Smalltalk e .net. Facilidade na reconstruo da rvore sinttica a partir do cdigo, para compiladores JIT. Vantagem: grande facilidade de gerao, quer a partir da rvore sinttica, quer dirigida pela sintaxe, podendo ser utilizada como cdigo nal (stack machines) ou cdigo intermdio. O cdigo gerado muito compacto (ocupa pouco espao). Desvantagem: sequencialidade explcita, o que diculta a paralelizao e otimizao.

Compiladores2012 , Postx

12-2

Compiladores2012 , Postx

12-3

Postx: processador imaginrio SL0


SL0: single stack, large stack size, zero operand machine. todos os valores locais so guardados na pilha de dados. Os restantes valores so globais. a pilha tem dimenso ilimitada: no gera overows ( exceto quando no existe mais memria utilizvel ). 3 registos: ip (instruction pointer), sp (stack pointer) e fp (frame pointer). os operandos esto no topo na pilha, sendo substitudos pelo resultado da operao.

Postx: traduo dirigida pela sintaxe


Quer os operandos quer o operador esto na pilha do analisador sinttico: expr: | | | | LITERAL { emit($1.value); } IDENTIFIER { emit($1.name); } expr + expr { emit("add"); } - expr { emit("uminus"); } expr ? jz expr : jmp { emit(".L%d:", $3); } expr { emit(".L%d:", $6); }

; jz : { emit("jz .L%d", ++lbl); $$ = lbl; } ; jmp: { emit("jmp .L%d", ++lbl); $$ = lbl; } ; Vantagem: aparente simplicidade na gerao de cdigo. Desvantagem: introduz aces e regras nulas que podem produzir conitos (em parsers LR(k) com k 1).

Compiladores2012 , Postx

12-4

Compiladores2012 , Postx

12-5

Postx: traduo por rvore sinttica


Cada n da rvore designa um operador e os seus ramos os operandos:
void code(Node *t) { ... switch (n->type) { ... case operador-N: /* operador com M argumentos */ code(n->value.sub.n[0]); ... code(n->value.sub.n[M]); emit("operador-N"); break;

traduo por rvore sinttica: execuo condicionada


gerao de cdigo que implica saltos: if if expr (expr) while L1: expr (expr) then jz L1 instr (instr) else jmp L2; L1: instr (instr) end L1: instr2 (instr2) end L2:

then jz L1

instr1 (instr1) do jz L2

Vantagem: modularidade (separa a sntese da anlise), facilidade na gerao de cdigo. Passo intermdio para a transformao em DAG (otimizao). Desvantagem: obriga construo da rvore sinttica (necessita de memria).

expr (expr)

done jmp L1; L2: L1: L1:

expr1 (expr1) expr1 (expr1)

and dup; jz L1; trash or dup; jnz L1; trash

expr2 (expr2) expr2 (expr2)

Compiladores2012 , Postx

12-6

Compiladores2012 , Postx

12-7

Diretivas de assembler
global : torna smbolos locais acessveis por outros mdulos. extern : torna acessveis smbolos de outros mdulos. common : torna smbolos comuns (partilhados) entre mdulos. align : alinha a memria antes de cada varivel, constante ou funo. segment : altera o segmento corrente .data : dados iniciados por db (dene byte), dd (dene word, 4 bytes). .bss : dados no iniciados por resb (reserve byte). .text : funes (read only). .rodata : constantes e strings literais (read only). Em coff e win32 designa-se por .rdata e no existe em aout.

Questes prticas
Operadores retiram argumentos da pilha e colocam o resultado na pilha. Constantes escalares so empurradas na pilha enquanto variveis so colocadas na rea de dados. Constantes vetoriais, incluindo strings, devem ser colocados na rea de texto pois no podem ser modicados (read only). Um lvalue um endereo no qual pode ser efetuado um store. Um lvalue pode ser convertido num rvalue desreferenciando o endereo com um load. a sequncia de chamada a uma rotina inicia-se colocando os argumentos, com o primeiro argumento no topo, seguido da chamada e, aps o retorno, retirar os argumentos da pilha. uma rotina ao ser chamada cria o novo registo de ativao (stack frame) e reservado espao para as variveis locais; no m, e antes do retorno, deve ser retirado o registo de ativao.

Compiladores2012 , cdigo intermdio C3E

13-1

Compiladores2012 , cdigo intermdio C3E

13-2

Seleo de instrues
A seleo de instrues pode ser crtica em processadores com muitas instrues, que permite realizar a mesma operao recorrendo a diferentes combinaes de instrues (processadores CISC, tipicamente). Em processadores com poucas instrues (processadores RISC ou stackmahines) as escolhas so poucas, ou nenhumas, pelo que a seleo de instrues no crtica. Cada instruo do processador representada como uma rvore padro e por um custo associado. O custo denido arbitrariamente e pode ser utilizado para minimizar o tempo de execuo ou o espao ocupado, por exemplo. Existem dois tipos de algoritmos para a seleo de instrues: maximalmunch e programao dinmica.

Seleo de instrues por maximal-munch


A seleo de instrues por maximal-munch -e um algoritmo greedy que consiste numa s passagem descendente (da raiz para as folhas) de uma rvore sinttica. Em cada passo escolhida a instruo com o padro mais extenso que se adapta ao n em anlise, e a respetivo cdigo gerado. As instrues so geradas por ordem inversa. Como s considera o n em anlise e no os sub-ns a soluo no globalmente tima, apenas localmente tima. O algoritmo muito eciente e produz cdigo de boa qualidade em arquiteturas RISC (instrues de pequena profundidade).

Compiladores2012 , cdigo intermdio C3E

13-3

Compiladores2012 , cdigo intermdio C3E

13-4

Seleo de instrues por programao dinmica


Uma seleo tima necessita de dois passos: primeiro calculam-se todos os custos e no segundo gera-se as instrues de menor custo. Clculo dos custos efetuado das folhas para a raiz (bottom-up), em cada n considera-se a melhor instruo local, qual se soma os menores custos de cada sub-ramo. Notar que ao subir na rvore podem-se ir encontrando instrues mais complexas e de menor custo que a seleo local. A escolha das instrues efetuada da raiz para as folhas, como no maximalmunch, mas tendo em conta os custos timos em cada n. O algoritmo indicado para processadores com grande combinatria de instrues, mas mais lento pois exige dois passos e, para processadores mais complexos, a rvore maior.

Gramticas burg
O formato das regras constitudo por uma etiqueta seguido da instruo; depois da atribuio indica-se o nmero da regra (para identicar o cdigo a gerar e, entre parentesis, o custo associado instruo a gerar. stat: mem: mem: reg: reg: reg: reg: reg: mem: mem: reg: mem: mem = 0 (0); store(reg) store(cte) load(mem) load(cte) add(reg,reg) add(reg,cte) add(reg,mem) add(mem,cte) add(mem,reg) uminus(reg) uminus(mem) = = = = = = = = = = = 1 2 3 4 5 6 7 8 9 10 11 (19); (20); (18); (4); (3); (4); (19); (31); (30); (3); (30);

Compiladores2012 , cdigo intermdio C3E

13-5

Compiladores2012 , cdigo intermdio C3E

13-6

Clculos dos custos (labeling)


Construir os pares <ast-node, op-tree>, garantindo que os ramos do n intermdio concordam com os no-terminais dos ns lhos. Usar apenas 1 operao por ast: x : op1(a, op2(b, c)) x : op1(a, a ) a : op2(b, c) Tile(n) Label(n) <- 0 Tile(child[0]) ... Tile(child[k]) for each rule that matches n if child[r] in Label(child[n]) and ... Label(n) <- Label(n) U {r} Utilizao de custos dinmicos obriga a fazer labeling no gerador. Pode ser necessrio devido a spilling e scheduling dos dados (para evitar latncia).

gerador Burg e derivados


Burg: Recebe uma rvore com a representao intermdia e calcula os custo quando o gerador produzido, logo os custos so estticos. Iburg: ao contrrio do Burg, calcula os custos quando o gerador executa, logo os custos podem ser dinmicos. Gburg: utiliza uma expresses regulares, logo produz uma mquina de estados nita (FSM), gerando as instrues num s passo. Tal estrutura adapta-se s representaes de bytecodes postxados. Utiliza um algoritmo greedy e produz cdigo ao dobro da velocidade do Iburg pburg: semelhante ao Iburg, mas com suporte para custos dinmicos, blocos de cdigo, acesso ao y.tab.h, etc.

Compiladores2012 , cdigo intermdio C3E

13-7

Compiladores2012 , cdigo intermdio C3E

13-8

Escalonamento de instrues
Uma multiplicao pode ter uma grande latncia, ou seja, leva muito tempo a produzir o resultado a partir dos dados. No entanto, o resto dos registos est livre e podem ser efetuadas outras operaes (somas, por exemplo) enquanto o resultado da multiplicao no estabiliza. Escalonamento de instrues consiste em alterar a ordem de execuo das instrues por forma a tirar proveito das limitaes de desempenho do processador. Por exemplo, assumindo mul = 2, store = 3, add = 1 e load = 3, a expresso w = w2xyz pode gastar 22 ciclos (load, add, load, mul, load, mul, load, mul, store) ou 13 ciclos (load, load, load, add, mul, load, mul, mul, store), como se pode vericar pelos tempos de incio e m de cada instruo.

Grafo de dependncia e instrues acessveis


Renomear as denies para evitar antidependncias: cada nova denio de uma varivel recebe um novo nome (SSA ou C3E, por exemplo). Construir o grafo, percorrendo sequencialmente as instrues pela ordem inicial. Cada operao representa constitui um novo n que representa o novo valor calculado. Os ramos, dirigidos, indicam os valores utilizados na operao e so etiquetados com a latncia da operao corrente. Atribuir prioridades a cada operao, para determinar quais as instrues a selecionar em cada passo do escalonamento. A ordenao mais comum utiliza o caminho cuja soma das latncias maior como primeira escolha. Manter uma lista de instrues acessveis (ready), em cada momento. Esto acessveis todas as instrues cujos operandos estejam disponveis.

Compiladores2012 , cdigo intermdio C3E

13-9

Compiladores2012 , cdigo intermdio C3E

13-10

Escalonamento da instrues por lista


O escalonamento efetuado por simulao abstrata: t <- 0; Ativas <- {}, Ready <- Graph leaves while (Ready U Ativas <> {}) if (Ready <> {}) remove Op from Ready and add to Ative Start(Op) <- t t <- t + 1 for each Op in Ativas if (Start(Op) + Delay(Op) < t) remove Op from Ative for each sucessor S of Op in Graph if (S is ready) add S to Ready

Utilizao de registos genricos


Os registos disponibilizados pelo processador sem funo especca designamse por genricos, excetua-se IP, SP, FP e flags. No confundir com a classe do registo, ou seja, o tipo de operaes a que pode ser sujeito, por exemplo, registo de base em operaes de indexao ou registo contador. Existem processadores sem registos genricos (stack-machines), com apenas um registo (accumulator-machines), com poucos (< 16) registos (CISC-machines) e muitos ( 16) registos (RISC-machines). O registos genricos podem ser usados para: resultados intermdios da avaliao de expresses reutilizao de resultados de expresses contedo de variveis frequentemente utilizadas parmetros ou resultados de funes,

Compiladores2012 , cdigo intermdio C3E

13-11

Compiladores2012 , cdigo intermdio C3E

13-12

Atribuio de registos
A atribuio de registos efetuada depois do cdigo fonte ter sido analisado, otimizado, traduzido para cdigo mquina e, por vezes, escalonado. Os registos so a memria de acesso mais rpido, mas o nmero de registos limitado, em cada classe: endereo, inteiro, vrgula utuante, ... A atribuio de registos procura reduzir: nmero de acessos a memria: acessos a cache so 2 mais lentos, a memria so 2 a 10 mais lentos e a disco (swapping) 100 a 10000 mais lentos. spilling (ou relegao): instrues que salvaguardam e repoem o contedo de registos, em geral por falta de registos disponveis. O processo baseia-se em criar um novo registo simblico para cada valor calculado, cando a atribuio efetiva de registos para uma fase posterior.

Mtodos de atribuio de registos


A atribuio de registos deve atribuir registos fsicos s instrues j geradas e introduzir instrues que movimentem os valores entre registos (no caso de registos no uniformes) e entre registos e memria. Se o nmero de registos no for suciente acrescenta-se cdigo (spill code) para guardar e repor o valor de registos em uso. O objetivo consiste em minimizar o spill code necessrio atravs da alterao da ordem de avaliao. A atribuio de registos pode ser precedida por uma fase de reserva, onde os registos de cada instruo so pr-escolhidos e os spills necessrios gerados. Existem diversos mtodos de atribuio de registos: local: top-down, ordenao de subrvores e prximo uso. global (para alm dos blocos bsicos): greedy, linear-scan, next-use ou colorao de grafos.

Compiladores2012 , cdigo intermdio C3E

13-13

Compiladores2012 , cdigo intermdio C3E

13-14

Spilling
o DAG minimiza a reavaliao de subexpresses comuns; o spill , em grande medida, o resultado da ganncia em evitar as reavaliaes. o n que representa a subexpresso comum modicado para guardar o valor obtido, de tal forma que posteriores referncias obtenham esse valor. spilling envolve 3 passos: 1. identicar os registos a libertar (spilled registers) 2. gerar o cdigo que salvaguarda o valor do registo 3. gerar, no local apropriado, o cdigo que recarrega o valor salvaguardado.

Atribuio de registos top-down


Heurstica: os valores mais utilizados so mantidos em registos. Para tal conta o nmero de ocorrncias de cada registo virtual no bloco bsico, usando a respetiva frequncia para denir as prioridades. Se houver mais registos virtuais que fsicos, devem ser deixados 2 a 4 registos livres para carregar 2 operandos e guardar o resultado. Percorrer a lista linear de instrues, contando as ocorrncias de cada registo virtual, e ordenar por ordem decrescente do nmero de ocorrncias. Atribuir os k registos mais utilizados. Numa segunda fase, percorrer a lista de instrues atribuindo registos temporrios aos registos ainda no atribudos, introduzindo as instrues de load e store necessrias. Problema: registos s usados no incio do bloco no so libertados.

Compiladores2012 , cdigo intermdio C3E

13-15

Compiladores2012 , cdigo intermdio C3E

13-16

Ordenao de subrvores (Sethi & Ullman)


Minimizar o nmero de registos necessrios comeando por avaliar a subrvore que necessita de maior nmero de registos. A primeira passagem determina o nmero de registos necessrios (labeling): trivial bsico unrio binrio 0 1 max(1,need[child]) 1 + need[left] max(1,need[left],need[right])

Atribuio de registos greedy


Ocupar os registos sequencialmente, registando a data da ocupao (nmero de sequncia da instruo, por exemplo). Quando no existem registos disponveis, retirar o registo ocupado mais tempo. (Claro que pode ser, precisamente, aquele que vai ser utilizado na instruo seguinte!) Pode ser melhorado mantendo a informao dos registos limpos (registos que foram carregado de memria e ainda no foram modicados) e sujos (cujo valor foi alterado pelo processador e ainda no foi guardado). Optar pelo registo limpos ocupado mais tempo para evitar o spilling. Como pode nem ser necessrio o reload, a reutilizam de um registo limpos pode ter custo zero.

need[left] == need[right] need[left] != need[right]

Na segunda passagem avaliar a subrvore que necessita de maior nmero de registos, efetuando a atribuio de registos (top-down) e gerar o cdigo pela ordem de avaliao (bottom-up). O cdigo gerado s timo se os registos forem uniformes, mas no otimiza subexpresses comuns.

Compiladores2012 , cdigo intermdio C3E

13-17

Compiladores2012 , cdigo intermdio C3E

13-18

Atribuio linear de registos


A atribuio linear de registos usa cdigo j linearizado (sem considerar blocos bsicos) e constroi uma lista ordenada com o intervalo de vida de cada uma das variveis. Cada instruo intermdia (linearizada) atribudo um nmero com base no qual so denidos os limites do intervalo. Numa aproximao conservadora podem existir subintervalos em que a varivel no est ativa. Um outro algoritmo, designado por binpacking, controla igualmente os subintervalos (lifetime holes) mas consome muito mais tempo. A atribuio de registos efetuada de uma forma sequencial e so efetuados spilling sempre que no existem registos sucientes.

Algoritmo de Linear Scan


Construir uma lista de intervalos, representando cada um o tempo de vida de cada varivel, ordenada por ordem crescente de primeira utilizao. Percorrer a lista e atribuir variveis a registos, enquanto houver registos disponveis. Se no houver registos fazer spilling. Manter uma outra lista de variveis ativas, ordenadas por ordem crescente de m de vida. Antes de cada nova atribuio, retirar as variveis que entretanto expiraram. Para fazer spilling, considerar a ltima varivel ativa: aquela cujo m de vida mais distante. Se o seu m de vida for inferior ao da nova varivel, manter a atribuio existente ( fazer spilling da nova varivel), caso contrrio fazer spilling do registo e ocup-lo com a nova varivel.

Compiladores2012 , cdigo intermdio C3E

13-19

Compiladores2012 , cdigo intermdio C3E

13-20

Atribuio de registos por prximo uso


Atribuio de registos com base numa tabela de smbolos de variveis vivas e indicao de prximo uso. Uma varivel est viva se voltar a ser usada. Comear no m do bloco com todas as variveis do programador vivas e todas as variveis temporrias mortas. Nenhuma varivel tem o prximo uso preenchido. Recuar at ao incio do bloco, executando em cada instruo: 1. Retirar da tabela de smbolos a informao sobre cada varivel utilizada na instruo, morta ou viva e respetivo prximo uso (se viva) e associar instruo; 2. Atualizar a tabela de smbolos considerando: cada argumento como tendo a instruo corrente como prximo uso; a varivel atribuda, caso exista, marcada como morta e sem prximo uso.

Atribuio de registos por prximo uso (2)


Exemplo: d = (a - b) + a V C3E b V 1 u=ab c V 2 v =ca d V u M 3 w =u+v v M 4 x=d+b w M 5 y =c+1 x M 6 z =xy y M 7 d=wz z M (c - a) - (d + b) * a vivas mortas b u:3 a:2 b:4 c v:3 c:5 a:d w:7 uv u x:6 b:d v w y:6 c:x z:7 xy y d:wz z (c + 1) 1 1 2 4 M M M M M M

Compiladores2012 , cdigo intermdio C3E

13-21

Compiladores2012 , cdigo intermdio C3E

13-22

Atribuio de registos por prximo uso (3)


A tabela de smbolos em cada passo : passo 1 2 3 4 5 6 7 linha 7 6 5 4 3 2 1 C3E d=wz z =xy y =c+1 x=d+b w =u+v v =ca u=ab a V b V c V 5 4 2 1 2 1 M 4 3 3 M M M d V M u M v M w M 7 x M 6 y M 6 M z M 7 M

Atribuio de registos por prximo uso (4)


usar o registo (R) se a varivel j existe em (R) e (R) no usado tambm por outra varivel e a varivel est morta (e sem prximo uso) se existir um registo livre, us-lo selecionar um registo em uso com base numa tabela de registos (o que o registo contm) e numa tabela de endereos (onde existe o valor atual da varivel: memria e/ou registo). instrues de atribuio, a = b, colocam duas variveis no mesmo registo. variveis que cam sem prximo uso libertam o respetivo registo, antes de guardar o resultado. no m do bloco, guardar as variveis vivas.

Compiladores2012 , cdigo intermdio C3E

13-23

Compiladores2012 , cdigo intermdio C3E

13-24

Atribuio de registos por prximo uso (5)


O exemplo, d = (a - b) + (c - a) - (d + b) * (c + 1), pode ser codicado com 4 registos e sem reloads: a:r1 1 load a, r1 load b, r2 a:r1 b:r2 sub r1, r2, r3 a:r1 b:r2 u:r3 a:r1 b:r2 u:r3 c:r4 2 load c, r4 sub r4, r1, r1 v:r1 b:r2 u:r3 c:r4 3 add r3, r1, r1 w:r1 b:r2 c:r4 w:r1 b:r2 d:r3 c:r4 4 load d, r3 add r3, r2, r2 w:r1 x:r2 c:r4 5 add r4, 1, r3 w:r1 x:r2 y:r3 6 mul r2, r3, r2 w:r1 z:r2 7 sub r1, r2, r1 d:r1 store r1, d

Atribuio de registos por colorao


Construo de um grafo de interferncias: ns: so live ranges (variveis, temporrios, registos virtuais/simblicos) que so candidatos para a reserva de registos. arcos: ligam as live ranges que interferem, ou seja, que esto simultaneamente ativas pelo menos num ponto do programa. Assim, argumentos distintos de uma mesma operao correspondem a variveis que no podem ser atribudas ao mesmo registo. A colorao do grafo consiste atribuir cores, tantas cores quanto o nmero de registos disponveis, aos ns de tal forma que ns que interferem possuem cores distintas (problema dos mapas polticos).

Compiladores2012 , cdigo intermdio C3E

13-25

Compiladores2012 , optim

14-1

Impossibilidade de colorao
Quando no existem cores sucientes necessrio remover alguns ns at que seja possvel a colorao. Os ns removidos tero de ser spilled. O objetivo consiste em obter um grafo colorvel em que o custo das operaes de spilling seja mnimo. Isto no signica fazer um nmero mnimo de remoes de ns, j que certos ns provocam vrios spills. Quando uma origem e o destino de uma operao no esto interligados nos grafo de interferncias, os respetivos ns podem ser fundidos num s e a operao de cpia de registos eliminada. Contudo, esta tcnica de fuso, designada por coalescing, quando usada em exagero pode conduzir a grafos no colorveis e a mais spilling.

Otimizao
Preservar o signicado do programa original melhorando-o signicativamente: gerao de cdigo timo um problema indecidvel heursticas podem gerar cdigo bom, mas no timo. dever afetar signicativamente o desempenho do programa. Melhorar o resultado nal do programa eliminando instrues: inacessveis: instrues que nunca conseguem ser executadas. redundantes: instrues que no alteram o estado da aplicao. lentas: conjuntos instrues equivalentes que executam mais depressa. pesadas: conjuntos instrues equivalentes que ocupam menos memria e/ou registos do processador.

Compiladores2012 , optim

14-2

Compiladores2012 , optim

14-3

Tipos de otimizao
utilizador: efetuadas pelo programador (ou aplicao) quando gera cdigo fonte. genrica: efetuada no cdigo intermdio e independente do processador alvo. peephole: considera apenas uma janela de instrues consecutivas. local: otimizao dentro de um bloco bsico. global: uxo de informao entre blocos, essencialmente ciclos.

Blocos bsicos
Sequncia de comandos consecutivos onde o uxo de controlo comea na primeira instruo e termina na ltima, sem possibilidade de desvio exceto na ltima instruo: um bloco bsico comea numa etiqueta (ou etiquetas consecutivas) ou na instruo que se segue a um salto. um bloco bsico termina numa instruo de salto ou na instruo que antecede uma etiqueta. As transformaes num bloco bsico tm de preservar a semntica atmica do bloco: eliminao de subexpresses comuns troca da ordem de execuo de instrues independentes renomeao de variveis

Compiladores2012 , optim

14-4

Compiladores2012 , optim

14-5

Subexpresses comuns num bloco bsico


Guardar referncias para todos os ns criados. Procurar os ns que representam os argumentos de uma operao, dependendo da sua aridade. Se o n no existir ento deve ser criado. Se os ns de todos os argumentos j existiam, procurar um n com a mesma operao que ligue os mesmos argumentos, ou seja, uma subexpresso comum. Ao gerar o grafo dirigido acclico (DAG), considerar a atribuio simples (a := b) que acrescenta uma etiqueta ao n, bem como o facto de qualquer atribuio a uma etiqueta mover uma anterior referncia para o n atual. O algoritmo pode ser realizado com recurso a uma pilha auxiliar para memorizar os argumentos, quer o cdigo intermdio seja C3E ou postxado.

Gerao das instrues a partir de um DAG


Num grafo, um n constitudo apenas por origens de arcos designado por uma fonte, enquanto um n constitudo apenas por destinos de arcos designado por sorvedoro. A ordenao topolgica de um DAG baseia-se em numerar sucessivamente as fontes, por ordem crescente, retirando-as de seguida, at no haver mais ns. Se na escolha da fonte se optar pelo lho mais esquerda da ltima fonte retirada, o cdigo gerado de qualidade superior pois valor calculado pela instruo ca diretamente acessvel num registo. A gerao de cdigo (s C3E) efetuada pela ordem inversa da numerao efetuada, ou seja, pode ser realizado com recurso a uma pilha auxiliar sem necessitar de numerao. (a lista de fontes do DAG pode ser tambm mantida numa pilha).

Compiladores2012 , optim

14-6

Compiladores2012 , optim

14-7

Exemplo de selection sort


Considere-se a expresso: x[i] = y[i] + i + 1 representada pelo DAG abaixo, onde os ns esto etiquetados pela ordem inversa em que devem ser geradas as respetivas instrues:
1

Exemplo de selection sort


Considere-se o algoritmo de ordenao:
void sort(int *vec, int siz) { int i, j, max, tmp; for (i = siz; i > 1; i--) { max = 1; for (j = 2; j < i; j++) // o maior if (vec[j] > vec[max]) max = j; if (max != i) { // colocar no lugar tmp = vec[i]; vec[i] = vec[max]; vec[max] = tmp; } } }

= +
4

+
6

+
8

x
7

y
11

+ i

10

12

Compiladores2012 , optim

14-8

Compiladores2012 , optim

14-9

Grafo de uxo de controlo


Um grafo de uxo de controlo representa as dependncias entre blocos bsicos:

Clculo de dominantes
Um n Bi domina um n Bj se tivermos de passar por Bi para atingir Bj . Bi um dominante imediato de Bj se Bi for o ltimo dominador antes de atingir Bj . Os dominadores podem ser representados como um rvore, ou seja a dominao uma ordenao parcial.
B11 B9 B8 B10 B3 B4 B6 B5 B7

B11

B8

B9

B10

B1

B2

B3

B4

B5

B6

B7

B1

B2

Compiladores2012 , optim

14-10

Compiladores2012 , optim

14-11

Deteo de ciclos
se a origem de um arco dominado pelo destino do arco ento existe um ciclo. (ciclos so importantes em otimizao pois representam a maioria do tempo de execuo)

Melhorar o desempenho
predio de saltos (branch prediction): reduzir saltos, reduzir chamadas indiretas, inlining, tail-recurse, prefetch consistente com predio esttica. esperas de memria (memory access stalls): store forwarding, alinhamento, evitar cdigo automodicvel, evitar converses de tipos, arrumao de estruturas, evitar variveis globais, restringir alcance (static), constante em rodata, prefetching. seleo de instrues: reduzir a latncia (mul->shift->inc->add), evitar instrues complexas (micro-cdigo). sequenciao de instrues (instruction scheduling): calcular endereos o mais cedo possvel, ter em conta a latncia das instrues, evitar load store. vectorizao: tipos de dados o mais pequenos possvel, evitar condies, varivel de ciclo com base em expresses simples, evitar lexically-backward dependence

B11 B1 B2 B3
dominante imediato fluxo no dominante ciclo detectado

B9 B8 B10 B4 B6 B5 B7

Compiladores2012 , optim

14-12

Compiladores2012 , optim

14-13

Otimizao pelo utilizador


Melhorar o programa pode degradar a sua legibilidade, manuteno e evoluo: zonas a otimizar: apenas as partes mais executadas (programas gastam 90% do tempo em 10% do cdigo), usar sempre um proler. substituio de algoritmos: mais ecientes ou que ocupem menos espao (bubble vs quick sort). transformaes de ordem elevada: aquelas que pela sua complexidade, ou falta de informo, dicilmente podem ser efetuadas por um compilador. otimizaes independentes da mquina: desde que no degradem signicativamente a legibilidade do cdigo, a menos que sejam crticas. (nem todos os compiladores tm optimizadores e muitos optimizadores so fracos).

Otimizao independente da mquina


desdobramento e propagao de constantes (constant folding): resoluo de expresses com literais durante a compilao (MAX * 3 + 1). eliminao de cdigo inacessvel: aps intrues de salto incondicional (return, continue, break, etc.), condies determinveis em compilao (if (debug)). inline de funes: substituir chamadas a funes pelo cdigo das prprias funes. (funes estticas podem ser eliminadas e chamadas por valor obrigam a duplicar variveis) propagao de cpias: referncias a uma varivel podem ser substitudas por outra que lhe tenha sido atribuda (depois de a = b existe um nico valor que pode ser referido, at que uma das variveis seja alterada). ciclos: fuso e desdobramento de ciclos, deslocamento de cdigo invariante, predio de saltos (ciclos do).

Compiladores2012 , optim

14-14

Compiladores2012 , optim

14-15

Otimizao dependente da mquina


simplcaes algbricas: instrues equivalentes, em geral com literais (por exemplo, x + 0, x - x, x * 1). reduo de esforo (strength-reduce): instrues equivalentes de menor custo em termos de desempenho ou memria (por exemplo, x2 = x x, 0 x = x, x 2 = x << 1). peephole: simplicao de operaes e utilizao de instrues especiais com base na anlise de uma janela de instrues (por exemplo, instrues postx como JEQ, ADDRV ou START). eliminao de instrues redundantes: que no afetam o estado do sistema: store seguido de um load da mesma posio de memria ou um push seguido de um pop.

Pentium IV face aos anteriores


reduo da latncia das instrues: add, sub cmp, test, and, or, xor, neg, not, sahf, mov. aumento da latncia das instrues: shifts, rotates, mov de memria com extenso de sinal. separar: leituras e escritas da mesma posio de memria. ciclos: devem terminar sempre com saltos para a frente (branch prediction). chaches de 64 bytes: menor necessidade de prefetching (Pentium II e III usavam 32 bytes). chamadas a procedimentos: saltos so mais dispendiosos que chamadas.

Compiladores2012 , optim

14-16

Compiladores2012 , cdigo nal

15-1

Outras otimizaes
Otimizao independente da mquina: ciclos: eliminao de varveis de induo e simplicao de operaes. eliminao de subexpresses comuns: guardar numa varivel temporria (registo ou memria) o resultado. eliminao de cdigo redundante: instrues sem efeito (push seguido de pop, store seguido de load). Otimizao dependente da mquina: alterao da ordem das instrues: instrues com efeitos independentes podem ser alteradas por forma a reduzir o spill de registos. troca de registos: evitar movimentos entre registos (escolha de registos). code hoisting: otimizao do espao ocupado e no da velocidade de execuo.

Gerao de cdigo
Produo de cdigo para um processador especco, tendo em conta as suas caractersticas particulares. Tipos de processadores podem ser: Stack machines: B5000, HP-3000 ou mquinas virtuais Java, e .net. Accumulator machines: PDP-9, M6809, 68HC11. Load-store machines (RISC): RS/6000, MIPS-R, HP-PA, SPARC, M88k. Memory machines (CISC): Register-memory architecture: i80x86, IBM-RT, M68k, IBM360. Memory-memory architecture: VAX, PDP-11. Compilao JIT a partir de um formato intermdio ou compilao object-code a partir de cdigo nal.

Compiladores2012 , cdigo nal

15-2

Compiladores2012 , cdigo nal

15-3

Load-store machines
Load-store machines: vrios registos genricos, todos os (3) argumentos explcitos:
CPU
ALU

Accumulator machines
Accumulator machines: s um registo (o acumulador), um argumento explcito:
CPU
ALU

endereos
REGs AR

memria
AR

endereos
ACC

memria dados

dados
IP IR DR

IP IR

DR

os argumentos de tm origem num registo bem como o destino do resultado. (operaes especiais de load e store so necessrias) o resultado pode ser implcito num dos argumentos (primeiro ou segundo) ou num registo especco (acumulador).

um dos argumentos tem origem no acumulador que serve tambm de destino para o resultado (o outro argumento vem da memria).

Compiladores2012 , cdigo nal

15-4

Compiladores2012 , cdigo nal

15-5

Stack machines
Stack machines: sem registos, sem argumentos explcitos (0 address).
CPU
ALU

Memory machines
Memory machines: mquinas hbridas onde o acesso memoria pode substituir alguns dos argumentos: register-memory: um dos argumentos e/ou o resultado podem ser acedidos diretamente na memria, sem passar por um registo.

endereos
STACK AR

memria dados

memory-memory: os dois argumentos, e mesmo o resultado, podem ser acedidos diretamente na memria, sem passar por um registo. estas mquinas s funcionam aceitavelmente com grandes caches (primria e secundria), pois o acesso memria de massa lento.

IP IR

DR

argumentos tm origem na pilha bem como o destino do resultado. apenas a operao literal tem um argumento explcito. load e store so efetuados para e da pilha.

Compiladores2012 , cdigo nal

15-6

Compiladores2012 , cdigo nal

15-7

Operao de soma de inteiros


Somar dois inteiros localizados em 100 e 104 e colocar o resultado em 300: arquitetura parcela 1 parcela 2 soma resultado instrues ciclos bytes stack lit 100 load lit 104 load add lit 300 store 7 10 19 accumulator load 100 load-store load 100, src1 load 104, src2 add src1, src2, dst store dst, 300 4 11 (8) 22

Register spilling
quando os registos no chegam necessrio guardar valores temporrios na memria, em geral, na pilha de dados: Stack machine: no tem reserva de registos nem spilling: melhor densidade de cdigo compilador mais simples difcil de paralelizar ( pipelining ) Register machine: compilador maior e mais complexo: acesso mais rpido aos registos uso eciente dos registos pelo compilador pipelining determinante na ecincia

add 104 store 300 3 9 15

Compiladores2012 , cdigo nal

15-8

Compiladores2012 , cdigo nal

15-9

b2 4ac
arquitetura stack lit 104 load dup mul lit 4 lit 100 load mul lit 108 load mul sub lit 300 store 14 18 34 accumulator load 104 mul 104 store t1 lit 4 mul 100 mul 108 store t2 load t1 sub t2 store 300 load-store load 100, a load 104, b load 108, c load 4, d mul b, b, e mul d, a, f mul c, f, g sub e, g, h store h, 300

Modos de endereamento
imediato: o operando a instruo (lit 100) direto: endereo absoluto na memria (load 100) aumentado: concatenao de um registo base c/ bits baixos deslocamento: soma com registo base indireto: o endereo contm outro endereo relativo: relativo instruo corrente implcito: implcito no nome da instruo

spill

spill

instrues ciclos bytes

10 30 50

9 22 (16) 46

Compiladores2012 , cdigo nal

15-10

Compiladores2012 , cdigo nal

15-11

Custo das instrues


simples: soma, subtrao, deslocamento (shift). complexas: multiplicao, diviso, salto, chamada, retorno. elaboradas: chamadas ao sistema, interrupes. Considerar o tipo de endereamento e o acesso aos parmetros e resultado: registo: baixo custo. (1x a 2x) cache: uso frequente. (2x a 5x) memria: uso pouco frequente. (2x a 100x) disco: em cheiro ou por paginao. (1000x a 10000x)

Gerao de cdigo
seleo de instrues: uniformidade, velocidade, dimenso, modos de endereamento. reserva e gesto de registos.

Compiladores2012 , cdigo nal

15-12

Compiladores2012 , cdigo nal

15-13

Compilador optimizante
traduo

The End
.c

.c . . .
.java

char

anlise lxica

token

anlise sintctica

pilha

anlise rvore semntica

interpretao directa

optimizao local linear

linear reserva de registos ssa escalonamento instruces ssa

anlise fluxo dag seleco instruces

stack

.class 0-reg .asm .net

Thats all folks!

.asm

linear optimizao global

interpretao threaded

Compiladores2012 , cdigo nal

15-14

Compiladores2012 , cdigo nal

15-15

Você também pode gostar