Skip to content

Instantly share code, notes, and snippets.

@sangwoo-joh
Created September 16, 2022 06:59
Show Gist options
  • Save sangwoo-joh/07b132f87470775d138bf6366786b453 to your computer and use it in GitHub Desktop.
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
# 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