View
113
Download
0
Category
Preview:
Citation preview
CES-41 CES-41 COMPILADORESCOMPILADORES
Capítulo VIICapítulo VII
Código Código IntermediárioIntermediário
Capítulo VIICapítulo VIICódigo IntermediárioCódigo Intermediário
7.1 – Um programa com subprogramas7.1 – Um programa com subprogramas
7.2 – Estruturas de dados7.2 – Estruturas de dados
7.3 – Quádruplas para alguns 7.3 – Quádruplas para alguns comandoscomandos
7.4 – Quádruplas para ponteiros7.4 – Quádruplas para ponteiros
7.5 – Quádruplas para 7.5 – Quádruplas para subprogramaçãosubprogramação
7.1 – Um Programa com 7.1 – Um Programa com SubprogramasSubprogramas
global:global: int comb;int comb;
functions:functions:
int fat (int n;) {int fat (int n;) {local:local: int i, fat;int i, fat;statements:statements:
if (n < 0 || n > 7) fat = ~1;if (n < 0 || n > 7) fat = ~1;else {else {
fat = 1; i = 2;fat = 1; i = 2;while (i <= n) while (i <= n)
{{ fat = fat * i;fat = fat * i; i i = i + 1;= i + 1; }}}}return fat;return fat;
}}
Seja o seguinte programa para calcular o número de combinações de m elementos tomados n a n:
void main () {void main () {local:local:
char c; int m, n;char c; int m, n;statements:statements:
do {do {write ("Combinacao de m elementos tomados n a n? write ("Combinacao de m elementos tomados n a n?
(s/n): ");(s/n): ");do read (c); while (c!='s' && c!='n');do read (c); while (c!='s' && c!='n');if (c == 's') {if (c == 's') {
write ("m: "); read (m);write ("m: "); read (m);write ("n: "); read (n);write ("n: "); read (n);if (m <= 0 || m > 7 || n <= 0 || m if (m <= 0 || m > 7 || n <= 0 || m < n)< n)
write ("Dados incompativeis");write ("Dados incompativeis");else {else {
comb = fat(m) / (fat(m-n) * fat(n));comb = fat(m) / (fat(m-n) * fat(n));write ("Num. de combinacoes: ", comb);write ("Num. de combinacoes: ", comb);
} } }}
} while (c == 's');} while (c == 's');}}
Quádruplas do escopo global:Quádruplas do escopo global:
1) OPENMOD, (FUNCAO, ##global), (IDLE), (IDLE)1) OPENMOD, (FUNCAO, ##global), (IDLE), (IDLE)2) CALLOP, (FUNCAO, main), (INT, 0), (IDLE)2) CALLOP, (FUNCAO, main), (INT, 0), (IDLE)3) EXITOP, (IDLE) , (IDLE) , (IDLE)3) EXITOP, (IDLE) , (IDLE) , (IDLE)
A quádrupla A quádrupla OPENMODOPENMOD aloca aloca memóriamemória para para as as variáveis globaisvariáveis globais
A quádrupla A quádrupla CALLOPCALLOP chama a função chama a função mainmain, , passando-lhe passando-lhe zero argumentoszero argumentos
A função A função mainmain, como é do tipo , como é do tipo voidvoid, não , não produz resultadoproduz resultado
A função A função mainmain, depois de executada, , depois de executada, retornaretorna o controle para o escopo o controle para o escopo globalglobal
A quádrupla A quádrupla EXITOPEXITOP encerraencerra a execução do a execução do programaprograma
Quádruplas da funçãoQuádruplas da função main: main:
void main () {void main () {local:local:
char c; int m, n;char c; int m, n;- - - - -- - - - -
}}
1) OPENMOD, (FUNCAO, main), (IDLE), (IDLE)1) OPENMOD, (FUNCAO, main), (IDLE), (IDLE)
- - - - -- - - - -
51) RETURNOP, (IDLE), (IDLE), (IDLE)51) RETURNOP, (IDLE), (IDLE), (IDLE)
OPENMOD aloca na memória as variáveis locais da função main
Sendo main do tipo void, a quádrupla RETURNOP não tem operando para retornar
RETURNOP:
Desaloca da memória as variáveis locais da função main
Retorna o controle da execução para o escopo global
do {do {- - - - -- - - - -
} while (c == 's');} while (c == 's');
2) NOP, (IDLE), (IDLE), (IDLE)2) NOP, (IDLE), (IDLE), (IDLE)
- - - - -- - - - -
49) EQOP, (VAR, c), (CHAR, s), (VAR, ##25)49) EQOP, (VAR, c), (CHAR, s), (VAR, ##25)
50) JTOP, (VAR, ##25), (IDLE), (ROTULO, 2)50) JTOP, (VAR, ##25), (IDLE), (ROTULO, 2)
------------------------------------------------------------------------------------------------------------------------------------------------------
write ("Combinacao de m elementos tomados n a n? write ("Combinacao de m elementos tomados n a n? (s/n): ");(s/n): ");
3) PARAM, 3) PARAM,
(CADEIA, Combinacao de m elementos tomados n a (CADEIA, Combinacao de m elementos tomados n a n? n? (s/n): ), (s/n): ),
(IDLE), (IDLE)(IDLE), (IDLE)
4) WRITEOP, (INT, 1), (IDLE), (IDLE)4) WRITEOP, (INT, 1), (IDLE), (IDLE)
do read (c); while (c!='s' && c!='n');do read (c); while (c!='s' && c!='n');
5) NOP, (IDLE), (IDLE), (IDLE)5) NOP, (IDLE), (IDLE), (IDLE)6) PARAM, (VAR, c), (IDLE), (IDLE)6) PARAM, (VAR, c), (IDLE), (IDLE)7) READOP, (INT, 1), (IDLE), (IDLE)7) READOP, (INT, 1), (IDLE), (IDLE)8) NEOP, (VAR, c), (CHAR, s), (VAR, ##8)8) NEOP, (VAR, c), (CHAR, s), (VAR, ##8)9) NEOP, (VAR, c), (CHAR, n), (VAR, ##9)9) NEOP, (VAR, c), (CHAR, n), (VAR, ##9)10) ANDOP, (VAR, ##8), (VAR, ##9), (VAR, ##10)10) ANDOP, (VAR, ##8), (VAR, ##9), (VAR, ##10)11) JTOP, (VAR, ##10), (IDLE), (ROTULO, 5)11) JTOP, (VAR, ##10), (IDLE), (ROTULO, 5)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if (c == 's') {if (c == 's') {- - - - -- - - - -
}}
12) EQOP, (VAR, c), (CHAR, s), (VAR, ##11)12) EQOP, (VAR, c), (CHAR, s), (VAR, ##11)13) JFOP, (VAR, ##11), (IDLE), (ROTULO, 48)13) JFOP, (VAR, ##11), (IDLE), (ROTULO, 48)- - - - -- - - - -48) NOP, (IDLE), (IDLE), (IDLE)48) NOP, (IDLE), (IDLE), (IDLE)
write ("m: "); read (m);write ("m: "); read (m);write ("n: "); read (n);write ("n: "); read (n);
14) PARAM, (CADEIA, m: ), (IDLE), (IDLE)14) PARAM, (CADEIA, m: ), (IDLE), (IDLE)
15) WRITEOP, (INT, 1), (IDLE), (IDLE)15) WRITEOP, (INT, 1), (IDLE), (IDLE)
16) PARAM, (VAR, m), (IDLE), (IDLE)16) PARAM, (VAR, m), (IDLE), (IDLE)
17) READOP, (INT, 1), (IDLE), (IDLE)17) READOP, (INT, 1), (IDLE), (IDLE)
18) PARAM, (CADEIA, n: ), (IDLE), (IDLE)18) PARAM, (CADEIA, n: ), (IDLE), (IDLE)
19) WRITEOP, (INT, 1), (IDLE), (IDLE)19) WRITEOP, (INT, 1), (IDLE), (IDLE)
20) PARAM, (VAR, n), (IDLE), (IDLE)20) PARAM, (VAR, n), (IDLE), (IDLE)
21) READOP, (INT, 1), (IDLE), (IDLE)21) READOP, (INT, 1), (IDLE), (IDLE)
if (m <= 0 || m > 7 || n <= 0 || m if (m <= 0 || m > 7 || n <= 0 || m < n)< n)write ("Dados incompativeis");write ("Dados incompativeis");
else { else { - - - - - - - - - - }}
22) LEOP, (VAR, m), (INT, 0), (VAR, ##12)22) LEOP, (VAR, m), (INT, 0), (VAR, ##12)
23) GTOP, (VAR, m), (INT, 7), (VAR, ##13)23) GTOP, (VAR, m), (INT, 7), (VAR, ##13)
24) OROP, (VAR, ##12), (VAR, ##13), (VAR, ##14)24) OROP, (VAR, ##12), (VAR, ##13), (VAR, ##14)
25) LEOP, (VAR, n), (INT, 0), (VAR, ##15)25) LEOP, (VAR, n), (INT, 0), (VAR, ##15)
26) OROP, (VAR, ##14), (VAR, ##15), (VAR, ##16)26) OROP, (VAR, ##14), (VAR, ##15), (VAR, ##16)
27) LTOP, (VAR, m), (VAR, n), (VAR, ##17)27) LTOP, (VAR, m), (VAR, n), (VAR, ##17)
28) OROP, (VAR, ##16), (VAR, ##17), (VAR, ##18)28) OROP, (VAR, ##16), (VAR, ##17), (VAR, ##18)
29) JFOP, (VAR, ##18), (IDLE), (ROTULO, 33)29) JFOP, (VAR, ##18), (IDLE), (ROTULO, 33)
30) PARAM, (CADEIA, Dados incompativeis), (IDLE), 30) PARAM, (CADEIA, Dados incompativeis), (IDLE), (IDLE)(IDLE)
31) WRITEOP, (INT, 1), (IDLE), (IDLE)31) WRITEOP, (INT, 1), (IDLE), (IDLE)
32) JUMPOP, (IDLE), (IDLE), (ROTULO, 47)32) JUMPOP, (IDLE), (IDLE), (ROTULO, 47)
33) NOP, (IDLE), (IDLE), (IDLE)33) NOP, (IDLE), (IDLE), (IDLE)
- - - - -- - - - -
47) NOP, (IDLE), (IDLE), (IDLE)47) NOP, (IDLE), (IDLE), (IDLE)
comb = fat(m) / (fat(m-n) * fat(n));comb = fat(m) / (fat(m-n) * fat(n));
34) PARAM, (VAR, m), (IDLE), (IDLE)34) PARAM, (VAR, m), (IDLE), (IDLE)
35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19)35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19)
36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20)36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20)
37) PARAM, (VAR, ##20), (IDLE), (IDLE)37) PARAM, (VAR, ##20), (IDLE), (IDLE)
38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21)38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21)
39) PARAM, (VAR, n), (IDLE), (IDLE)39) PARAM, (VAR, n), (IDLE), (IDLE)
40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22)40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22)
41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23)41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23)
42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24)42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24)
43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)
write ("Num. de combinacoes: ", comb);write ("Num. de combinacoes: ", comb);
44) PARAM, (CADEIA, Num. de combinacoes: ), 44) PARAM, (CADEIA, Num. de combinacoes: ), (IDLE), (IDLE)(IDLE), (IDLE)
45) PARAM, (VAR, comb), (IDLE), (IDLE)45) PARAM, (VAR, comb), (IDLE), (IDLE)
46) WRITEOP, (INT, 2), (IDLE), (IDLE)46) WRITEOP, (INT, 2), (IDLE), (IDLE)
34) PARAM, (VAR, m), (IDLE), (IDLE)34) PARAM, (VAR, m), (IDLE), (IDLE)
35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19)35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19)
36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20)36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20)
37) PARAM, (VAR, ##20), (IDLE), (IDLE)37) PARAM, (VAR, ##20), (IDLE), (IDLE)
38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21)38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21)
39) PARAM, (VAR, n), (IDLE), (IDLE)39) PARAM, (VAR, n), (IDLE), (IDLE)
40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22)40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22)
41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23)41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23)
42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24)42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24)
43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)
CALLOP chama a função fat
Retira 1 argumento da pilha de parâmetros
Deposita o argumento no parâmetro n da função fat
O parâmetro n da função fat é localizado na lista de parâmetros do identificador fat na TabSmb
34) PARAM, (VAR, m), (IDLE), (IDLE)34) PARAM, (VAR, m), (IDLE), (IDLE)
35) CALLOP, (FUNCAO, fat), (INT, 1), 35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19)(VAR, ##19)
36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20)36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20)
37) PARAM, (VAR, ##20), (IDLE), (IDLE)37) PARAM, (VAR, ##20), (IDLE), (IDLE)
38) CALLOP, (FUNCAO, fat), (INT, 1), 38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21)(VAR, ##21)
39) PARAM, (VAR, n), (IDLE), (IDLE)39) PARAM, (VAR, n), (IDLE), (IDLE)
40) CALLOP, (FUNCAO, fat), (INT, 1), 40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22)(VAR, ##22)
41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23)41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23)
42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24)42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24)
43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)
Pela TabSimb, a função fat é do tipo int
Ela deve retornar um valor no 3º operando da quádrupla
##19, ##21 e ##22 são novas temporárias para guardar o valor retornado de suas respectivas chamadasEssas temporárias de retorno são usadas para o cálculo de comb
Como pode haver chamadas embutidas de funções, as temporárias de retorno devem ser introduzidas numa pilha
Quádruplas da funçãoQuádruplas da função fat: fat:
int fat (int n) {int fat (int n) {local:local:
int i, fat;int i, fat;- - - - -- - - - -returnreturn fat; fat;
}}
1) OPENMOD, (FUNCAO, fat), (IDLE), (IDLE)1) OPENMOD, (FUNCAO, fat), (IDLE), (IDLE)- - - - -- - - - -22) RETURNOP, (VAR, fat), (IDLE), (IDLE)22) RETURNOP, (VAR, fat), (IDLE), (IDLE)
OPENMOD aloca na memória as variáveis locais da função fat
Pela TabSimb, a função fat do tipo int
Então, RETURNOP deve retirar da pilha de variáveis de retorno uma para guardar o valor a ser retornado
Essa variável deve ter sido empilhada pela função que a chamou
RETURNOP:
Desaloca da memória as variáveis locais e os parâmetros da função fat
Retorna o controle da execução para a função main
2) LTOP, (VAR, n), (INT, 0), (VAR, ##1)2) LTOP, (VAR, n), (INT, 0), (VAR, ##1)3) GTOP, (VAR, n), (INT, 7), (VAR, ##2)3) GTOP, (VAR, n), (INT, 7), (VAR, ##2)4) OROP, (VAR, ##1), (VAR, ##2), (VAR, ##3)4) OROP, (VAR, ##1), (VAR, ##2), (VAR, ##3)5) JFOP, (VAR, ##3), (IDLE), (ROTULO, 9)5) JFOP, (VAR, ##3), (IDLE), (ROTULO, 9)6) MENUNOP, (INT, 1), (IDLE), (VAR, ##4)6) MENUNOP, (INT, 1), (IDLE), (VAR, ##4)7) ATRIBOP, (VAR, ##4), (IDLE), (VAR, fat)7) ATRIBOP, (VAR, ##4), (IDLE), (VAR, fat)8) JUMPOP, (IDLE), (IDLE), (ROTULO, 21)8) JUMPOP, (IDLE), (IDLE), (ROTULO, 21)9) NOP, (IDLE), (IDLE), (IDLE)9) NOP, (IDLE), (IDLE), (IDLE)10) ATRIBOP, (INT, 1), (IDLE), (VAR, fat)10) ATRIBOP, (INT, 1), (IDLE), (VAR, fat)11) ATRIBOP, (INT, 2), (IDLE), (VAR, i)11) ATRIBOP, (INT, 2), (IDLE), (VAR, i)12) NOP, (IDLE), (IDLE), (IDLE)12) NOP, (IDLE), (IDLE), (IDLE)13) LEOP, (VAR, i), (VAR, n), (VAR, ##5)13) LEOP, (VAR, i), (VAR, n), (VAR, ##5)14) JFOP, (VAR, ##5), (IDLE), (ROTULO, 20)14) JFOP, (VAR, ##5), (IDLE), (ROTULO, 20)15) MULTOP, (VAR, fat), (VAR, i), (VAR, ##6)15) MULTOP, (VAR, fat), (VAR, i), (VAR, ##6)16) ATRIBOP, (VAR, ##6), (IDLE), (VAR, fat)16) ATRIBOP, (VAR, ##6), (IDLE), (VAR, fat)17) MAISOP, (VAR, i), (INT, 1), (VAR, ##7)17) MAISOP, (VAR, i), (INT, 1), (VAR, ##7)18) ATRIBOP, (VAR, ##7), (IDLE), (VAR, i)18) ATRIBOP, (VAR, ##7), (IDLE), (VAR, i)19) JUMPOP, (IDLE), (IDLE), (ROTULO, 12)19) JUMPOP, (IDLE), (IDLE), (ROTULO, 12)20) NOP, (IDLE), (IDLE), (IDLE)20) NOP, (IDLE), (IDLE), (IDLE)21) NOP, (IDLE), (IDLE), (IDLE)21) NOP, (IDLE), (IDLE), (IDLE)
if (n < 0 || n > 7) fat = ~1;else {
fat = 1; i = 2;while (i <= n) {
fat = fat * i; i = i + 1;
}}
7.2 – Estruturas de Dados7.2 – Estruturas de Dados
As listas de As listas de quádruplas de quádruplas de cada cada subprograma: subprograma:
Estrutura de uma Estrutura de uma quádruplaquádrupla::
Estrutura de um Estrutura de um operandooperando::
Estrutura de um cabeçalho Estrutura de um cabeçalho
de função (de função (funcheadfunchead):):
As declarações foram vistas no lab
Protótipos das Protótipos das funçõesfunções para construir o código para construir o código intermediário:intermediário:
void void InicCodIntermedInicCodIntermed (void); (void);
void void InicCodIntermFuncInicCodIntermFunc (simbolo); (simbolo);
void void ImprimeQuadruplasImprimeQuadruplas (void); (void);
quadrupla quadrupla GeraQuadruplaGeraQuadrupla (int, operando, (int, operando,
operando, operando);operando, operando);
simbolo simbolo NovaTempNovaTemp (int); (int);
Função Função InicCodIntermedInicCodIntermed: : inicializainicializa a a estrutura do código intermediário, deixando-a estrutura do código intermediário, deixando-a assim:assim:
Função Função InicCodIntermFunc (simbolo simb)InicCodIntermFunc (simbolo simb): : inicializa o código intermediário da função cujo nome inicializa o código intermediário da função cujo nome está na tabela de símbolos apontada por está na tabela de símbolos apontada por simbsimb;;
Deixa a estrutura do código intermediário assim:
7.3 – Quádruplas para 7.3 – Quádruplas para Alguns ComandosAlguns Comandos
Apresentada a seguir, programação para Apresentada a seguir, programação para construir o construir o código intermediáriocódigo intermediário de de comandos não abordados nas aulas de comandos não abordados nas aulas de laboratório:laboratório:
Comando Comando do-whiledo-while
Comando Comando forfor
Comando Comando casecase
7.3.1 – Quádruplas para o comando do-7.3.1 – Quádruplas para o comando do-whilewhile
Seja o seguinte trecho de Seja o seguinte trecho de
programa:programa:
local: int i, j, h;local: int i, j, h;
statements:statements:
- - - - -- - - - -
do {i = i + h; j = j - h; do {i = i + h; j = j - h; } }
while (i < j);while (i < j);
i = 0;i = 0;
- - - - -- - - - -
A programação para isso está na produção do não A programação para isso está na produção do não terminal terminal CmdDoCmdDo a seguir a seguir
2) NOP, (IDLE), (IDLE), (IDLE)3) MAISOP, (VAR, i), (VAR, h), (VAR, ##1)4) ATRIBOP, (VAR, ##1), (IDLE), (VAR, i)5) MENOSOP, (VAR, j), (VAR, h), (VAR, ##2)6) ATRIBOP, (VAR, ##2), (IDLE), (VAR, j)7) LTOP, (VAR, i), (VAR, j), (VAR, ##3)8) JTOP, (VAR, ##3), (IDLE), (ROTULO, 2)9) ATRIBOP, (INT, 0), (IDLE), (VAR, i)
Suas possíveis quádruplas:
CmdDoCmdDo : DO {: DO {$<quad>$ = GeraQuadrupla (NOP, opndidle, $<quad>$ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle, opndidle);opndidle);
} Comando WHILE } Comando WHILE ABPAR Expressao {ABPAR Expressao {- - - - -- - - - -opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;opndaux.atr.rotulo = $<quad>2;opndaux.atr.rotulo = $<quad>2;GeraQuadrupla (JTOP, $6.opnd, opndidle, opndaux);GeraQuadrupla (JTOP, $6.opnd, opndidle, opndaux);
} FPAR PVIRG } FPAR PVIRG ;;
Comando
JTOP ##n ---- ROT
Expressão
NOP -----
-----
-----
-----
-----
-----
##n
$2
7.3.2 – Quádruplas para o comando for7.3.2 – Quádruplas para o comando for
Seja o seguinte trecho de Seja o seguinte trecho de
programa:programa:
local: int i, n, s, p;local: int i, n, s, p;
statements:statements:
- - - - -- - - - -
s = 0; p = 1;s = 0; p = 1;
for (i = 1; i <= n; i = i + 1) for (i = 1; i <= n; i = i + 1)
{{
s = s + i;s = s + i;
p = p * i;p = p * i;
}}
i = 0;i = 0;
2) ATRIBOP, (INT, 0), (IDLE), (VAR, s)3) ATRIBOP, (INT, 1), (IDLE), (VAR, p)
4) ATRIBOP, (INT, 1), (IDLE), (VAR, i)
5) NOP, (IDLE), (IDLE), (IDLE)6) LEOP, (VAR, i), (VAR, n), (VAR, ##1)
7) JFOP, (VAR, ##1), (IDLE), (ROTULO, 17)
8) NOP, (IDLE), (IDLE), (IDLE)9) MAISOP, (VAR, s), (VAR, i), (VAR, ##3)10) ATRIBOP, (VAR, ##3), (IDLE), (VAR, s)11) MULTOP, (VAR, p), (VAR, i), (VAR, ##4)12) ATRIBOP, (VAR, ##4), (IDLE), (VAR, p)
13) NOP, (IDLE), (IDLE), (IDLE)14) MAISOP, (VAR, i), (INT, 1), (VAR, ##2)15) ATRIBOP, (VAR, ##2), (IDLE), (VAR, i)
16) JUMPOP, (IDLE), (IDLE), (ROTULO, 5)
17) NOP, (IDLE), (IDLE), (IDLE)
18) ATRIBOP, (INT, 0), (IDLE), (VAR, i)
Possíveis quádrupl
as
CmdForCmdFor :: FOR ABPAR CmdAtrib PVIRG {FOR ABPAR CmdAtrib PVIRG {
$<quad>$ = GeraQuadrupla (NOP, opndidle, $<quad>$ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle);opndidle, opndidle);
} Expressao {} Expressao {
- - - - -- - - - -
opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;
$<quad>$ = GeraQuadrupla (JFOP, $6.opnd, $<quad>$ = GeraQuadrupla (JFOP, $6.opnd, opndidle, opndaux);opndidle, opndaux);
} PVIRG {} PVIRG {
$<quad>$ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle);$<quad>$ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle);
} CmdAtrib FPAR } CmdAtrib FPAR
{ $<quad>$ = quadcorrente; }{ $<quad>$ = quadcorrente; }
{ $<quad>$ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle); }{ $<quad>$ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle); }
Comando {Comando {
quadaux = quadcorrente;quadaux = quadcorrente;
opndaux.tipo = ROTOPND; opndaux.atr.rotulo = $<quad>5;opndaux.tipo = ROTOPND; opndaux.atr.rotulo = $<quad>5;
quadaux2 = GeraQuadrupla (JUMPOP, opndidle, opndidle, opndaux);quadaux2 = GeraQuadrupla (JUMPOP, opndidle, opndidle, opndaux);
$<quad>7->result.atr.rotulo = GeraQuadrupla $<quad>7->result.atr.rotulo = GeraQuadrupla
(NOP, opndidle, opndidle, opndidle);(NOP, opndidle, opndidle, opndidle);
- - - - - Correcao da ordem das quadruplas - - - - - }- - - - - Correcao da ordem das quadruplas - - - - - }
;;
A ordem das quádruplas deve
ser corrigida
Ordem na qual as
quádruplas foram
geradas:
Comando deve ser executado antes de CmdAtrib2
CmdAtrib 1
NOP
Expressão
JFOP, ##expr, --- , rot
NOP
CmdAtrib 2
$5
$7
$9
$12
NOP
Comando
JUMP, --- , --- , rot
NOP
$13
quadaux
quadaux2
CmdAtrib 1
NOP
Expressão
JFOP, ##expr, --- , rot
NOP
NOP
CmdAtrib 2
Comando
JUMP, --- , --- , rot
NOP
$5
$7
$9
$12
$13
quadaux
quadaux2
Agora Comando será executado
antes de CmdAtrib2
Correção da ordem das Correção da ordem das quádruplas:quádruplas:
$<quad>7->prox = $<quad>7->prox = $<quad>13;$<quad>13;quadaux->prox = quadaux->prox = $<quad>9;$<quad>9;$<quad>12->prox = $<quad>12->prox = quadaux2;quadaux2;RenumQuadruplas RenumQuadruplas ($<quad>7, ($<quad>7, quadcorrente);quadcorrente);
7.3.3 – Quádruplas para o comando case7.3.3 – Quádruplas para o comando case
Seja o seguinte trecho de programa:Seja o seguinte trecho de programa:
local: int i, n, s;local: int i, n, s;
statements:statements:
- - - - -- - - - -
case (i + j) {case (i + j) {
1, 2, 3: {i = i + 1; j = j + 2;}1, 2, 3: {i = i + 1; j = j + 2;}
4, 5: {i = i + 3; j = j - 1;}4, 5: {i = i + 3; j = j - 1;}
6: case (i - j) {6: case (i - j) { 1, 2: i = i * j;1, 2: i = i * j; 3: j = j + i;3: j = j + i; }}
7: j = i - j;7: j = i - j;
default: i = 0;default: i = 0;
}}
- - - - -- - - - -
Aninhamento de dois comandos case
A seguir possíveis quádruplas para ele
2) MAISOP, (VAR, i), (VAR, j), (VAR, ##1)2) MAISOP, (VAR, i), (VAR, j), (VAR, ##1)
3) EQOP, (VAR, ##1), 3) EQOP, (VAR, ##1), (INT, 1)(INT, 1), (VAR, ##2), (VAR, ##2)
4) JTOP, (VAR, ##2), (IDLE), (ROTULO, 10)4) JTOP, (VAR, ##2), (IDLE), (ROTULO, 10)
5) EQOP, (VAR, ##1), 5) EQOP, (VAR, ##1), (INT, 2)(INT, 2), (VAR, ##3), (VAR, ##3)
6) JTOP, (VAR, ##3), (IDLE), (ROTULO, 10)6) JTOP, (VAR, ##3), (IDLE), (ROTULO, 10)
7) EQOP, (VAR, ##1), 7) EQOP, (VAR, ##1), (INT, 3)(INT, 3), (VAR, ##4), (VAR, ##4)
8) JTOP, (VAR, ##4), (IDLE), (ROTULO, 10)8) JTOP, (VAR, ##4), (IDLE), (ROTULO, 10)
9) JUMPOP, (IDLE), (IDLE), (ROTULO, 16)9) JUMPOP, (IDLE), (IDLE), (ROTULO, 16)
10) NOP, (IDLE), (IDLE), (IDLE)10) NOP, (IDLE), (IDLE), (IDLE)
11) MAISOP, (VAR, i), (INT, 1), (VAR, ##5)11) MAISOP, (VAR, i), (INT, 1), (VAR, ##5)
12) ATRIBOP, (VAR, ##5), (IDLE), (VAR, i)12) ATRIBOP, (VAR, ##5), (IDLE), (VAR, i)
13) MAISOP, (VAR, j), (INT, 2), (VAR, ##6)13) MAISOP, (VAR, j), (INT, 2), (VAR, ##6)
14) ATRIBOP, (VAR, ##6), (IDLE), (VAR, j)14) ATRIBOP, (VAR, ##6), (IDLE), (VAR, j)
15) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)15) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)
case (i + j)
1, 2, 3:
{i = i + 1; j = j + 2;
}
Final do case externo
4, 5:
16) NOP, (IDLE), (IDLE), (IDLE)16) NOP, (IDLE), (IDLE), (IDLE)
17) EQOP, (VAR, ##1), 17) EQOP, (VAR, ##1), (INT, 4)(INT, 4), (VAR, ##7), (VAR, ##7)
18) JTOP, (VAR, ##7), (IDLE), (ROTULO, 22)18) JTOP, (VAR, ##7), (IDLE), (ROTULO, 22)
19) EQOP, (VAR, ##1), 19) EQOP, (VAR, ##1), (INT, 5)(INT, 5), (VAR, ##8), (VAR, ##8)
20) JTOP, (VAR, ##8), (IDLE), (ROTULO, 22)20) JTOP, (VAR, ##8), (IDLE), (ROTULO, 22)
21) JUMPOP, (IDLE), (IDLE), (ROTULO, 28)21) JUMPOP, (IDLE), (IDLE), (ROTULO, 28)
22) NOP, (IDLE), (IDLE), (IDLE)22) NOP, (IDLE), (IDLE), (IDLE)
23) MAISOP, (VAR, i), (INT, 3), (VAR, ##9)23) MAISOP, (VAR, i), (INT, 3), (VAR, ##9)
24) ATRIBOP, (VAR, ##9), (IDLE), (VAR, i)24) ATRIBOP, (VAR, ##9), (IDLE), (VAR, i)
25) MENOSOP, (VAR, j), (INT, 1), (VAR, ##10)25) MENOSOP, (VAR, j), (INT, 1), (VAR, ##10)
26) ATRIBOP, (VAR, ##10), (IDLE), (VAR, j)26) ATRIBOP, (VAR, ##10), (IDLE), (VAR, j)
27) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)27) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)
4, 5:
{ i = i + 3; j = j - 1;}
Final do case externo
6:
28) NOP, (IDLE), (IDLE), (IDLE)28) NOP, (IDLE), (IDLE), (IDLE)
29) EQOP, (VAR, ##1), 29) EQOP, (VAR, ##1), (INT, 6)(INT, 6), (VAR, ##11), (VAR, ##11)
30) JTOP, (VAR, ##11), (IDLE), (ROTULO, 32)30) JTOP, (VAR, ##11), (IDLE), (ROTULO, 32)
31) JUMPOP, (IDLE), (IDLE), (ROTULO, 54)31) JUMPOP, (IDLE), (IDLE), (ROTULO, 54)
32) NOP, (IDLE), (IDLE), (IDLE)32) NOP, (IDLE), (IDLE), (IDLE)
33) MENOSOP, (VAR, i), (VAR, j), (VAR, ##12)33) MENOSOP, (VAR, i), (VAR, j), (VAR, ##12)
34) EQOP, (VAR, ##12), 34) EQOP, (VAR, ##12), (INT, 1)(INT, 1), (VAR, ##13), (VAR, ##13)
35) JTOP, (VAR, ##13), (IDLE), (ROTULO, 39)35) JTOP, (VAR, ##13), (IDLE), (ROTULO, 39)
36) EQOP, (VAR, ##12), 36) EQOP, (VAR, ##12), (INT, 2)(INT, 2), (VAR, ##14), (VAR, ##14)
37) JTOP, (VAR, ##14), (IDLE), (ROTULO, 39)37) JTOP, (VAR, ##14), (IDLE), (ROTULO, 39)
38) JUMPOP, (IDLE), (IDLE), (ROTULO, 43)38) JUMPOP, (IDLE), (IDLE), (ROTULO, 43)
39) NOP, (IDLE), (IDLE), (IDLE)39) NOP, (IDLE), (IDLE), (IDLE)
40) MULTOP, (VAR, i), (VAR, j), (VAR, ##15)40) MULTOP, (VAR, i), (VAR, j), (VAR, ##15)
41) ATRIBOP, (VAR, ##15), (IDLE), (VAR, i)41) ATRIBOP, (VAR, ##15), (IDLE), (VAR, i)
42) JUMPOP, (IDLE), (IDLE), (ROTULO, 52)42) JUMPOP, (IDLE), (IDLE), (ROTULO, 52)
6:
i = i * j
Final do case interno
case (i – j)
1, 2:
3:
7:
43) NOP, (IDLE), (IDLE), (IDLE)43) NOP, (IDLE), (IDLE), (IDLE)
44) EQOP, (VAR, ##12), 44) EQOP, (VAR, ##12), (INT, 3)(INT, 3), (VAR, ##16), (VAR, ##16)
45) JTOP, (VAR, ##16), (IDLE), (ROTULO, 47)45) JTOP, (VAR, ##16), (IDLE), (ROTULO, 47)
46) JUMPOP, (IDLE), (IDLE), (ROTULO, 51)46) JUMPOP, (IDLE), (IDLE), (ROTULO, 51)
47) NOP, (IDLE), (IDLE), (IDLE)47) NOP, (IDLE), (IDLE), (IDLE)
48) MAISOP, (VAR, j), (VAR, i), (VAR, ##17)48) MAISOP, (VAR, j), (VAR, i), (VAR, ##17)
49) ATRIBOP, (VAR, ##17), (IDLE), (VAR, j)49) ATRIBOP, (VAR, ##17), (IDLE), (VAR, j)
50) JUMPOP, (IDLE), (IDLE), (ROTULO, 52)50) JUMPOP, (IDLE), (IDLE), (ROTULO, 52)
51) NOP, (IDLE), (IDLE), (IDLE)51) NOP, (IDLE), (IDLE), (IDLE)
52) NOP, (IDLE), (IDLE), (IDLE)52) NOP, (IDLE), (IDLE), (IDLE)
53) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)53) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)
3:
Final do case externo
j = j + i;
default vazioFinal do case interno
54) NOP, (IDLE), (IDLE), (IDLE)54) NOP, (IDLE), (IDLE), (IDLE)
55) EQOP, (VAR, ##1), 55) EQOP, (VAR, ##1), (INT, 7)(INT, 7), (VAR, ##18), (VAR, ##18)
56) JTOP, (VAR, ##18), (IDLE), (ROTULO, 58)56) JTOP, (VAR, ##18), (IDLE), (ROTULO, 58)
57) JUMPOP, (IDLE), (IDLE), (ROTULO, 62)57) JUMPOP, (IDLE), (IDLE), (ROTULO, 62)
58) NOP, (IDLE), (IDLE), (IDLE)58) NOP, (IDLE), (IDLE), (IDLE)
59) MENOSOP, (VAR, i), (VAR, j), (VAR, ##19)59) MENOSOP, (VAR, i), (VAR, j), (VAR, ##19)
60) ATRIBOP, (VAR, ##19), (IDLE), (VAR, j)60) ATRIBOP, (VAR, ##19), (IDLE), (VAR, j)
61) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)61) JUMPOP, (IDLE), (IDLE), (ROTULO, 64)
62) NOP, (IDLE), (IDLE), (IDLE)62) NOP, (IDLE), (IDLE), (IDLE)
63) ATRIBOP, (INT, 0), (IDLE), (VAR, i)63) ATRIBOP, (INT, 0), (IDLE), (VAR, i)
64) NOP, (IDLE), (IDLE), (IDLE)64) NOP, (IDLE), (IDLE), (IDLE)
7:
j = j + i;
default: i = 0;
Final do case externo
Nesse exemplo, observa-se que o Nesse exemplo, observa-se que o rótulorótulo das das quádruplas quádruplas de desvio 4, 6, e 8de desvio 4, 6, e 8 somente serão preenchidos, quando somente serão preenchidos, quando a a quádrupla 10quádrupla 10 for gerada; o mesmo vale para: for gerada; o mesmo vale para:
Quádruplas de desvio 18, 20 Quádruplas de desvio 18, 20 e e quádrupla 22quádrupla 22 Quádruplas de desvio 30 Quádruplas de desvio 30 e e quádrupla 32quádrupla 32 Quádruplas de desvio 35, 37 Quádruplas de desvio 35, 37 e e quádrupla 39quádrupla 39 Quádrupla de desvio 45 Quádrupla de desvio 45 e e quádrupla 47quádrupla 47 Quádruplas de desvio 15, 27, 53 Quádruplas de desvio 15, 27, 53 e e quádrupla 64quádrupla 64 Quádruplas de desvio 42, 50 Quádruplas de desvio 42, 50 e e quádrupla 52quádrupla 52
Para esse Para esse preenchimentopreenchimento, essas quádruplas podem ser , essas quádruplas podem ser colocadas numa colocadas numa lista de quádruplaslista de quádruplas a fazer parte do a fazer parte do atributoatributo dos não-terminais da formação do dos não-terminais da formação do comando comando casecase
Quando a Quando a quádrupla destinoquádrupla destino dos desvios for gerada, tais dos desvios for gerada, tais rótulos serão preenchidosrótulos serão preenchidos
Observa-se também que o resultado da Observa-se também que o resultado da expressão expressão central do casecentral do case será o será o primeiro operandoprimeiro operando de várias de várias quádruplas:quádruplas:
No 1No 1oo case: case: operando operando (VAR, ##1)(VAR, ##1) nas quádruplas nas quádruplas 3, 5, 7, 17, 19, 29 e 553, 5, 7, 17, 19, 29 e 55
No 2No 2oo case: case: operando operando (VAR, ##12)(VAR, ##12) nas nas quádruplas quádruplas 34, 36 e 4434, 36 e 44
É conveniente que É conveniente que esses operandosesses operandos sejam colocados sejam colocados numa numa pilhapilha apropriada, no momento em que a apropriada, no momento em que a expressão centralexpressão central de seu case é analisada, e sejam de seu case é analisada, e sejam dela dela retiradosretirados no no final da análisefinal da análise do seu case do seu case
As estruturas para tais As estruturas para tais listas de quádruplaslistas de quádruplas e tal e tal pilha pilha de operandosde operandos bem como as declarações e programação bem como as declarações e programação para a geração de quádruplas para comandos para a geração de quádruplas para comandos case case ficam como exercícioficam como exercício
7.4 – Quádruplas para 7.4 – Quádruplas para PonteirosPonteiros
Seja o seguinte trecho Seja o seguinte trecho
de programa:de programa:
local:local:
int a, b, x, @y;int a, b, x, @y;
statements:statements:
y := &x;y := &x;
x := #y + a;x := #y + a;
#y := a + b;#y := a + b;
Suas possíveis quádruplas:
2) ENDEROP, (VAR, x), (IDLE), (VAR, ##1)3) ATRIBOP, (VAR, ##1), (IDLE), (VAR, y)4) CONTAPONT, (VAR, y), (IDLE), (VAR, ##2)5) MAISOP, (VAR, ##2), (VAR, a), (VAR, ##3)6) ATRIBOP, (VAR, ##3), (IDLE), (VAR, x)7) MAISOP, (VAR, a), (VAR, b), (VAR, ##4)8) ATRIBPONT, (VAR, ##4), (IDLE), (VAR, y)
Produções para referências a ponteiros:
FatorFator : : Variavel | CTINT | CTREAL Variavel | CTINT | CTREAL
| | CTCHAR | TRUE CTCHAR | TRUE | FALSE | FALSE
| | ~ Fator | ( Expressao )~ Fator | ( Expressao )
|| CallFunc | CallFunc | # Variavel# Variavel
CmdAtribCmdAtrib :: LadoEsquerdo := Expressao ;LadoEsquerdo := Expressao ;
|| LadoEsquerdo := & Variavel LadoEsquerdo := & Variavel ;;
LadoEsquerdo:LadoEsquerdo: Variavel | Variavel | # Variavel # Variavel
A programação para a geração de quádruplas A programação para a geração de quádruplas envolvendo ponteiros fica como exercícioenvolvendo ponteiros fica como exercício
7.5 – Quádruplas para 7.5 – Quádruplas para SubprogramaçãoSubprogramação
Produções envolvidas:Produções envolvidas:
ComandoComando : CallMod: CallMod
CallModCallMod : CALL CallFunc PVIRG : CALL CallFunc PVIRG
CallFuncCallFunc : ID ABPAR Argumentos FPAR: ID ABPAR Argumentos FPAR
ArgumentosArgumentos : : || ListExpr ListExpr
ListExprListExpr : Expressao : Expressao
| ListExpr VIRG Expressao| ListExpr VIRG Expressao
CmdReturnCmdReturn : RETURN PVIRG: RETURN PVIRG
| RETURN Expressao PVIRG| RETURN Expressao PVIRG
FatorFator : CallFunc: CallFunc
7.5.1 – Chamada de subprogramas7.5.1 – Chamada de subprogramas
Exemplo:Exemplo: na função na função mainmain do programa inicial, o do programa inicial, o comandocomando
comb = fat(m) / (fat(m-n) * fat(n));comb = fat(m) / (fat(m-n) * fat(n));
tem as seguintes tem as seguintes
quádruplas:quádruplas:
34) PARAM, (VAR, m), (IDLE), (IDLE)35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19)36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20)37) PARAM, (VAR, ##20), (IDLE), (IDLE)38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21)39) PARAM, (VAR, n), (IDLE), (IDLE)40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22)41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23)42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24)43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)
Nas produções dos não-terminais Nas produções dos não-terminais ListExpr ListExpr e e ArgumentosArgumentos::
ListExpr ListExpr : Expressao {: Expressao {$$.nargs = 1; $$.listtipo = InicListTipo ($1.tipo);$$.nargs = 1; $$.listtipo = InicListTipo ($1.tipo);GeraQuadrupla (PARAM, $1.opnd, opndidle, GeraQuadrupla (PARAM, $1.opnd, opndidle,
opndidle);opndidle);}}
| ListExpr VIRG Expressao {| ListExpr VIRG Expressao {$$.narg = $1.narg + 1;$$.narg = $1.narg + 1;$$.listtipo = $$.listtipo =
ConcatListTipo ($1.listtipo, InicListTipo ($3.tipo));ConcatListTipo ($1.listtipo, InicListTipo ($3.tipo));GeraQuadrupla (PARAM, $3.opnd, opndidle, GeraQuadrupla (PARAM, $3.opnd, opndidle,
opndidle);opndidle);}}
;;
ArgumentosArgumentos : : {$$.nargs = 0; $$.listtipo = NULL;} {$$.nargs = 0; $$.listtipo = NULL;} | ListExpr /* default: $$ = $1; */| ListExpr /* default: $$ = $1; */
O não-terminal O não-terminal CallFunc CallFunc pode ter o mesmo pode ter o mesmo atributo que o não-terminal atributo que o não-terminal VariavelVariavel::
%type <infovar> Variavel %type <infovar> Variavel CallFuncCallFunc
Onde:Onde:
E também:E também:
Então o atributo de Então o atributo de CallFuncCallFunc tem dois tem dois campos:campos:
simb simb e e opndopnd
%union {- - - - -infovariavel
infovar;- - - - -
}
typedef struct infovariavel infovariavel;struct infovariavel { simbolo simb; operando opnd; };
Na produção do não-terminal Na produção do não-terminal CallFuncCallFunc::
CallFuncCallFunc : ID ABPAR {: ID ABPAR {
simb = ProcuraSimb ($1, escopo->escopo);simb = ProcuraSimb ($1, escopo->escopo);
$<simb>$ = simb;$<simb>$ = simb; if (! simb) if (! simb) NaoDeclarado ($1);NaoDeclarado ($1);
} Argumentos FPAR { $$.simb = $<simb>3;} Argumentos FPAR { $$.simb = $<simb>3;
- - - - - Testes de compatibilidade - - - - -- - - - - Testes de compatibilidade - - - - -
opnd1.tipo = FUNCOPND;opnd1.tipo = FUNCOPND; opnd1.atr.func = $opnd1.atr.func = $$.simb->fhead;$.simb->fhead;
opnd2.tipo = INTOPND;opnd2.tipo = INTOPND; opnd2.atr.valint = $4.nargs;opnd2.atr.valint = $4.nargs;
if ($$.simb->tvar == NAOVAR) result = opndidle;if ($$.simb->tvar == NAOVAR) result = opndidle;
else {else { result.tipo = VAROPND;result.tipo = VAROPND;
result.atr.simb = NovaTemp ($$.simb->tvar);result.atr.simb = NovaTemp ($$.simb->tvar); } }
GeraQuadrupla (CALLOP, opnd1, opnd2, result);GeraQuadrupla (CALLOP, opnd1, opnd2, result);
$$.opnd = result;$$.opnd = result;
} } ;;
Mais um campo na TabSimb:
um ponteiro para um funchead
Na produção do não-terminal Na produção do não-terminal FatorFator::
FatorFator : CallFunc : CallFunc { {
if ($1.simb != NULL) {if ($1.simb != NULL) {
$$.tipo = $1.simb->tvar;$$.tipo = $1.simb->tvar;
$$.opnd = $1.opnd;$$.opnd = $1.opnd;
}}
} }
;;
Não há programação especial para a produção:Não há programação especial para a produção:
CallModCallMod : CALL CallFunc PVIRG : CALL CallFunc PVIRG ;;
7.5.3 – Retorno de subprogramas7.5.3 – Retorno de subprogramas
Nas produções do não-terminal Nas produções do não-terminal CmdReturnCmdReturn
CmdReturnCmdReturn :: RETURN {RETURN {
GeraQuadrupla (RETURNOP, opndidle, opndidle, GeraQuadrupla (RETURNOP, opndidle, opndidle, opndidle);opndidle);
}}
|| RETURN Expressao {RETURN Expressao {
GeraQuadrupla (RETURNOP, $2.opnd, opndidle, GeraQuadrupla (RETURNOP, $2.opnd, opndidle, opndidle);opndidle);
}}
;;
Para o caso de uma função não ter Para o caso de uma função não ter retorno retorno explícitoexplícito, deve-se , deve-se gerar uma quádruplagerar uma quádrupla com a com a operação de operação de retornarretornar
Isso é feito na produção do não terminal Isso é feito na produção do não terminal CmdsCmds::
CmdsCmds : STATEMENTS ABCHAV ListCmds FCHAV {: STATEMENTS ABCHAV ListCmds FCHAV {
if (quadcorrente->oper != RETURNOP)if (quadcorrente->oper != RETURNOP)
GeraQuadrupla (RETURNOP, opndidle, opndidle, GeraQuadrupla (RETURNOP, opndidle, opndidle, opndidle);opndidle);
- - - - -- - - - -
}}
;;
Lembrando o contexto do não-terminal Lembrando o contexto do não-terminal CmdsCmds::
ModuloModulo : Cabecalho DeclLocs Cmds: Cabecalho DeclLocs Cmds
Garante que a última quádrupla de qualquer função é um RETURN
Mesmo que a função tenha RETURN fora do final
Recommended