-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.py
105 lines (95 loc) · 3.97 KB
/
parser.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
import matrix
class Parser:
def __init__(self, op_matrix, operators, rules):
self.operators = operators
self.t = ['/b/', *operators]
self.operator_matrix = op_matrix
self.error = False
self.error_msg = "Parser: OK"
self.stack = []
self.rules: dict = rules
def set_error(self, msg):
self.error = True
self.error_msg = "Parser: " + msg
def print_matrix(self):
pass
def get_t(self, n=1):
if n < 1:
n = 1
for item in self.stack[::-1]:
if item in self.t:
n -= 1
if n == 0:
return item
return "ERROR"
def check(self):
self.stack.append('/b/')
i = 0
while True:
if self.get_t() == '/b/' and self.operators[i] == '/e/':
break
if self.get_t() not in self.operator_matrix.keys() or self.operators[i] not in self.operator_matrix[self.get_t()].keys():
self.set_error("unknown construction '" + self.get_t() + " " + self.operators[i] + "' in " + " ".join(self.operators[i-2:i+1]))
break
if self.operator_matrix[self.get_t()][self.operators[i]] == matrix.ORDER.EQUALS or self.operator_matrix[self.get_t()][self.operators[i]] == matrix.ORDER.PRECEDED:
self.stack.append(self.operators[i])
i += 1
elif self.operator_matrix[self.get_t()][self.operators[i]] == matrix.ORDER.FOLLOWS:
rule = []
if self.operator_matrix[self.get_t(2)][self.get_t()] == matrix.ORDER.PRECEDED:
count = 1
while True:
if self.stack[-1] in self.t:
if count == 0:
break
count -= 1
rule.append(self.stack.pop())
find = False
rule.reverse()
# print("RULE:", rule)
for name in self.rules.keys():
for r in self.rules[name]:
if rule == r:
find = True
self.stack.append("E")
break
if find:
break
if not find:
self.set_error("Unable to locate rule " + " ".join(rule))
break
# print("NAME:", name)
# print(self.stack)
elif self.operator_matrix[self.get_t(2)][self.get_t()] == matrix.ORDER.EQUALS:
count = 2
while self.operator_matrix[self.get_t(count+1)][self.get_t(count)] == matrix.ORDER.EQUALS:
count += 1
# print(count)
while True:
if self.stack[-1] in self.t:
if count == 0:
break
count -= 1
rule.append(self.stack.pop())
find = False
rule.reverse()
# print("RULE:", rule)
for name in self.rules.keys():
for r in self.rules[name]:
if rule == r:
find = True
self.stack.append("E")
break
if find:
break
if not find:
self.set_error("Unable to locate rule " + " ".join(rule))
break
# print("NAME:", name)
# print(self.stack)
if __name__ == "__main__":
source_path = "grammar.txt"
input_stream = open(source_path, 'r')
gen = matrix.MatrixGenerator(input_stream)
gen.generate()
print(gen.error_msg)