-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexpressoes_disponiveis.py
More file actions
135 lines (121 loc) · 5.05 KB
/
expressoes_disponiveis.py
File metadata and controls
135 lines (121 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import re
import os
class BlocoBasico:
"""
Representa um bloco básico no grafo de fluxo de controle.
"""
def __init__(self, numero):
self.numero = numero
self.instrucoes = []
self.sucessores = []
self.predecessores = []
self.gen_ae = set()
self.kill_ae = set()
self.in_ae = set()
self.out_ae = set()
def extrair_partes_instrucao(instrucao):
"""
Extrai a variável definida e a expressão do lado direito.
"""
if '=' in instrucao:
definida, lado_dir = instrucao.split('=', 1)
definida = definida.strip()
op_match = re.search(r'[\+\-\*\/]', lado_dir)
if op_match:
expressao = "".join(lado_dir.split())
return definida, expressao
return definida, None
return None, None
def pre_processar_expressoes(blocos):
"""Encontra todas as expressões únicas no programa."""
todas_expressoes = set()
for bloco in blocos.values():
for instrucao in bloco.instrucoes:
_, expressao = extrair_partes_instrucao(instrucao)
if expressao:
todas_expressoes.add(expressao)
return todas_expressoes
def calcular_gen_kill_ae(blocos, todas_expressoes):
"""
Calcula os conjuntos gen e kill para cada bloco.
"""
for bloco in blocos.values():
disponibilidade_local = set()
for instrucao in bloco.instrucoes:
definida, expressao = extrair_partes_instrucao(instrucao)
if definida:
exp_a_remover = {expr for expr in disponibilidade_local if re.search(r'\b' + re.escape(definida) + r'\b', expr)}
disponibilidade_local -= exp_a_remover
if expressao:
operandos = re.findall(r'[a-zA-Z_]\w*', expressao)
if definida not in operandos:
disponibilidade_local.add(expressao)
bloco.gen_ae = disponibilidade_local
defs_deste_bloco = {p[0] for p in [extrair_partes_instrucao(i) for i in bloco.instrucoes] if p[0]}
for expr in todas_expressoes:
operandos_expr = re.findall(r'[a-zA-Z_]\w*', expr)
if any(op in defs_deste_bloco for op in operandos_expr):
bloco.kill_ae.add(expr)
def analisar_expressoes_disponiveis(blocos, todas_expressoes):
for bloco in blocos.values():
if bloco.predecessores:
bloco.out_ae = todas_expressoes.copy()
alterou = True
while alterou:
alterou = False
for num_bloco in sorted(blocos.keys()):
bloco = blocos[num_bloco]
if not bloco.predecessores:
in_set = set()
else:
in_set = todas_expressoes.copy()
for p_num in bloco.predecessores:
in_set.intersection_update(blocos[p_num].out_ae)
out_antigo = bloco.out_ae
bloco.in_ae = in_set
bloco.out_ae = bloco.gen_ae.union(bloco.in_ae - bloco.kill_ae)
if bloco.out_ae != out_antigo:
alterou = True
def ler_entrada_e_construir_grafo(dados_entrada):
blocos = {}
linhas = dados_entrada.strip().split('\n')
i=0
while i < len(linhas):
parts = linhas[i].split();
if not parts: i+=1; continue
num, n_inst = int(parts[0]), int(parts[1]); i+=1
bloco = BlocoBasico(num)
bloco.instrucoes = [l.strip() for l in linhas[i:i+n_inst]]; i+=n_inst
bloco.sucessores = [int(s) for s in linhas[i].split() if s != '0']; i+=1
blocos[num] = bloco
for num, bloco in blocos.items():
for suc in bloco.sucessores:
if suc in blocos: blocos[suc].predecessores.append(num)
return blocos
def main():
PASTA_ENTRADA = "in"
PASTA_SAIDA = "out"
if not os.path.isdir(PASTA_ENTRADA):
print(f"Erro: Pasta '{PASTA_ENTRADA}' não encontrada."); return
os.makedirs(PASTA_SAIDA, exist_ok=True)
for nome_ficheiro in os.listdir(PASTA_ENTRADA):
caminho_entrada = os.path.join(PASTA_ENTRADA, nome_ficheiro)
nome_saida = os.path.splitext(nome_ficheiro)[0] + "_ae.txt"
caminho_saida = os.path.join(PASTA_SAIDA, nome_saida)
with open(caminho_entrada, 'r', encoding='utf-8') as f: dados_entrada = f.read()
blocos = ler_entrada_e_construir_grafo(dados_entrada)
todas_expressoes = pre_processar_expressoes(blocos)
calcular_gen_kill_ae(blocos, todas_expressoes)
analisar_expressoes_disponiveis(blocos, todas_expressoes)
with open(caminho_saida, 'w', encoding='utf-8') as f:
f.write("Resultado das Expressões Disponíveis:\n")
for num_bloco in sorted(blocos.keys()):
bloco = blocos[num_bloco]
in_str = sorted(bloco.in_ae)
out_str = sorted(bloco.out_ae)
f.write(f"IN[{bloco.numero}] = {in_str}\n")
f.write(f"OUT[{bloco.numero}] = {out_str}\n")
f.write("--------------------\n")
print(f"Análise de '{caminho_entrada}' salva em '{caminho_saida}'")
if __name__ == "__main__":
main()