Repository: lark-parser/lark

Issue:
Syntactic sugar: Tree.find_token()
**Suggestion**
Add new method `Tree.find_type(typ: str) -> Iterator[Token]` as a companion for `Tree.find_data()`:
```python
for term in tree.find_type('TERM'):
    ...
```

**Describe alternatives you've considered**
Right now this can be achieved by
```python
for term in tree.find_pred(lambda node: isinstance(node, Token) and node.type == 'TERM'):
    ...
```
which doesn't fit Black's line width and will look even uglier in real cases.

**Additional context**
I can provide PR if you find this enhancement reasonable.

The method proposed seems to be a logical extension of existing API:
```
Tree => find_data()
Token => find_type()
```

Discussion:

Patch:
diff --git a/.gitignore b/.gitignore
index 26275e4..d4e6418 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 *.pyc
 *.pyo
 /.tox
+/lark.egg-info/**
 /lark_parser.egg-info/**
 tags
 .vscode
diff --git a/lark/tree.py b/lark/tree.py
index 76f8738..9dccadd 100644
--- a/lark/tree.py
+++ b/lark/tree.py
@@ -3,8 +3,10 @@ from copy import deepcopy
 
 from typing import List, Callable, Iterator, Union, Optional, Generic, TypeVar, TYPE_CHECKING
 
+from .lexer import Token
+
 if TYPE_CHECKING:
-    from .lexer import TerminalDef, Token
+    from .lexer import TerminalDef
     try:
         import rich
     except ImportError:
@@ -171,6 +173,16 @@ class Tree(Generic[_Leaf_T]):
 
 ###}
 
+    def find_token(self, token_type: str) -> Iterator[_Leaf_T]:
+        """Returns all tokens whose type equals the given token_type.
+
+        This is a recursive function that will find tokens in all the subtrees.
+
+        Example:
+            >>> term_tokens = tree.find_token('TERM')
+        """
+        return self.scan_values(lambda v: isinstance(v, Token) and v.type == token_type)
+
     def expand_kids_by_data(self, *data_values):
         """Expand (inline) children with any of the given data values. Returns True if anything changed"""
         changed = False


Test patch:
diff --git a/tests/test_trees.py b/tests/test_trees.py
index 1f69869..55fdae9 100644
--- a/tests/test_trees.py
+++ b/tests/test_trees.py
@@ -17,6 +17,11 @@ from lark.visitors import Visitor, Visitor_Recursive, Transformer, Interpreter,
 class TestTrees(TestCase):
     def setUp(self):
         self.tree1 = Tree('a', [Tree(x, y) for x, y in zip('bcd', 'xyz')])
+        self.tree2 = Tree('a', [
+            Tree('b', [Token('T', 'x')]),
+            Tree('c', [Token('T', 'y')]),
+            Tree('d', [Tree('z', [Token('T', 'zz'), Tree('zzz', 'zzz')])]),
+        ])
 
     def test_eq(self):
         assert self.tree1 == self.tree1
@@ -48,6 +53,11 @@ class TestTrees(TestCase):
         nodes = list(self.tree1.iter_subtrees_topdown())
         self.assertEqual(nodes, expected)
 
+    def test_find_token(self):
+        expected = [Token('T', 'x'), Token('T', 'y'), Token('T', 'zz')]
+        tokens = list(self.tree2.find_token('T'))
+        self.assertEqual(tokens, expected)
+
     def test_visitor(self):
         class Visitor1(Visitor):
             def __init__(self):