Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a "tree walk" recursively on an Abstract Syntax Tree?

Simple example of assignment in my language:

x = 3 ->

Here's the generated AST after parsing (In Python):

[('statement', ('assignment', 'x', ('assignment_operator', '='), ('expr', ('term', ('factor', '3')))), '->')]

How can I recursively access any possible depth in order to, in the most trivial case, print all of them? (Or convert the text into something else?). Is there a specific algorithm for doing this? If there is, do you recommend any specific material?

like image 964
Ericson Willians Avatar asked Aug 21 '16 10:08

Ericson Willians


People also ask

How do you walk an Abstract Syntax Tree?

To walk a tree, just use a stack or a queue (depending on wether you want to go depth first or breath first). For each node encountered, push the children onto the stack or into the queue, then take the next item out of the data structure to process and repeat.

What do you do with an Abstract Syntax Tree?

Application in compilers. Abstract syntax trees are data structures widely used in compilers to represent the structure of program code. An AST is usually the result of the syntax analysis phase of a compiler.

What makes Abstract Syntax Tree better than parse tree?

Abstract syntax trees are important data structures in a compiler. It contains the least unnecessary information. Abstract syntax trees are more compact than a parse tree and can be easily used by a compiler.

What is the difference between syntax tree and Abstract Syntax Tree?

An Abstract Syntax Tree describes the parse tree logically. It does not need to contain all the syntactical constructs required to parse some source code (white spaces, braces, keywords, parenthesis etc). That's why Parse Tree is also called Concrete Syntax Tree while the AST is called Syntax Tree .


1 Answers

To walk a tree, just use a stack or a queue (depending on wether you want to go depth first or breath first).

For each node encountered, push the children onto the stack or into the queue, then take the next item out of the data structure to process and repeat.

For example, breath first could look like this:

from collections import deque

def walk(node):
    queue = deque([node])
    while queue:
        node = queue.popleft()
        if isinstance(node, tuple):
            queue.extend(node[1:])  # add the children to the queue
        yield node

which produces the following walking order for your tree:

>>> for node in walk(tree[0]):
...     print(node[0] if isinstance(node, tuple) else node)
...
statement
assignment
->
x
assignment_operator
expr
=
term
factor
3

Your data structure is a little messy, mixing tuples of different length. You may want to look to using a nametuple class to formalise the contents a little.

like image 177
Martijn Pieters Avatar answered Oct 22 '22 14:10

Martijn Pieters