-
Notifications
You must be signed in to change notification settings - Fork 0
/
production.py
121 lines (104 loc) · 3.12 KB
/
production.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
120
121
from typing import *
class Node:
def __init__(self, node_type: str, content: str):
self.type = node_type
self.content = content
class ProductorBody:
def __init__(self, *args: str):
self.body = [] # type:List[Node]
for node in args:
if node.startswith('<'): # a non-terminate
self.body.append(Node('n', node))
else:
self.body.append(Node('t', node))
def __iter__(self):
return iter(self.body)
def __str__(self):
r = ''
for node in self.body:
r += node.content
return r
class Productor:
def __init__(self):
self.productor = {} # type: Dict[str, List[ProductorBody]]
self.productor = {
'<SL>': [
ProductorBody('<S>'),
ProductorBody('<S>', ';', '<SL>'),
],
'<S>': [
ProductorBody('<AS>'),
ProductorBody('<CS>'),
ProductorBody('<WHILE>'),
ProductorBody('<MS>'),
],
'<AS>': [
ProductorBody('<V>',":=",'<E>'),
],
'<CS>': [
ProductorBody('if', '<RS>', 'then', '<S>', 'else', '<S>'),
],
'<WHILE>': [
ProductorBody('while', '<RS>', 'do', '<S>'),
],
'<MS>': [
ProductorBody('begin', '<RS>', 'do', '<S>'),
],
'<E>': [
ProductorBody('<T>'),
ProductorBody('<E>', '+', '<T>'),
ProductorBody('<E>', '-', '<T>'),
],
'<T>': [
ProductorBody('<F>'),
ProductorBody('<T>', '*', '<F>'),
ProductorBody('<T>', '/', '<F>'),
],
'<F>': [
ProductorBody('<V>'),
ProductorBody('INT'),
ProductorBody('(', '<E>', ')'),
],
'<RS>': [
ProductorBody('<E>', '<OP>', '<E>'),
],
'<V>': [
ProductorBody('ID'),
],
'<OP>': [
ProductorBody('<'),
ProductorBody('<='),
ProductorBody('<>'),
ProductorBody('>'),
ProductorBody('>='),
ProductorBody('='),
]
}
self.first = {} # type:Dict[str, List[str]]
self.follow = {} # type:Dict[str, List[str]]
def caculate_first(self):
"""
caculate non-terminate's first set.
:return:
"""
def load(self, file_path: str):
"""
load productor from file
:param file_path: path to the productor file
:return:
"""
pass
def __str__(self):
r = ''
for head, body in self.productor.items():
r += head
r += ' -> '
for b in body[:len(body)-1]:
r += str(b)
r += ' | '
r += str(body[len(body)-1])
r += '\n'
return r
if __name__ == "__main__":
p = Productor()
print (p)