-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcnf.py
66 lines (58 loc) · 2.1 KB
/
cnf.py
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
import re
class CNF:
def __init__(self):
self.rules: dict[str, list[list[str]]] = {}
self.start = 'START'
@staticmethod
def get_var_name(i: int) -> str:
alphabet = chr(i % 26 + ord('A'))
num = i // 26
if num > 0:
alphabet += str(num)
return alphabet
def dump(self, filename: str):
with open(filename, 'w') as f:
strs = []
start = self.rules.pop(self.start)
strs.append(
f"{self.start} -> " + " | ".join([" ".join(right) for right in start]))
for key, value in self.rules.items():
strs.append(
f"{key} -> " + " | ".join([" ".join(right) for right in value]))
f.write("\n".join(strs))
def load(self, filename: str):
self.rules = {}
with open(filename, 'r') as f:
buffer = f.readlines()
self.start = None
for rule in buffer:
left, right = re.split(r' *-> *', rule)
if self.start is None:
self.start = left
rightList = []
for r in re.split(r' *\| *', right):
rule = []
for x in r.split():
if x == "space":
x = " "
elif x == "newline":
x = "\n"
elif x == "or":
x = "|"
rule.append(x)
rightList.append(rule)
self.rules[left] = rightList
def subtitute_all_postfix(self, postfix, replacement: str):
keys = list(self.rules.keys())
for key in keys:
value = self.rules[key]
for right in value:
if right[-len(postfix):] == postfix:
right[-len(postfix):] = [replacement]
def subtitute_all(self, old: str, new: str):
for key, value in self.rules.items():
value = self.rules[key]
for right in value:
for i in range(len(right)):
if right[i] == old:
right[i] = new