Created
September 16, 2022 06:59
-
-
Save sangwoo-joh/07b132f87470775d138bf6366786b453 to your computer and use it in GitHub Desktop.
Standard Visitor class for tree-sitter, support with `visit` and `leave` callbacks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Very inspired by https://github.com/tree-sitter/py-tree-sitter/pull/90 | |
class Visitor: | |
def visit(self, _node): | |
return True | |
def leave(self, _node): | |
pass | |
def on_visit(self, node): | |
visitor = getattr(self, f"visit_{node.type}", self.visit) | |
return visitor(node) | |
def on_leave(self, node): | |
leaver = getattr(self, f"leave_{node.typ}", self.leave) | |
leaver(node) | |
def walk(self, tree): | |
cursor = tree.walk() | |
has_next = True | |
postorder = [] | |
while has_next: | |
node = cursor.node # current node | |
postorder.append(node) # push to the stack for postorder leave | |
# visit current node, and check subtree first | |
has_next = cursor.goto_first_child() if self.on_visit(node) else False | |
if not has_next: | |
# check sibling, and call leave in postorder | |
has_next = cursor.goto_next_sibling() | |
self.on_leave(postorder.pop()) | |
while not has_next and cursor.goto_parent(): | |
# check parent's siblings, and call leave in postorder. | |
has_next = cursor.goto_next_sibling() | |
self.on_leave(postorder.pop()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment