1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
import json
from collections import defaultdict
import tatsu
from tatsu.util import asjson
from tatsu.walkers import DepthFirstWalker, NodeWalker
def test_walk_node_ast():
GRAMMAR = r"""
@@grammar::TLA
#
# comment
#
start = expression $;
expression = temporal_expression | nontemporal_top_expression ;
nontemporal_top_expression(SampleExpression) = expr:nontemporal_expression ;
temporal_expression = temporal_atom;
temporal_atom(TemporalSeq) = ['Seq'] '(' @:temporal_arg_list ')';
temporal_arg_list = "," .{@+:expression}+;
nontemporal_expression = number ;
# tokens
number::int = /\d+/;
"""
parser = tatsu.compile(GRAMMAR, asmodel=True)
model = parser.parse('Seq(1,1)')
assert model.ast is not None
seen = defaultdict(int)
class PW(DepthFirstWalker):
def walk_Node(self, node, *args, **kwargs):
t = type(node).__name__
print(f'node {t}')
seen[t] += 1
print(json.dumps(asjson(model), indent=2))
PW().walk(model)
assert seen == {'SampleExpression': 2, 'TemporalSeq': 1}
def test_cache_per_class():
class PW(DepthFirstWalker):
pass
assert isinstance(
NodeWalker._walker_cache, dict,
)
assert isinstance(
DepthFirstWalker._walker_cache, dict,
)
assert isinstance(PW._walker_cache, dict)
assert id(NodeWalker._walker_cache) != id(
DepthFirstWalker._walker_cache,
)
assert id(PW._walker_cache) != id(
DepthFirstWalker._walker_cache,
)
walker = PW()
assert id(walker._walker_cache) == id(
PW._walker_cache,
)
|