-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgrammar_converter.py
66 lines (56 loc) · 2.21 KB
/
grammar_converter.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 numpy as np
class GrammarConverter:
def __init__(self, CFG):
with open(CFG, encoding = 'utf-8') as cfg:
lines = cfg.readlines() # first line is dedicated for list of non-terminals
CFG = [x.replace(" ->", "").split() for x in lines[1:]]
CFG = np.unique(np.array(CFG, dtype = object)).tolist()
self.CFG = CFG
self.rules = {}
self.CNF = None
def convert_grammar(self):
prods = []
for r in self.CFG:
p0 = r[0]
p1 = r[1:]
if len(p1) <= 2:
if p0 not in self.rules.keys():
self.rules[p0] = []
self.rules[p0].append(p1)
else:
prods.append([p0] + p1)
while prods:
for prod in prods:
p0 = prod[0]
p1 = prod[1:]
for j in range(0, len(p1)-1, 1):
query = p1[j:j+2]
for key in list(self.rules.keys()):
for match in self.rules[key]:
if query == match:
potential_rule = replace(p1, query, [key])
if len(potential_rule) > 2:
prods.append([p0] + potential_rule)
if prod in prods:
prods.remove(prod)
elif len(potential_rule) == 2:
if prod in prods:
prods.remove(prod)
if p0 not in list(self.rules.keys()):
self.rules[p0] = []
self.rules[p0].append(potential_rule)
else:
'problem'
CNF = []
for key in self.rules.keys():
p0 = [key]
for p1 in self.rules[key]:
CNF.append(p0 + p1)
self.CNF = CNF
return CNF
def replace(lst, a, b):
str_l = " ".join(lst)
str_a = " ".join(a)
str_b = " ".join(b)
str_l = str_l.replace(str_a, str_b)
return str_l.split()