Added basic version of tree-to-text generator.

parent 792f984d
def generate_line(root, node_type):
"""
Print an expression tree in a single text line. Where needed, add
parentheses.
>>> from node import Node, Leaf
>>> #from graph import generate_graph
>>> l0, l1 = Leaf(1), Leaf(2)
>>> n0 = Node('+', l0, l1)
>>> print generate_line(n0, Node)
1 + 2
>>> n1 = Node('+', l0, l1)
>>> n2 = Node('*', n0, n1)
>>> print generate_line(n2, Node)
(1 + 2) * (1 + 2)
>>> l2 = Leaf(3)
>>> n3 = Node('-', l2)
>>> n4 = Node('*', n1, n3)
>>> print generate_line(n4, Node)
(1 + 2) * -3
>>> #integral = Node('int', n0, n1)
"""
operators = [
('+', '-'),
('*', '/'),
('^', )
]
max_assoc = len(operators)
def assoc(node):
"""
Get the associativity of an operator node.
"""
if isinstance(node, node_type) and len(node) > 1:
op = node.title()
for i, group in enumerate(operators):
if op in group:
return i
return max_assoc
def traverse(node):
"""
The expression tree is traversed using preorder traversal:
1. Visit the root
2. Traverse the left subtree
3. Traverse the right subtree
"""
s = node.title()
if not isinstance(node, node_type):
return s
arity = len(node)
if arity == 1:
# Unary expression
s += traverse(node[0])
elif arity == 2:
# Binary expression
left, right = map(traverse, node)
# Check if there is an assiociativity conflict on either side. If
# so, add parentheses
if assoc(node[0]) < assoc(node):
left = '(' + left + ')'
if assoc(node[1]) < assoc(node):
right = '(' + right + ')'
s = left + ' ' + s + ' ' + right
return s
return traverse(root)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment