Para desempenhar suas tarefas, um compilador deve executar dois tipos de atividade. A primeira atividade é a análise do código fonte, onde a estrutura e significado do programa de alto nível são reconhecidos. A segunda atividade é a síntese do programa equivalente em linguagem simbólica. Após realizada a análise do código fonte, na fase de síntese, o compilador deverá gerar o código em linguagem simbólica equivalente ao código analisado. Analise as seguintes afirmativas sobre a fase de síntese de um compilador.
Quais das assertivas apresentadas estão corretas?
a. apenas as assertivas I e II.
b. apenas as assertivas I e III.
c. apenas as assertivas II e III.
d. apenas as assertivas II e IV.
e. apenas as assertivas III e IV.
A notação tradicional para expressões aritméticas, que representa uma operação binária na forma x + y, ou seja, com o operador entre seus dois operandos, é conhecida como notação infixada. Uma notação alternativa para esse tipo de expressão é a notação pré-fixada, na qual o operador é expresso antes de seus operandos, como por exemplo, + x y. Outra notação alternativa é a notação pós-fixada, na qual o operador é expresso após seus operandos, como por exemplo, x y +. O atrativo das notações pré-fixada e pós-fixada é que elas dispensam o uso de parênteses ao adotar a noção de pilha para a representação das expressões. Analise as assertivas a seguir, considerando a gramática livre de contexto G.
G = ({A, E, T, F}, {a, b, c, d, e, f, g, h, =, +, -, *, /}, P, A)
P = {A → F=E
E → T+E | T-E | T
T → F*T | F/T | F
F → a | b | c | d | e | f | g | h}
Quais das assertivas apresentadas estão corretas?
a. apenas as assertivas I e II.
b. apenas as assertivas I e III.
c. apenas as assertivas II e III.
d. apenas as assertivas II e IV.
e. apenas as assertivas III e IV.
Dado o trecho de programa a seguir:
int a, b;
void xpto (T1 int x, T2 int y)
{
int z = x + a;
x = y + 2;
y = y + z;
}
void main()
a = 3;
b = 2;
xpto(a, b);
printf("%d %d", a, b);
}
Onde T1 e T2 indicam mecanismos de passagem de parâmetros (por valor ou por referência). A tabela a seguir deve ser preenchida com os valores a serem impressos pelo programa para cada combinação de T1 e T2.
T1 | |||
---|---|---|---|
valor | referência | ||
T2 | valor | ||
referência |
Qual das alternativas abaixo preenche a tabela acima com os valores a serem impressos pelo trecho de programa?
a.
T1 | |||
---|---|---|---|
valor | referência | ||
T2 | valor | 3 2 | 4 8 |
referência | 3 8 | 4 2 |
b.
T1 | |||
---|---|---|---|
valor | referência | ||
T2 | valor | 3 2 | 2 4 |
referência | 3 8 | 8 4 |
c.
T1 | |||
---|---|---|---|
valor | referência | ||
T2 | valor | 3 8 | 4 2 |
referência | 3 2 | 4 8 |
d.
T1 | |||
---|---|---|---|
valor | referência | ||
T2 | valor | 3 2 | 4 2 |
referência | 3 8 | 4 8 |
e.
T1 | |||
---|---|---|---|
valor | referência | ||
T2 | valor | 3 2 | 4 2 |
referência | 4 2 | 4 8 |
Considere o programa escrito em Simpletron Machine Language, apresento a seguir.
Posição | Palavra | Instrução |
---|---|---|
00 | +1017 | read N |
01 | +2017 | load N |
02 | +4114 | branch negative to 14 |
03 | +4214 | branch zero to 14 |
04 | +3317 | multiply N |
05 | +3018 | add S |
06 | +2118 | store S |
07 | +2017 | load N |
08 | +3016 | add -1 |
09 | +2117 | store N |
10 | +4212 | branch zero to 12 |
11 | +4004 | branch to 04 |
12 | +1118 | write S |
13 | +4300 | halt |
14 | +1116 | write -1 |
15 | +4300 | halt |
16 | -0001 | variable -1 |
17 | +0000 | variable N |
18 | +0000 | variable S |
Com base no programa apresentado, avalie as assertivas a seguir.
A respeito dessas asserções, assinale a alternativa correta.
a. apenas as assertivas I e II.
b. apenas as assertivas I e III.
c. apenas as assertivas II e III.
d. apenas as assertivas II e IV.
e. apenas as assertivas III e IV.
A fase de otimização do código intermediário vem logo após a fase de geração desse código e tem por objetivo tornar o código intermediário mais apropriado para a produção de código objeto (código de máquina) eficiente, tanto em relação ao tamanho como ao tempo de execução. Uma das técnicas de otimização de código intermediário consiste em identificar segmentos sequencias do programa, chamados blocos básicos, e representá-los através de grafos dirigidos e submetê-los a um processo de otimização. Apresente o código de três endereços não otimizado da seguinte sequência de comandos, sobre a gramática livre de contexto G, utilizando a notação pós-fixada.
a = d + e – f * g + h;
b = e – f * g / h;
c = d + e + g / h;
G = ({A, E, T, F}, {a, b, c, d, e, f, g, h, =, +, -, *, /}, P, A)
P = {A → F=E
E → E+T | E-T | T
T → T*F | T/F | F
F → a | b | c | d | e | f | g | h }
oper | arg1 | arg2 | result | |
---|---|---|---|---|
(0) | + | d | e | T1 |
(1) | * | f | g | T2 |
(2) | - | T1 | T2 | T3 |
(3) | + | T3 | h | T4 |
(4) | = | T4 | a | |
(5) | * | f | g | T5 |
(6) | / | T5 | h | T6 |
(7) | - | e | T6 | T7 |
(8) | = | T7 | b | |
(9) | + | d | e | T8 |
(10) | / | g | h | T9 |
(11) | + | T8 | T9 | T10 |
(12) | = | T10 | c |
Um grafo acíclico dirigido também é uma representação intermediária de um compilador, sendo utilizado para a identificação de subexpressões comuns existentes no mesmo bloco básico. Apresente o código de três endereços otimizado, após a construção do grafo acíclico dirigido para blocos básicos, no código de três endereços não otimizado elaborado na Questão 5.
oper | arg1 | arg2 | result | |
---|---|---|---|---|
(0) | + | d | e | T1 |
(1) | * | f | g | T2 |
(2) | - | T1 | T2 | T3 |
(3) | + | T3 | h | T4 |
(4) | = | T4 | a | |
(5) | / | T2 | h | T5 |
(6) | - | e | T5 | T6 |
(7) | = | T6 | b | |
(8) | / | g | h | T7 |
(9) | + | T1 | T7 | T8 |
(10) | = | T8 | c |
Apresente o código objeto resultante do código de três endereços otimizado obtido na Questão 6, utilizando no máximo cinco registradores (R0 a R4).
Código objeto | Comentário | R0 | R1 | R2 | R3 | R4 |
---|---|---|---|---|---|---|
LOAD d, R0 | R0 = d | d | ||||
LOAD e, R3 | R3 = e | d | e | |||
ADD R3, R0 | R0 = R0 + R3 (d + e) | (d + e) | e | |||
COPY R0, R1 | R1 = R0 (d + e) | (d + e) | (d + e) | e | ||
LOAD f, R2 | R2 = f | (d + e) | (d + e) | f | e | |
LOAD g, R4 | R4 = g | (d + e) | (d + e) | f | e | g |
MUL R4, R2 | R2 = R2 * R4 (f * g) | (d + e) | (d + e) | (f * g) | e | g |
SUB R2, R1 | R1 = R1 - R2 ((d + e) - (f * g)) | (d + e) | ((d + e) - (f * g)) | (f * g) | e | g |
LOAD h, R4 | R4 = h | (d + e) | ((d + e) - (f * g)) | (f * g) | e | h |
ADD R4, R1 | R1 = R1 + R4 (((d + e) - (f * g)) + h) | (d + e) | (((d + e) - (f * g)) + h) | (f * g) | e | h |
STORE R1, a | a = (((d + e) - (f * g)) + h) | (d + e) | (((d + e) - (f * g)) + h) | (f * g) | e | h |
DIV R4, R2 | R2 = R2 / R4 ((f * g) / h) | (d + e) | (((d + e) - (f * g)) + h) | ((f * g) / h) | e | h |
SUB R2, R3 | R3 = R3 – R2 (e - ((f * g) / h)) | (d + e) | (((d + e) - (f * g)) + h) | ((f * g) / h) | (e - ((f * g) / h)) | h |
STORE R3, b | b = (e - ((f * g) / h)) | (d + e) | (((d + e) - (f * g)) + h) | ((f * g) / h) | (e - ((f * g) / h)) | h |
LOAD g, R1 | R1 = g | (d + e) | g | ((f * g) / h) | (e - ((f * g) / h)) | h |
DIV R4, R1 | R1 = R1 / R4 (g / h) | (d + e) | (g / h) | ((f * g) / h) | (e - ((f * g) / h)) | h |
ADD R1, R0 | R0 = R0 + R1 ((d + e) + (g / h)) | ((d + e) + (g / h)) | (g / h) | ((f * g) / h) | (e - ((f * g) / h)) | h |
STORE R0, c | c = ((d + e) + (g / h)) | ((d + e) + (g / h)) | (g / h) | ((f * g) / h) | (e - ((f * g) / h)) | h |