Good afternoon, guys. I am in a compilers matter step which is the intermediate code generation of my grammar. After the steps of lexical, syntactic, semantic analysis.
Basically I have the following code:
from infixToPostfix import infixToPostfix # Importação da função que faz a conversão de infixa pra posfixa
def verAtribuicao(variavel, i, cod, tok):
ex = ''
while tok[i][1] != 'fim_linha': # Enquanto não encontrar um token de fim linha
ex += ' ' + tok[i][0] # o buffer acumula os tokens encontrados
i += 1
return tac(variavel, infixToPostfix(ex), cod, i) # Chama a função tac (three address code) passando a variavel, expressao pos fixada, a lista e a iteração
def tac(var, expression, cod, it):
exp = expression.split()
stack = []
oper = ['+', '-', '*', '/']
for i in range(len(exp)):
if exp[i] in oper:
v1 = stack.pop()
v2 = stack.pop()
t = f'{v2} {exp[i]} {v1}'
if len(exp) == i+1:
cod.append(f'{var} := {t}')
else:
cod.append(f'_t{it} := {t}')
stack.append(f'_t{it}')
it += 1
else:
stack.append(exp[i])
if len(stack) == 1:
cod.append(f'{var} := {stack[0]}')
# Abertura da lista de tokens retornada na análise léxica
with open("lista_tokens.txt", "r") as arquivo:
tk = arquivo.readlines()
# variáveis de controle
i = 0
ctrl = 0
# declaração das listas de apoio
cod_intermediario = []
registro_log = []
tokens = []
# Loop apenas pra inserir as informações das linhas já delimitado
for j in tk:
tokens.append(j.split('|'))
# Faz a verificação da declaração das variáveis
for tk in tokens:
if tk[1] == 'id' and tokens[ctrl-1][1] == 'tiponum':
cod_intermediario.append(f'INTEIRO {tk[0]}')
registro_log.append(f'Declaração da variável {tk[0]}')
ctrl += 1
def verifica(tokens, i, L, C): # Função para fazer a verificação de leitura, escrita e atribuição
expressao = ''
if tokens[i][1] == 'ler': # Verifica se o token é de leitura, mostra o token e pula 4 iterações
cod_intermediario.append(f'LEIA {tokens[i+2][0]}')
registro_log.append(f'Reconhecido comando leitura da variável {tokens[i+2][0]}')
i += 4
elif tokens[i][1] == 'escrever': # Verifica se o token é de escrita, mostra o token e pula 4 iterações
cod_intermediario.append(f'ESCREVA {tokens[i+2][0]}')
registro_log.append(f'Reconhecido comando de escrita')
i += 4
elif tokens[i][1] == 'atribuicao': # Verifica se o token é de atribuição e avança 1 iteração
variavel = tokens[i - 1][0]
i += 1
registro_log.append(f'Reconhecido expressão atribuída para {tokens[i-2][0]}')
verAtribuicao(variavel, i, cod_intermediario, tokens)
elif tokens[i][1] == 'enquanto': # Verifica se o token encontrado é um enquanto
i += 2
while tokens[i][1] != 'parenteses_fecha': # enquanto não encontrar um fechamento de parenteses, acumula os tokens no buffer
expressao += ' ' + tokens[i][0]
i += 1
if expressao.split()[1] == '<=':
operador = '>'
elif expressao.split()[1] == '>=':
operador = '<'
elif expressao.split()[1] == '==':
operador = '='
cod_intermediario.append(f'_L{L}: if {expressao.split()[0]} {operador} {expressao.split()[2]} goto _L{L+1}')
i += 2
i = verifica(tokens, i, L+1, C)
cod_intermediario.append(f'_L{L+1}:')
registro_log.append(f'Reconhecido expressão enquanto para {expressao}')
elif tokens[i][1] == 'se': # Verifica se o token encontrado é um enquanto
i += 2
while tokens[i][1] != 'parenteses_fecha': # enquanto não encontrar um fechamento de parenteses, acumula os tokens no buffer
expressao += ' ' + tokens[i][0]
i += 1
if expressao.split()[1] == '<=':
operador = '>'
elif expressao.split()[1] == '>=':
operador = '<'
elif expressao.split()[1] == '==':
operador = '='
cod_intermediario.append(f'_C{C}: if {expressao.split()[0]} {operador} {expressao.split()[2]} goto _C{C+1}')
i += 2
cod_intermediario.append(f'_C{C+1}:')
registro_log.append(f'Reconhecido expressão se para {expressao}')
return i
L = C = 0
while i < len(tokens):
i = verifica(tokens, i, L, C)
i += 1
for t in registro_log:
print(t)
print('\n')
print('*' * 50)
print('\n')
for j in cod_intermediario:
print(j)
Within the function checks I have two conditions: When a "while" is encountered, and when a "if" is found.
Let's say in my grammar below:
run
integer f = 1;
integer i = 1;
integer n;
display("Digite qual numero deseja calcular a fatorial");
input(n);
while(i <= n){
f = f * i;
i = i+1;
}
exit
As I have a while and within that while I have two rows of assignments, so far so good ... but for example, it can happen inside of it having an if, or another while, etc. Can someone help me get an idea of what to do in this case? Thanks!