1
Good afternoon, guys. I’m at a stage in the matter of compilers 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 is found a "while", and when is found a "if".
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 inside that while I have two lines of assignments, so far so good... but for example, it can happen from inside it to have an if, or other while, etc. Can anyone help me to have an idea of what to do in this case? Thank you!