Buscar

Geração de código intermediário - Compiladores - Exercícios

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 4 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Geração de código intermediário - Compiladores
Exercícios
1. Os compiladores são organizados em uma sequência de fases. À medida que o
compilador deriva conhecimento sobre o código que compila, precisa transmitir
essa informação de uma fase para outra. Ele necessita, então, de uma
representação para todas as informações que deriva sobre o programa-fonte.
Chama-se isso de representação intermediária (IR).
Sobre as IRs geradas por um compilador, considere as seguintes afirmações:
I — A árvore sintática é a forma de representação intermediária mais próxima da
estrutura do código-alvo.
II — A árvore sintática abstrata é uma representação contendo mais informações
sobre as produções gramaticais realizadas, se comparada com a árvore sintática
comum.
III — Um dos motivos de se utilizar o código de três endereços como representação
intermediária é a sua facilidade de tradução para linguagens de máquina.
Assinale a alternativa que indica as afirmações corretas:
Você acertou!
C. Apenas a afirmação III está correta.
Sobre as afirmações feitas, apenas a afirmação III é correta. O código de três
endereços é muito parecido com os tipos de operação em linguagem Assembly, o
que o torna uma boa forma de código intermediário. Assim, um dos motivos de se
utilizar o código de três endereços como IR é a sua facilidade de tradução para
linguagens de máquina. A afirmação I é incorreta,  pois uma árvore sintática é
uma representação do código-fonte, e não do código-alvo. A afirmação II também
está incorreta, pois é justamente o contrário: a árvore sintática comum tem mais
nós relativos aos símbolos das produções gramaticais do que a árvore sintática
abstrata, que representa apenas os símbolos terminais usados nas produções.
2. A função de um compilador é traduzir programas escritos em uma linguagem-
fonte em um dos programas equivalentes em outra linguagem-alvo. Para isso, o
compilador é dividido em fases, que implementam diversas técnicas.
A ___________________ é uma técnica de tradução aplicada em compiladores que
consiste em inserir regras de tradução nas produções gramaticais da linguagem-
fonte, de modo que o percurso na árvore sintática executa a tradução desejada.
Qual das alternativas a seguir preenche melhor a lacuna na afirmação?
Você acertou!
D. Tradução dirigida pela sintaxe.
A frase correta é:  A tradução dirigida pela sintaxe é uma técnica de tradução
aplicada   em   compiladores   que   consiste   em   inserir   regras   de   tradução   nas
produções gramaticais  da  linguagem-fonte,  de modo que o percurso na árvore
sintática executa a tradução desejada.
A  análise   léxica  consiste  em  identificar tokens da   linguagem-fonte   do   texto   do
programa-fonte.   Os tokens reconhecidos   são   usados   na   análise   sintática   para
validar essa sequência com a gramática da linguagem-fonte. Entretanto, nenhuma
tradução é feita. A otimização de código consiste em tornar o código-alvo mais
eficiente,   mas   isso   independe   da   linguagem-fonte.  A   interpretação   de   código
consiste   em   executar   instruções   na   máquina-alvo   a   partir   da   análise   das
instruções do código-fonte.
3. Compiladores podem gerar uma variedade de representações intermediárias para
representar as construções sintáticas da linguagem-fonte. Cada representação tem
a finalidade de registrar informações de uma fase da compilação para as fases
seguintes.
___________________ é uma representação intermediária que consiste em
representar as produções gramaticais de forma mais sucinta, de modo que apenas
os símbolos terminais das produções gramaticais compõem suas construções.
Qual das opções a seguir completa apropriadamente a lacuna da afirmação?
Você acertou!
B. Árvore sintática abstrata.
A árvore sintática abstrata é uma representação intermediária que consiste em
representar as produções gramaticais de forma mais sucinta, de modo que apenas
os símbolos terminais das produções gramaticais compõem suas construções.
Ela   é   uma   versão   resumida   da   árvore   sintática.  A   árvore   sintática   também
representa   símbolos   não   terminais   em   suas   construções.   A   árvore   sintática
anotada consiste em uma árvore sintática contendo em suas ramificações regras
de tradução, além de terminais e não terminais. Um grafo de dependências é um
grafo que modela o fluxo de valores desde suas definições até seus usos em um
fragmento de código. O código de três endereços é uma representação de código
intermediário já voltada para geração de linguagem-alvo.
4. Na notação tradicional para as expressões aritméticas (notação infixa), o
operador aparece entre os seus dois operandos. Já na notação pós-fixa, também
conhecida como notação polonesa inversa, o operador é colocado após os seus
dois operandos.
Considere o esquema de tradução de expressões para a forma pós-fixa para a
gramática a seguir:
EXPR → EXPR + TERMO { imprimir (“+”) }
EXPR → EXPR – TERMO { imprimir (“-”) }
EXPR → TERMO 
TERMO → TERMO * FATOR {imprimir (“*”) }
TERMO → TERMO / FATOR {imprimir (“/”) }
TERMO → FATOR
FATOR → ( EXPR ) 
FATOR → 0 { imprimir (“0”) }
... ...
FATOR → 9 { imprimir (“9”) }
Qual será o resultado da sua execução para a entrada 2 + 4 * (5 - 3)?
Você acertou!
D. 2 4 5 3 - * +.
A árvore sintática anotada para a entrada 2 + 4 *   (5 -  3),  usando a gramática
proposta, é mostrada na figura abaixo:
Ao se percorrer a árvore sintática contendo as regras de tradução no percurso em
profundidade, a expressão pós-fixa será gerada após a execução das regras de
tradução da gramática, na seguinte ordem:
1.  { imprimir (“2”) }
2. { imprimir (“4”) }
3. { imprimir (“5”) }
4. { imprimir (“3”) }
5. { imprimir (“-”) }
6. { imprimir (“*”) }
7. { imprimir (“+”) }
O que torna incorretas as saídas: 
• 2 4 + 5 * 3 - 
• 2 4 5 3 + * -
• + 2 4 * - 5 3
• 2 4 3 5 - * +
Isso porque elas não poderiam ser geradas pela execução das regras de tradução
na ordem de avaliação da árvore sintática.
Nesse caso, a única saída correta seria 2 4 5 3 - * +.
5. As fases de um compilador podem ser classificadas em dois grupos: análise e
síntese. Na fase de análise, encontram-se as fases de análise léxica, análise
sintática e análise semântica. Já na fase de síntese, encontram-se as fases de
geração de código intermediário, otimização e geração de código.
Sobre a fase de geração de código intermediário de um compilador, assinale a
alternativa correta:
Você acertou!
C. A fase de geração de código intermediário de um compilador é a fase em que ocorre a
transformação da árvore sintática em uma linguagem intermediária, que é mais próxima
da linguagem-objeto do que o código-fonte, mas ainda não se trata do código-final.
Análise léxica é a fase em que se reconhecem os tokens da linguagem-fonte por
meio da leitura dos caracteres do código-fonte.
Análise sintática é a fase em que se constrói uma árvore sintática para validar a
estrutura dos tokens reconhecidos do código-fonte.
Geração de código intermediário é a fase em que ocorre a transformação da
árvore sintática em uma linguagem intermediária, que é mais próxima da
linguagem-objeto do que o código-fonte, mas ainda não se trata do código
final.
Otimização de código é a fase em que se procura produzir um código que execute
com mais eficiência.
Geração de código final é a fase em que se gera o código para ser executado
diretamente na máquina-alvo.
	Geração de código intermediário - Compiladores
	Exercícios

Continue navegando