Skip to content

Commit f68e353

Browse files
Support match on tree (#1521)
* add __match_args__ attribute to Tree * unit test case for pattern matching on Tree objects
1 parent 1640da5 commit f68e353

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

lark/tree.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ def meta(self) -> Meta:
7070
def __repr__(self):
7171
return 'Tree(%r, %r)' % (self.data, self.children)
7272

73+
__match_args__ = ("data", "children")
74+
7375
def _pretty_label(self):
7476
return self.data
7577

tests/test_pattern_matching.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from unittest import TestCase, main
22

3-
from lark import Token
3+
from lark import Token, Tree
44

55

66
class TestPatternMatching(TestCase):
@@ -46,6 +46,51 @@ def test_matches_with_bad_token_type(self):
4646
case _:
4747
pass
4848

49+
def test_match_on_tree(self):
50+
tree1 = Tree('a', [Tree(x, y) for x, y in zip('bcd', 'xyz')])
51+
tree2 = Tree('a', [
52+
Tree('b', [Token('T', 'x')]),
53+
Tree('c', [Token('T', 'y')]),
54+
Tree('d', [Tree('z', [Token('T', 'zz'), Tree('zzz', 'zzz')])]),
55+
])
56+
57+
match tree1:
58+
case Tree('X', []):
59+
assert False
60+
case Tree('a', []):
61+
assert False
62+
case Tree(_, 'b'):
63+
assert False
64+
case Tree('X', _):
65+
assert False
66+
tree = Tree('q', [Token('T', 'x')])
67+
match tree:
68+
case Tree('q', [Token('T', 'x')]):
69+
pass
70+
case _:
71+
assert False
72+
tr = Tree('a', [Tree('b', [Token('T', 'a')])])
73+
match tr:
74+
case Tree('a', [Tree('b', [Token('T', 'a')])]):
75+
pass
76+
case _:
77+
assert False
78+
# test nested trees
79+
match tree2:
80+
case Tree('a', [
81+
Tree('b', [Token('T', 'x')]),
82+
Tree('c', [Token('T', 'y')]),
83+
Tree('d', [
84+
Tree('z', [
85+
Token('T', 'zz'),
86+
Tree('zzz', 'zzz')
87+
])
88+
])
89+
]):
90+
pass
91+
case _:
92+
assert False
93+
4994

5095

5196
if __name__ == '__main__':

0 commit comments

Comments
 (0)