Geração de Código Intermediário
|
|
|
- Raphael Valgueiro Chaves
- 8 Há anos
- Visualizações:
Transcrição
1 UPE Caruaru Sistemas de Informação Disciplina: Compiladores Prof.: Paulemir G. Campos Geração de Código Intermediário Um compilador pode ser considerado como um modelo de: Análise("front-end modules") - traduz um programa fonte em uma representação (linguagem) intermediária e Síntese("back-end modules") - a partir do código intermediário gera o código objeto final. Embora um programa fonte possa ser traduzido diretamente para a linguagem objeto, o uso de uma representação intermediária, independente de máquina, tem as seguintes vantagens: 1) Reaproveitamento de código, facilitando o transporte de um compilador para diversas plataformas de hardware; somente os módulos finais precisam ser refeitos a cada transporte. 2) Um otimizador de código independente de máquina pode ser usado no código intermediário. 3) Pode ser facilmente interpretado
2 Linguagens Intermediárias (formas internas) Notação Pós-Fixa ou Polonesa Reversa Árvores Sintáticas Código de Três Endereços Notação Pós-Fixa ou Polonesa Reversa Os operandos vêm antes dos operadores. Adequada para representar expressões aritméticas e/ou lógicas. As expressões pós-fixas podem ser obtidas caminhando-se, em pós-ordem, na árvore sintática correspondente. Exemplo: expressão infixa a + b a*(b+c) a/b + c*d a b c expressão pós-fixa ab+ abc+* ab/cd*+ ab c Os operandos unários podem ser manipulados de duas formas: Como operador binário, p/ ex: -b 0-b 0b- Introduzindo um novo símbolo para o operador unário Ex: assim, -b * a b@a*
3 OBS: Na notação pós-fixa os operadores aparecem na ordem em que serão executados. Ótima notação para máquinas com estrutura de pilha (stack machine), como, calculadora de bolso. As expressões pós-fixas podem ser avaliadas com uma simples varredura, da esquerda para a direita, utilizando-se uma pilha para os operandos. Exemplo: Avaliar a expressão pós-fixa w = ab@cd*++ passo w i expressão posfixa pilha operações 0 ab@cd*++ 1 a b@cd*++ a 2 ab cd*++ at 1 T 1 := -b 4 c d*++ at 1 c 5 d *++ at 1 cd 6 * ++ at 1 T 2 T 2 := c*d at 3 T 3 := T 1 + T R R := a + T 3 R := a+t 3 := a+t 1 +T 2 := a+ T 1 + c*d := a+(-b)+c*d Nota: A notação pós-fixa é inadequada para o processo de otimização de código.
4 Árvores Sintáticas Uma árvore sintática (ou de sintaxe) mostra a estrutura hierárquica de um programa fonte. Por exemplo, a atribuição: a := b * c + b * -d seria representada graficamente por: := a + * * b c b -U que poderia ter a seguinte implementação: d
5 Código de Três Endereços O código de três endereços é uma seqüência de comandos da forma: x := y op z onde: x, y e z - variáveis ou constantes definidas pelo programador ou variáveis temporárias geradas pelo compilador; op - define um operador (aritmético, relacional ou lógico) := - define o operador de atribuição. Para o comando de atribuição: a := b * c + b * -d poderíamos ter a seguinte seqüência de comandos: comando operando-1 operador operando-2 operando-3 1 t1 * b c 2 t2 -U d 3 t3 * b t2 4 t4 + t1 t3 5 a := t4 OBS: O código de três endereços é uma representação linearizada de uma árvore sintática
6 O código de três endereços é semelhante às instruções em linguagem de montagem. Nesse sentido, podemos ter comandos com rótulos simbólicos e comandos para controle de fluxo. Comandos bastante comuns para a geração de código intermediário são os seguintes: Atribuições: x := y op z - op é uma operação binária (aritmética, lógica ou relacional) x := op y - op é uma operação unária (menos, negação lógica, deslocamento, conversão de tipos) x := y - atribui o valor de y a x Desvio Incondicional: goto L - desvia para o comando com rótulo L Desvio Condicional: if x op_rel y then goto L aplica um operador relacional (<, =,, etc.) a x e y. Se a relação for verdadeira executa o comando com rótulo L, caso contrário executa o comando após o bloco do if.
7 Ativação de Sub-Programa: param x e call p, n para ativação de procedimentos. Na ativação de sub( x 1, x 2,..., x n ) é gerada a seguinte seqüência de três endereços: param x 1 param x 2... param x n call p, n Atribuições Indexadas x := y[ i ] atribui a x o valor da localização i unidades de memória após a localização de y x[ i ] := y atribui à localização i unidades de memória após a localização de x o valor y
8 Atribuição de Endereços e Apontadores: x := &y atribui a x o endereço (localização) de y x := *y atribui a x o conteúdo de memória cuja localização é dada pelo valor de y *x := y atribui o valor de y ao objeto apontado por x A escolha dos operadores disponíveis é de fundamental importância no projeto de uma linguagem intermediária: O conjunto de operadores deve ser claro e rico o suficiente para implementar todas as operações da linguagem fonte. Um conjunto pequeno de operadores simplifica o transporte do compilador para novas plataformas. Entretanto, isso acarreta: - a geração de longas seqüências de comandos para algumas operações da linguagem fonte. - um trabalho maior do otimizador e do gerador de código intermediário para produzir um código final de qualidade.
9 Implementações de Códigos de Três Endereços Código de três endereços é uma forma abstrata de código intermediário. Em um compilador real, esses comandos podem ser implementados como registros com campos para o operador e os operandos. Os dois tipos mais comuns desses registros são as quádruplas e as triplas. Quádruplas São estruturas de registros com quatro campos, contendo: <operador, argumento_1, argumento_2, resultado> Na forma de quádruplas, o código de três endereços x := y + z é representado como: <+, y, z, x>
10 Exemplo: Para o comando de atribuição: a := b * -c + b * -c temos a seguinte seqüência de quádruplas: quádrupla operador argumento_1 argumento_2 resultado (0) -unário c t1 (1) * b t1 t2 (2) -unário c t3 (3) * b t3 t4 (4) + t2 t4 t5 (5) := t5 a OBS: - Os comandos com operadores unários não usam o argumento_2. - Os operadores como param não usam nem argum2 nem resultado - Os desvios condicionais e incondicionais colocam o rótulo alvo em resultado. - Os conteúdos dos campos arg1, arg2 e resultado são normalmente apontadores para as entradas, na tabela de símbolos, dos nomes representados por esses campos.
11 Exemplo: Gerar quádruplas para o seguinte programa Pascal program estat; var soma, somaq, valor, media, variancia : integer; begin soma := 0; somaq := 0; for i := 1 to 100 do begin read(valor); soma := soma + valor; somaq := somaq + valor*valor; end; media := soma div 100; variancia := somaq div 100 media*media; write(media, variancia); end. quádr. op arg1 arg2 result. comentário 0 := 0 soma {soma := 0} 1 := 0 somaq {somaq := 0} 2 := 1 i {for i:= 1 to 100} 3 JGT i 100 (14) 4 param valor {read(valor)} 5 call read 6 + soma valor t1 {soma := soma + valor} 7 := t1 soma 8 * valor valor t2 {somaq := somaq somaq t2 t3 valor*valor} 10 := t3 somaq
12 quádr. op arg1 arg2 result. comentário 11 + i 1 t4 {fim do loop for} 12 := t4 i 13 JMP (3) 14 div soma 100 t5 {media:=soma div 100} 15 := t5 media 16 div somaq 100 t6 {variancia := 17 * media media t7 somaq div t6 t7 t8 - media*media} 19 := t8 varianci a 20 param media {write(media, 21 param variancia variancia)} 22 call write 23 halt Triplas São estruturas de registros com três campos, contendo: <op, arg1, arg2> Os campos arg1 e arg2, na qualidade de argumentos de op, ou são apontadores para a tabela de símbolos (para nomes definidos pelo programador ou constantes) ou apontadores para estruturas de triplas (para valores temporários).
13 Exemplo: Para o comando de atribuição: a := b * -c + b * -c temos a seguinte seqüência de triplas: tripla operador argumento_1 argumento_2 (0) - unário c (1) * b (0) (2) - unário c (3) * b (2) (4) + (1) (3) (5) := a (4) Rotinas de Semântica (Geração das Formas Internas) O analisador sintático informa apenas se uma sentença pertence ou não a uma linguagem. Entretanto, durante o processo de análise outras atividades terão que ser realizadas, por exemplo: - verificar compatibilidade de tipos; - gerar código intermediário (ou de máquina); - recuperar erros sintáticos.
14 Solução: Associar a cada símbolo da gramática um conjunto de atributos e, também, associar a cada produção um conjunto de regras semânticas para computar os valores dos atributos associados aos símbolos que figuram nessa produção (definição dirigida pela sintaxe). OBS: Para uma mesma produção, o conteúdo das regras semânticas varia conforme a atividade que se deseja realizar. Por exemplo, gerar expressões pós-fixas, quádruplas, etc. Exemplo: A seguinte definição dirigida pela sintaxe traduz expressões da notação infixa para a pós-fixa. Produção Regra Semântica E E + T E.t := E.t T.t + E E - T E.t := E.t T.t - E T E.t := T.t T 0 T.t := 0 T 1 T.t := T 9 T.t := 9 X.t significa associar o atributo t ao símbolo X - símbolo de concatenação
15 A árvore gramatical com os valores dos atributos para a sentença é a seguinte: E.t = E.t = 9 5 T.t = 2 E.t = 9 T.t = 5 T.t =
16 Esquema de tradução Um esquema de tradução é como uma definição dirigida pela sintaxe, exceto que a ordem de avaliação das regras semânticas é explicitamente mostrada. Por exemplo, um esquema de tradução para o exemplo anterior seria: Produção Regra Semântica E E + T {imprimir + } E E - T {imprimir - } E T T 0 {imprimir 0 } T 1 {imprimir 1 } T 9 {imprimir 9 } A árvore gramatical com as regras semânticas para traduzir em é a seguinte: E As regras semânticas, no caso {imprimir * }, são vistas como símbolos acrescentados às produções da gramática. São acionadas sempre que as produções forem usadas. E + T {imprimir( + )} E - T {imprimir( - )} 2 {imprimir( 2 )} T 5 {imprimir( 5 )} 9 {imprimir( 9 )}
17 OBS: Na transformação de uma gramática com regras semânticas, por exemplo para eliminar a recursividade à esquerda, essas regras são tratadas como símbolos quaisquer. Exemplo: A gramática do esquema de tradução do exemplo anterior é recursiva à esquerda, portanto, não pode ser usada diretamente por um Parsing Preditivo ou Analisador Sintático Descendente Preditor. Nesse caso, elimina-se a recursividade à esquerda, lembrando que as regras semânticas são símbolos da gramática. Eliminando a recursividade à esquerda da gramática com semântica do exemplo anterior temos: E TE E +T{imprimir + }E -T{imprimir - }E ε T 0{imprimir 0 } 1{imprimir 1 }... 9{imprimir 9 } E T E 9 {impr 9 } - T {impr - } E 5 {impr 5 } + T {impr + } E Tradução de em {impr 2 } ε
18 Geração de Código Intermediário para Expressões Aritméticas Vamos começar com expressão aritmética e comando de atribuição, considerando a gramática abaixo: A id := E E T E' E' + T E' ε T F T' T' * F T' ε F id nro_int nro_real ( E ) Uma forma simples de geração de código intermediário consiste no uso de uma Pilha de controle de Operandos (PcO), que vai conter os operandos usados nas operações realizadas em uma expressão aritmética. Quando o analisador sintático aplicar as regras F id ou F nro_int ou F nro_real vamos simplesmente empilhar na PcO o identificador, número inteiro ou número real correspondente (ou indicador de onde se encontra esse operando).
19 Quando o analisador sintático aplicar as regras E' + T E' ou T' * F T' sabemos que ele reconheceu uma operação de adição ou multiplicação e que, não havendo problemas de tipos, pode gerar código intermediário para a realização de tais operações. Para tal, basta utilizar os operandos que estiverem no topo e subtopo da PcO, deixando o resultado em uma variável temporária e empilhando essa variável na PcO. Vamos então modificar as regras para introduzir ações de geração de código necessárias (semelhantes às ações semânticas). A id := E A id <G1> := E <G2> E' + T E' T' * F T' E' + T E' <G3> T' * F T' <G4> F id F id <G5> F nro_int F nro_int <G6> F nro_real F nro_real <G7>
20 As ações de geração de código são as seguintes: <G1> /* lembrar do lado esquerdo de uma atribuição e iniciar o contador de temporárias em 1 */ lado_esquerdo <- símbolo; reset_temp(); <G2> /* gerar código para atribuição */ oper_1 <- pop( PcO ); emitir(':=', oper_1,,lado_esquerdo); <G3> /* aplicou regra + TE', gerar código para adição */ oper_2 = pop( PcO ); oper_1 = pop( PcO ); result = nova_temp(); emitir('+', oper_1, oper_2, result); <G4> /* aplicou regra *FT', gerar código para multiplicação */ oper_2 = pop( PcO ); oper_1 = pop( PcO ); result = nova_temp(); emitir('*', oper_1, oper_2, result);
21 <G5> <G6> <G7> /* viu identificador como operando; se for global, colocar nome dele na PcO; se for local, colocar referência relativa à pilha do programa (Exemplo: [base_da_pilha+endereço_relativo]) */ pesquisa_tab_símbolo( símbolo ); se símbolo.escopo = global push( PcO, símbolo ); senão push( PcO, [base_da_pilha+endereço_relativo] ); /* viu número inteiro ou real como operando; colocar símbolo na PcO */ push( PcO, símbolo ); As rotinas auxiliares usadas são as seguintes: nova_temp() /* gera nome de nova variável temporária */ { var = concat( "t", prox_temp ); prox_temp = prox_temp + 1; retorna( var ); } reset_temp() { prox_temp = 1; }
22 Vejamos um exemplo com o comando x := a + b * c Observando a pilha de análise. PILHA DE ANÁLISE ENTRADA PcO OBS. $ A x := a+b*c$ $ <G2>E := <G1>id x OK $ <G2>E := <G1> := a+b*c$ lado_esquer = x; prox_temp = 1; $ <G2>E := := OK $ <G2>E a + b * c $ $ <G2>E' T $ <G2>E' T' F $ <G2>E' T' <G5>id a OK $ <G2>E' T' <G5> + b * c $ a push( PcO, a ) $ <G2>E' T' $ <G2>E' $ <G2><G3>E' T + + OK $ <G2><G3>E' T b * c $ $ <G2><G3>E' T' F $ <G2><G3>E' T' <G5>id b OK $ <G2><G3>E' T' <G5> * c $ a b push( PcO, b ) $ <G2><G3> E' T' $ <G2><G3>E' <G4>T' F * * OK $ <G2> <G3> E' <G4> T' F c $ $ <G2><G3>E' <G4>T' <G5>id c OK $ <G2><G3>E' <G4>T' <G5> $ a b c push( PcO, c ) $ <G2><G3>E' <G4>T' $ <G2><G3>E' <G4> a t1 t1 := b * c $ <G2><G3>E' $ <G2><G3> t2 t2 := a + t1 $ <G2> x := t2 $ $ $ OK
23 Geração de Código Intermediário para Comandos de Controle de Fluxo Comandos de controle de fluxo podem ser basicamente resumidos aos seguintes: <cmdo> if <cond> then <cmdo> <pelse> while <cond> do <cmdo> <pelse> else <cmdo> ε Exemplo_1: esqueleto para o comando: if E then S1 else S2 Código para avaliar E JFALSE Início_else {desvia se E for falso} Código para S1 JMP Fim_if Início_else: Código para S2 Fim_if:... {desvia para o fim do IF}
24 Exemplo_2: esqueleto para o comando: while E do S Início_while: Código para avaliar E JFALSE Fim_while Código para S JMP Início_while Fim_while:.. {desvio incondicional} Para tratá-los, vamos usar uma pilha de controle de rótulos (labels) e uma tabela de rótulos, necessárias para resolver o endereço de um rótulo referenciado antes de ser definido. Considera-se que ao final da geração do código intermediário, a tabela de rótulos contenha somente entradas resolvidas (com rótulo e endereço) para que se faça a respectiva substituição no código intermediário.
25 Para o comando if, as ações de geração de código introduzidas seriam as seguintes: <cmdo> if <cond> then <cmdo> <AG-5> <pelse> <AG-6> <cond> <AG-1><expr-arit><AG-2><op-rel><AG-3> <expr-arit> <AG-4> <op-rel> > >= < <= ==!= <pelse> else <cmdo> <AG-1> [Re]inicializa o contador de temporárias reset_temp(); <AG-2> Salva valor do lado esquerdo da expressão relacional lado_esquerdo = pop( PcO); <AG-3> Salva valor do operador relacional oper_relacional = código; // do símbolo lido <AG-4> Gera código para teste da condição com respectivo desvio result = nova_temp(); emitir(oper_relacional, lado_esquerdo, pop( PcO ), result ); label = novo_label(); push( PcL, label ); emitir( JFALSE, result,, label );
26 <AG-5> Resolve endereço do label anterior e gera desvio da parte else label-aux = pop( PcL ); label = novo_label(); push (PcL, label ); emitir( JMP,,, label ); insere( Tab_label, label-aux, quádrupla_atual ); <AG-6> Resolve endereço do label de fim de if label = pop( PcL ); insere( Tab_label, label, quádrupla_atual ); A rotina novo_label() retorna sempre um rótulo único a cada chamada no formato L.xxx, onde xxx é um número de 3 dígitos, iniciando em 001. A rotina insere(tab_label, label, quádrupla_atual ) insere, com o respectivo endereço, um rótulo na Tabela de rótulos. Ao final da geração do código intermediário, o mesmo deve ser varrido em busca de instruções de desvio para que os rótulos simbólicos (L.xxx) sejam substituídos pelos respectivos endereços de quádruplas.
27 Como um exemplo, mostramos o código intermediário gerado para o comando: If ( a + 2 > k/5-3 ) then... // comando associado ao then else... // comando associado ao else Qdr. OP Oper_1 Oper_2 Result Observação AG-1: [re]inicializa contador de temporárias 10 + a 2 T / - > JFALSE K T.002 T.001 T T T.003 T.003 T.004 L.001 Avalia lado esquerdo da expressão relacional AG-2: salva valor do lado esquerdo da expressão relacional AG-3: salva valor do operador relacional Avalia lado direito da expressão relacional AG-4: gera código para teste da condição com respectivo desvio Código para comando then 30 JMP L AG-5: resolve endereço de label anterior e gera desvio do comando else Código para o comando else 40 AG-6: resolve endereço do label do fim do if Tabela de Labels Label Endereço L L
28 Para o comando while, as ações de geração introduzidas seriam as mesmas usadas em <cond> do comando if, acrescidas da seguintes: <cmdo> ::= while < AG-7> <cond> do <cmdo> <AG-8> endwhile <AG-7> Gera label de início do ciclo label = novo_label(); insere( Tab_label, label, quádrupla_atual ); push( PcL, label ); <AG-8> Gera desvio para início do ciclo e resolve endereço para label de fim de while label-fim = pop( PcL ); label-início = pop( PcL ); emitir( JMP,,,label-início); insere( Tab_label, label-fim, quádrupla_atual );
29 Como um exemplo, mostramos o código intermediário gerado para o seguinte comando: while (a + 2 > k/5-3) do... // comando associado ao ciclo endwhile Qdr. OP Oper_1 Oper_2 Result Observação AG-7: gera label de início do ciclo AG-1: [re]inicializa contador de temporárias a 2 T / - > JFALSE K T.002 T.001 T T T.003 T.003 T.004 L JMP L Avalia lado esquerdo da expressão relacional AG-2: salva valor do lado esquerdo da expressão relacional AG-3: salva valor do operador relacional Avalia lado direito da expressão relacional AG-4: gera código para teste da condição com respectivo desvio Código para comando while AG-8: gera código de desvio para o início do ciclo e resolve endereço para label do fim do ciclo Tabela de Labels Label Endereço L L
30 Referências Notas de aulas do prof. Giuseppe Mongiovi do DI/UFPB, Appel, A. W. Modern Compiler Implementation in C. Cambridge University Press, (Capítulo 5, seções 5.1, 5.3 e 5.4; e Capítulo 7).
Compiladores e Computabilidade
Compiladores e Computabilidade Prof. Leandro C. Fernandes UNIP Universidade Paulista, 2013 GERAÇÃO DE CÓDIGO INTERMEDIÁRIO Geração de Código Intermediário Corresponde a 1ª etapa do processo de Síntese
Um Compilador Simples. Definição de uma Linguagem. Estrutura de Vanguarda. Gramática Livre de Contexto. Exemplo 1
Definição de uma Linguagem Linguagem= sintaxe + semântica Especificação da sintaxe: gramática livre de contexto, BNF (Backus-Naur Form) Especificação Semântica: informal (textual), operacional, denotacional,
Parsing Preditivo. Antes de ser abordado o Parsing Preditivo, será apresentado o Analisador Sintático Descendente Recursivo.
UPE Caruaru Sistemas de Informação Disciplina: Compiladores Prof.: Paulemir G. Campos Parsing Preditivo Antes de ser abordado o Parsing Preditivo, será apresentado o Analisador Sintático Descendente Recursivo.
Lembrando análise semântica. Compiladores. Implementação de esquemas de tradução L-atribuídos. Exemplo de implementação top-down (1)
Lembrando análise semântica Compiladores Geração de código intermediário (1) Parser Bottom-up: squema S-atribuído sem problema Apenas atributos sintetizados squema L-atribuído: ok, mas deve-se usar variáveis
Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES. Síntese. Prof. Geovane Griesang
Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Síntese Prof. [email protected] Data 18/11/2013 Análise sintática Parte 01 25/11/2013 Análise sintática Parte 02
Introdução à Programação
Introdução à Programação Linguagens de Programação: sintaxe e semântica de linguagens de programação e conceitos de linguagens interpretadas e compiladas Engenharia da Computação Professor: Críston Pereira
CAP. VII GERAÇÃO DE CÓDIGO
CAP. VII GERAÇÃO DE CÓDIGO VII. 1 - INTRODUÇÃO Léxica Análise Sintática Semântica Compilação G.C. intermediário Síntese Otimização de código Geração de código Síntese Tradução do programa fonte (léxica,
Compiladores. Motivação. Tradutores. Motivação. Tipos de Tradutores. Tipos de Tradutores
Motivação Prof. Sérgio Faustino Compiladores Conhecimento das estruturas e algoritmos usados na implementação de linguagens: noções importantes sobre uso de memória, eficiência, etc. Aplicabilidade freqüente
Geração de Código para LALG
Geração de Código para LALG Ambiente de execução para LALG Máquina hipotética Repertório de instruções Prof. Thiago A. S. Pardo 1 Geração de código para LALG Código-alvo será um código de montagem Portanto,
Introdução aos Compiladores
Universidade Católica de Pelotas Introdução aos Compiladores André Rauber Du Bois [email protected] 1 MOTIVAÇÃO Entender os algor ıtmos e estruturas usados para se implementar linguagens de programação
INE5421 LINGUAGENS FORMAIS E COMPILADORES
INE5421 LINGUAGENS FORMAIS E COMPILADORES PLANO DE ENSINO Objetivo geral Conhecer a teoria das linguagens formais visando sua aplicação na especificação de linguagens de programação e na construção de
Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES. Introdução. Geovane Griesang
Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Introdução [email protected] Processadores de linguagem Linguagens de programação são notações para se descrever
COMPILADORES. Análise semântica. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática
Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise semântica Parte 01 Prof. [email protected] Sumário Data 18/11/2013 Análise sintática Parte 01 25/11/2013
SCC 202 Algoritmos e Estruturas de Dados I. Pilhas (Stacks) (implementação dinâmica)
SCC 202 Algoritmos e Estruturas de Dados I Pilhas (Stacks) (implementação dinâmica) Operações alocação encadeada dinâmica typedef struct elem{ tipo_info info; struct elem *lig; tipo_elem; typedef struct{
Apresentação. !! Familiarização com os métodos de construção de compiladores de linguagens e com as técnicas de compilação mais habituais.
Apresentação Universidade dos Açores Departamento de Matemática www.uac.pt/~hguerra/!! Aquisição de conceitos sobre a definição de linguagens de programação.!! Familiarização com os métodos de construção
Geração de código. Ivan Ricarte INTRODUÇÃO À COMPILAÇÃO
Geração de código Ivan Ricarte 2008 Sumário Geração de código intermediário Código de três endereços Notação pós-fixa Otimização de código Heurísticas de otimização Geração de código em linguagem simbólica
Geração de Código para LALG
Geração de Código para LALG Ambiente de execução para LALG Máquina hipotética Repertório de instruções Prof. Thiago A. S. Pardo 1 Geração de código para LALG Código-alvo será um código de montagem Portanto,
CAP. VII GERAÇÃO DE CÓDIGO
CAP. VII GERAÇÃO DE CÓDIGO VII. 1 - INTRODUÇÃO Léxica Análise Sintática Semântica Compilação G.C. intermediário Síntese Otimização de código Geração de código Síntese Tradução do programa fonte (léxica,
Expressões e sentença de atribuição
Expressões e sentença de atribuição Marco A L Barbosa malbarbo.pro.br Departamento de Informática Universidade Estadual de Maringá cba Este trabalho está licenciado com uma Licença Creative Commons - Atribuição-CompartilhaIgual
Análise Sintática I. Eduardo Ferreira dos Santos. Abril, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 42
Análise Sintática I Eduardo Ferreira dos Santos Ciência da Computação Centro Universitário de Brasília UniCEUB Abril, 2017 1 / 42 Sumário 1 Introdução 2 Derivações 3 Ambiguidade 4 Análise sintática descendente
CONJUNTO DE INSTRUÇÕES DE UM PROCESSADOR (UCP)
CONJUNTO DE INSTRUÇÕES DE UM PROCESSADOR (UCP) 1 LINGUAGENS Conhecida pelo PROCESSADOR Conhecida pelo Usuário COMPILADOR LINGUAGEM DE ALTO NÍVEL LINGUAGEM ASSEMBLY 2 INSTRUÇÕES EM ASSEMBLY Para programar
Projeto de Compiladores
Projeto de Compiladores FIR Faculdade Integrada do Recife João Ferreira 26 e 27 de fevereiro de 2007 Agenda da Aula Revisão Linguagem de Programação Tradutores Compilador As Fases de Um Compilador Linguagem
COMPILAÇÃO. Ricardo José Cabeça de Souza
COMPILAÇÃO Ricardo José Cabeça de Souza www.ricardojcsouza.com.br Programas Código-fonte escrito em linguagem de programação de alto nível, ou seja, com um nível de abstração muito grande, mais próximo
ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA
ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA Prof. Dr. Daniel Caetano 2012-2 Objetivos Conhecer o processador Compreender os registradores
Tradução Dirigida Pela Sintaxe
Tradução Dirigida Pela Sintaxe Julho 2006 Sugestão de leitura: Livro do Aho, Sethi, Ullman (dragão) Seções 5.1 5.5 Tradução dirigida pela sintaxe É uma técnica que permite realizar tradução (geração de
CAP. VI ANÁLISE SEMÂNTICA
CAP. VI ANÁLISE SEMÂNTICA VI.1 Introdução Semântica SIGNIFICADO, SENTIDO LÓGICO, COERÊNCIA,... Diferença entre SINTAXE e SEMÂNTICA Sintaxe : descreve as estruturas de uma linguagem; Semântica : descreve
Compiladores Análise Semântica
Compiladores Análise Semântica Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Árvores Sintáticas Abstratas (ASTs) A árvore de análise sintática tem muita informação redundante Separadores,
LFA Aula 09. Gramáticas e Linguagens Livres de Contexto 18/01/2016. Linguagens Formais e Autômatos. Celso Olivete Júnior.
LFA Aula 09 Gramáticas e Linguagens Livres de Contexto (Hopcroft, 2002) 18/01/2016 Celso Olivete Júnior [email protected] www.fct.unesp.br/docentes/dmec/olivete/lfa 1 Classes Gramaticais Linguagens
Compiladores I Prof. Ricardo Santos (cap 1)
Compiladores I Prof. Ricardo Santos (cap 1) Compiladores Linguagens de programação são notações que permitem descrever como programas devem executar em uma máquina Mas, antes do programa executar, deve
Compiladores. Conceitos Básicos
Compiladores Conceitos Básicos Processadores de Linguagem De forma simples, um compilador é um programa que recebe como entrada um programa em uma linguagem de programação a linguagem fonte e o traduz
CONJUNTO DE INSTRUÇÕES
CONJUNTO DE INSTRUÇÕES 1 CARACTERÍSTICAS DE INSTRUÇÕES DE MÁQUINA Quando um programador usa uma linguagem de alto-nível, como C, muito pouco da arquitetura da máquina é visível. O usuário que deseja programar
ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA
ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA Prof. Dr. Daniel Caetano 2012-1 Objetivos Conhecer o processador Compreender os registradores
Universidade Federal de Goiás Bacharelado em Ciências da Computacão Compiladores
Universidade Federal de Goiás Bacharelado em Ciências da Computacão Compiladores 2013-2 Compilador para a Linguagem Cafezinho Especificação dos trabalhos: T2 (Geração da Representação Intermediária e Análise
Linguagens de Programação Aula 3
Aula 3 Celso Olivete Júnior [email protected] Na aula passada... Classificação das LPs (nível, geração e paradigma) Paradigmas Imperativo, OO, funcional, lógico e concorrente 2/33 Na aula de hoje...
Aula 4 Introdução ao C
Considere o nosso MSC. O Processador Central, entende o conjunto de instruções, leia, imprima, atribuição e condicional e com ela resolvemos vários problemas, construindo vários algoritmos. As instruções
Compiladores. Otimização de Código
Compiladores Otimização de Código Cristiano Lehrer, M.Sc. Atividades do Compilador Arquivo de origem Arquivo de destino Análise Otimização Geração de Código Intermediário Geração de Código Final Síntese
Linguagens Livres de Contexto
Linguagens Livres de Contexto 1 Roteiro Gramáticas livres de contexto Representação de linguagens livres de contexto Formas normais para gramáticas livres de contexto Gramáticas ambíguas Autômatos de Pilha
Sintaxe do Pascal Simplificado Estendido de 12 novas construções em Notação EBNF (BNF estendida)
Sintaxe do Pascal Simplificado Estendido de 12 novas construções em Notação EBNF (BNF estendida) Não-terminais são nomes mnemônicos colocados entre parênteses angulares. Vocabulário terminal formado por
Compiladores. Análise Léxica
Compiladores Análise Léxica Cristiano Lehrer, M.Sc. Introdução (1/3) Análise léxica é a primeira fase do compilador. A função do analisador léxico, também denominado scanner, é: Fazer a leitura do programa
Capítulo 7. Expressões e Sentenças de Atribuição
Capítulo 7 Expressões e Sentenças de Atribuição Introdução Expressões são os meios fundamentais de especificar computações em uma linguagem de programação Para entender a avaliação de expressões, é necessário
Compiladores. Introdução à Compiladores
Compiladores Introdução à Compiladores Cristiano Lehrer, M.Sc. Introdução (1/2) O meio mais eficaz de comunicação entre pessoas é a linguagem (língua ou idioma). Na programação de computadores, uma linguagem
Prof. Adriano Maranhão COMPILADORES
Prof. Adriano Maranhão COMPILADORES LINGUAGENS: INTERPRETADAS X COMPILADAS Resumo: Linguagem compilada: Se o método utilizado traduz todo o texto do programa, para só depois executar o programa, então
Compiladores. Análise Semântica
Compiladores Análise Semântica Análise semântica A semântica define o significado dos programas sintaticamente corretos; Por exemplo, em C, a instrução if(a>b) max = a; else max = b; Diz que a expressão
Detalhes da geração de código Usando a técnica ad hoc, amarrada aos procedimentos sintáticos, igual à análise semântica
Geração de Código para uma Máquina Hipotética a Pilha Detalhes da geração de código Usando a técnica ad hoc, amarrada aos procedimentos sintáticos, igual à análise semântica É composta de 3 Regiões MEPA
Compiladores - Análise SLR
Compiladores - Análise SLR Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Um exemplo que funciona Todo estado com um item de redução e algum outro item causa conflito LR(0)! A técnica LR(0)
Geração de código intermediário. Novembro 2006
Geração de código intermediário Novembro 2006 Introdução Vamos agora explorar as questões envolvidas na transformação do código fonte em uma possível representação intermediária Como vimos, nas ações semânticas
Compiladores Análise Semântica
Compiladores Análise Semântica Fabio Mascarenhas - 2013.2 http://www.dcc.ufrj.br/~fabiom/comp Árvores Sintáticas Abstratas (ASTs) A árvore de análise sintática tem muita informação redundante Separadores,
Compiladores Aula 6. Celso Olivete Júnior.
Aula 6 Celso Olivete Júnior [email protected] Na aula passada Analisadores Sintáticos Descendentes ASD com retrocesso ASD preditivo recursivo não-recursivo 2 ASD Preditivo Recursivo Projeto Parte 2
Folha 4.2 Análise sintática ascendente
Folha 4.2 Análise sintática ascendente 1. Considere a gramática G = (S, T, P, S) que representa o cabeçalho de métodos na linguagem Java (sem os modificadores de acesso), onde T = {S, Type, Param, Exception,
Conversões de Linguagens: Tradução, Montagem, Compilação, Ligação e Interpretação
Conversões de Linguagens: Tradução, Montagem, Compilação, Ligação e Interpretação Para executar uma tarefa qualquer, um computador precisa receber instruções precisas sobre o que fazer. Uma seqüência adequada
CONJUNTO DE INSTRUÇÕES DE UM PROCESSADOR (UCP)
CONJUNTO DE INSTRUÇÕES DE UM PROCESSADOR (UCP) 1 LINGUAGENS Constituída de seqüência de zeros (0) e uns (1) Cada instrução em ASSEMBLY constitui-se em um mnemônico (uma forma fácil de se lembra) de uma
Capítulo 8. Estruturas de Controle no Nível de Sentença
Capítulo 8 Estruturas de Controle no Nível de Sentença Níveis de fluxo de controle Computações são realizadas por meio da avaliação de expressões e da atribuição dos valores a variáveis Para tornar a computação
Compiladores Aula 13. Celso Olivete Júnior.
Aula 13 Celso Olivete Júnior [email protected] Na aula de hoje Análise léxica Tabela de símbolos Análise sintática Análise semântica Geração de código intermediário Manipulação de erros Tabela de palavras
Paradigmas de Linguagens de Programação. Expressões e Instruções de Atribuição
Expressões e Instruções de Atribuição Cristiano Lehrer Introdução Expressões são o meio fundamental de especificar computações em uma linguagem de programação: Familiarização com as ordens de avaliação
Identificadores Nome de variáveis, constantes, métodos, etc...
IV.2 Aspectos Léxicos Convencionais Classes de símbolos Genéricos Token genérico / Lei de formação bem definida Podem possuir limitações de tamanho e/ou valor Possuem valor semântico o token deve ser acompanhado
Métodos Computacionais. Operadores, Expressões Aritméticas e Entrada/Saída de Dados
Métodos Computacionais Operadores, Expressões Aritméticas e Entrada/Saída de Dados Tópicos da Aula Hoje aprenderemos a escrever um programa em C que pode realizar cálculos Conceito de expressão Tipos de
Geração e Otimização de Código
Geração e Otimização de Código Representação de código intermediária Código de três endereços, P-código Técnicas para geração de código Otimização de código Prof. Thiago A. S. Pardo 1 Estrutura geral de
Introdução à Programação. Operadores, Expressões Aritméticas e Entrada/Saída de Dados
Introdução à Programação Operadores, Expressões Aritméticas e Entrada/Saída de Dados Programa em C #include int main main ( ) { Palavras Reservadas } float celsius ; float farenheit ; celsius
Paradigmas de Programação
Paradigmas de Programação Sintaxe e semântica Aula 4 Prof.: Edilberto M. Silva http://www.edilms.eti.br Prof. Edilberto Silva / edilms.eti.br Sintaxe A sintaxe de uma linguagem de programação é a forma
Banco de Dados Profa. Dra. Cristina Dutra de Aguiar Ciferri. Banco de Dados Processamento e Otimização de Consultas
Processamento e Otimização de Consultas Banco de Dados Motivação Consulta pode ter sua resposta computada por uma variedade de métodos (geralmente) Usuário (programador) sugere uma estratégia para achar
Tratamento dos Erros de Sintaxe. Adriano Maranhão
Tratamento dos Erros de Sintaxe Adriano Maranhão Introdução Se um compilador tivesse que processar somente programas corretos, seu projeto e sua implementação seriam grandemente simplificados. Mas os programadores
Autômatos e Linguagens
Autômatos e Linguagens Eduardo Ferreira dos Santos Ciência da Computação Centro Universitário de Brasília UniCEUB Agosto, 2016 1 / 41 Sumário 1 Compiladores 2 Linguagens de programação 3 Ciência dos compiladores
IV.2 Aspectos Léxicos Convencionais
IV.2 Aspectos Léxicos Convencionais Classes de símbolos Genéricos - Token genérico / Lei de formação bem definida - Limitações de tamanho e/ou valor - Possuem valor semântico o token deve ser acompanhado
Conteúdo. Introdução a compiladores Tradução x Interpretação Processo de Compilação
Compiladores Conteúdo Introdução a compiladores Tradução x Interpretação Processo de Compilação Quando se inventou o computador criou se uma máquina a mais, quando se criou o compilador criou se uma nova
UNIVERSIDADE FEDERAL RURAL DO SEMI-ÁRIDO CURSO: CIÊNCIA DA COMPUTAÇÃO. Prof.ª Danielle Casillo
UNIVERSIDADE FEDERAL RURAL DO SEMI-ÁRIDO CURSO: CIÊNCIA DA COMPUTAÇÃO Prof.ª Danielle Casillo Diferentes computadores podem ter diferentes arquiteturas e os diversos tipos de linguagem de programação.
Linguagem de programação: Pascal
Aula 04 Linguagem de programação: Pascal Prof. Tecgº Flávio Murilo 26/03/2013 1 Pascal Introdução Pascal é uma linguagem de programação estruturada, criada em 1970 pelo suíço Niklaus Wirth, dando este
LINGUAGEM LIVRE DE CONTEXTO GRAMÁTICA LIVRE DE CONTEXTO
LINGUAGEM LIVRE DE CONTEXTO As Linguagens Livres de Contexto é um reconhecedor de linguagens, capaz de aceitar palavras corretas (cadeia, sentenças) da linguagem. Por exemplo, os autômatos. Um gerador
Organização e Arquitetura de Computadores I
Organização e Arquitetura de Computadores I Conjunto de Instruções Slide 1 Sumário Características de Instruções de Máquina Tipos de Operandos Tipos de Operações Linguagem de Montagem Slide 2 Características
Análise sintática. Prof. Thiago A. S. Pardo Tratamento de erros sintáticos
Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo
Vantagens de uma Gramática. Sintaxe de uma Linguagem. Analisador Sintático - Parser. Papel do Analisador Sintático. Tiposde Parsers para Gramáticas
Sintaxe de uma Linguagem Cada LP possui regras que descrevem a estrutura sintática dos programas. specificada através de uma gramática livre de contexto, BNF (Backus-Naur Form). 1 Vantagens de uma Gramática
III.2 - Princípios de Arquitetura
Conjunto de Instruções e Modo de Endereçamento Ciclo de busca decodificação execução de instruções Programação de um processador Arquitetura de Von Neumann e Componentes Arquiteturas 4, 3, 2, 1 e 0 Tabela
Unidade de Controle. UC - Introdução
Unidade de Controle Prof. Alexandre Beletti (Cap. 3 Weber, Cap.8 Monteiro, Cap. 10,11 Stallings) UC - Introdução Para gerenciar o fluxo interno de dados e o instante em que ocorrem as transferências entre
Função, interação com o compilador Especificação e reconhecimento de tokens Implementação Tratamento de erros. Prof. Thiago A. S.
Análise léxica Função, interação com o compilador Especificação e reconhecimento de tokens Implementação Tratamento de erros Prof. Thiago A. S. Pardo 1 Estrutura geral de um compilador programa-fonte analisador
