-
Notifications
You must be signed in to change notification settings - Fork 1
/
tree_parse.py
71 lines (67 loc) · 1.87 KB
/
tree_parse.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
NUMBER = 1
STRING = 2
WHITESPACE = 3
SYMBOL = 4
def getmode(char):
modes = {NUMBER: '1234567890.',
WHITESPACE: ' \t\n',
SYMBOL: '()'}
for m in modes:
if char in modes[m]:
return m
# else ... default mode is STRING
return STRING
def tokeniser(string):
"A generator that yields tokens based on input"
mode = WHITESPACE
forming_token = ""
for ch in string:
newmode = getmode(ch)
if newmode == mode:
if mode != SYMBOL:
forming_token += ch
else:
yield forming_token
forming_token = ch
else:
if forming_token.strip() != '':
yield forming_token
else:
pass
forming_token = ch
mode = newmode
yield forming_token
def createTree(string, rootNode=None):
"Creates a tree from a string like (+ (- 2 3) (a))"
cur_node = TreeNode('') # root node
for token in tokeniser(string):
if token == '(':
new_root = TreeNode('')
cur_node.addNodeBelow(new_root)
cur_node = new_root
elif token == ')':
cur_node = cur_node.above
else:
cur_node.addNodeBelow(TreeNode(token))
return cur_node.below[0]
class TreeNode:
"A single Node in a Tree"
def __init__(self, token):
self.token = token
self.above = None
self.below = []
def addNodeBelow(self, node):
node.above = self
self.below.append(node)
def toList(self):
if len(self.below) == 0:
try:
return float(self.token)
except ValueError:
return self.token
l = self.below
for i in range(len(l)):
x = l[i]
if isinstance(x,TreeNode):
l[i] = x.toList()
return l