Intermediate code generation - Verification recursion

1

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!

    
asked by anonymous 01.12.2018 / 16:03

0 answers