File: walker_test.py

package info (click to toggle)
python-tatsu 5.17.1%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,516 kB
  • sloc: python: 13,185; makefile: 127
file content (81 lines) | stat: -rw-r--r-- 2,274 bytes parent folder | download
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
69
70
71
72
73
74
75
76
77
78
79
80
81
# Copyright (c) 2017-2026 Juancarlo AƱez (apalala@gmail.com)
# SPDX-License-Identifier: BSD-4-Clause
from __future__ import annotations

from collections import defaultdict

import tatsu
from tatsu.util import asjsons
from tatsu.walkers import BreadthFirstWalker, 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) =  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(asjsons(model))
    PW().walk(model)
    assert dict(seen) == {'SampleExpression': 2, 'TemporalSeq': 1, 'Number': 2}

    walker = BreadthFirstWalker()
    result = tuple(type(n).__name__ for n in walker.walk(model))
    assert result == (
        'TemporalSeq',
        'SampleExpression',
        'SampleExpression',
        'Number',
        'Number',
    )

    walker = DepthFirstWalker()
    result = tuple(type(n).__name__ for n in walker.walk(model))
    assert result == (
        'TemporalSeq',
        'SampleExpression',
        'Number',
        'SampleExpression',
        'Number',
    )


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)