-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
120 lines (113 loc) · 3.73 KB
/
main.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
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
# Author: Max Base
# Date: 2020/06/17
# Web: maxbase.org
# Repo: https://github.com/BaseMax/CFG2CNF
import sys
print("Enter your grammers with `S -> ab` similar style, Also you can split grammers by | and even write grammers in diffrent lines\nand finaly type *:")
moves={}
rules={}
# alphas=list(map(chr, range(97, 123)))
alphas=['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
while True:
line=input()
if line == "*":
break
parts=line.split("->")
parts[0]=parts[0].strip()
parts[1]=parts[1].strip()
parts[1]=parts[1].split("|")
# print(parts)
if not parts[0] in rules:
rules[parts[0]]=[]
for part in parts[1]:
part=part.strip()
# print(part)
rules[parts[0]].append(part)
def new_name_for_grammer(array):
names=list(array)
# print(names)
for alpha in alphas:
if alpha not in names:
return alpha
print("Error: cannot find a new and fresh name for new Grammer statement!")
sys.exit(-1)
def delta_add_other_case_for_his(array, key):
index = 0
count = len(array[key])
if count == 0:
return None
while index < count:
if key in array[key][index]:
array[key].append(array[key][index].replace(key, ""))
index+=1
return array[key]
def delta_add_other_case_for_others(array, target):
for key in list(array):
if key != target:
index = 0
count = len(array[key])
while index < count:
if target in array[key][index]:
array[key].append(array[key][index].replace(target, ""))
index+=1
return array
def move_terminals_to_new_grammers(array):
# print("Result until this step:", array)
for key in list(array):
# print("\n\n= checking new key:", key)
index = 0
count = len(array[key])
# print("Count of", key,"grammer is",count)
while index < count:
value=array[key][index]
length=len(value)
# print("\n---- parsing", value)
# print("Value as", array[key])
i=0
while i < length:
# print("* Value as", array[key])
if str(value[i]).islower():
if value[i] not in list(moves):
name=new_name_for_grammer(array)
moves[value[i]]=name
# print("Create", name,"statement for",value[i],"terminal char!",)
array[name]=[]
array[name].append(value[i])
else:
name=moves[value[i]]
# print("found", value[i], "in", array[key][index], "will rename to", name)
array[key][index]=array[key][index].replace(value[i], name)
# print(array[key])
# print(value[i])
i+=1
index+=1
return array
def replace_grammer_statement_names(array, key, char):
print("Found big character(s)", char, "in", key, "statement")
print("Check move tables:", moves)
# print(moves.values())
if char not in list(moves.values()):
print("Error: find a non-terminal upper-case character, we cannot support one statement with one Upper-case non-terminalestic!")
sys.exit(-1)
return array
def formatter_grammers(array):
for key in list(array):
index = 0
count = len(array[key])
while index < count:
# if count == 1:
# elif count >= 2:
length=len(array[key][index])
if length == 1:
if not array[key][index][0].islower():
array=replace_grammer_statement_names(array, key, array[key][index])
elif length > 2:
# print("Found a non-standard grammer:", array[key][index])
values=array[key][index][1:]
name=new_name_for_grammer(array)
# print("Create", name,"statement for", values)
array[name]=[]
array[name].append(values)
array[key][index]=array[key][index].replace(values, name)
index+=1
return array