Skip to content

Instantly share code, notes, and snippets.

@podhmo
Created July 6, 2019 08:01
Show Gist options
  • Save podhmo/6c57644f8615d8b10968a134590f5253 to your computer and use it in GitHub Desktop.
Save podhmo/6c57644f8615d8b10968a134590f5253 to your computer and use it in GitHub Desktop.
python 00*.py
@ file_input ...
@ funcdef ...
@ NAME Leaf(1, 'def')
@ NAME Leaf(1, 'f')
@ parameters ...
@ LPAR ...
@ tname ...
@ NAME Leaf(1, 'x')
@ COLON ...
@ NAME Leaf(1, 'int')
@ RPAR ...
@ RARROW ...
@ NAME Leaf(1, 'int')
@ COLON ...
@ suite ...
@ NEWLINE ...
@ INDENT ...
@ if_stmt ...
@ NAME Leaf(1, 'if')
@ comparison ...
@ NAME Leaf(1, 'x')
@ EQEQUAL ...
@ NUMBER ...
@ COLON ...
@ suite ...
@ NEWLINE ...
@ INDENT ...
@ simple_stmt ...
@ return_stmt ...
@ NAME Leaf(1, 'return')
@ NUMBER ...
@ NEWLINE ...
@ DEDENT ...
@ NAME Leaf(1, 'else')
@ COLON ...
@ suite ...
@ NEWLINE ...
@ INDENT ...
@ simple_stmt ...
@ return_stmt ...
@ NAME Leaf(1, 'return')
@ term ...
@ NAME Leaf(1, 'x')
@ STAR ...
@ power ...
@ NAME Leaf(1, 'f')
@ trailer ...
@ LPAR ...
@ arith_expr ...
@ NAME Leaf(1, 'x')
@ MINUS ...
@ NUMBER ...
@ RPAR ...
@ NEWLINE ...
@ DEDENT ...
@ DEDENT ...
@ ENDMARKER ...
from parse import parse_string, PyTreeVisitor
code = """\
# toplevel comments
def f(x:int) -> int:
# condition, (inner comments)
if x == 0:
return 1
else:
return x * f(x - 1)
"""
t = parse_string(code)
visitor = PyTreeVisitor()
visitor.visit(t)
diff --git a/daily/20190706/example_debug_recursive/parse.py b/daily/20190706/example_debug_recursive/parse.py
index d80d55f..82ad566 100644
--- a/daily/20190706/example_debug_recursive/parse.py
+++ b/daily/20190706/example_debug_recursive/parse.py
@@ -29,6 +29,14 @@ def node_value(node):
class PyTreeVisitor:
def visit(self, node):
+ import traceback
+
+ print(
+ " " * (len(traceback.extract_stack()) - 2),
+ "@",
+ node_name(node),
+ node_value(node),
+ )
method = "visit_{0}".format(node_name(node))
if hasattr(self, method):
# Found a specific visitor for this node
00:
python 00*.py
from lib2to3 import pytree
from lib2to3 import pygram
from lib2to3.pgen2 import driver
from lib2to3.pgen2 import token
default_driver = driver.Driver(
pygram.python_grammar_no_print_statement, convert=pytree.convert
)
def parse_string(code, parser_driver=default_driver, *, debug=True):
return parser_driver.parse_string(code, debug=debug)
def node_name(node):
# Nodes with values < 256 are tokens. Values >= 256 are grammar symbols.
if node.type < 256:
return token.tok_name[node.type]
else:
return pygram.python_grammar.number2symbol[node.type]
def node_value(node):
if node_name(node) == "NAME":
return repr(node)
else:
return "..."
class PyTreeVisitor:
def visit(self, node):
import traceback
print(
" " * (len(traceback.extract_stack()) - 2),
"@",
node_name(node),
node_value(node),
)
method = "visit_{0}".format(node_name(node))
if hasattr(self, method):
# Found a specific visitor for this node
if getattr(self, method)(node):
return
elif hasattr(node, "value"): # Leaf
self.default_leaf_visit(node)
else:
self.default_node_visit(node)
def default_node_visit(self, node):
for child in node.children:
self.visit(child)
def default_leaf_visit(self, leaf):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment