Skip to content

Commit

Permalink
Added support for returning Inline in transformers (Issue #763)
Browse files Browse the repository at this point in the history
  • Loading branch information
erezsh committed Nov 17, 2020
1 parent c715426 commit efc1c82
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lark/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .utils import logger
from .tree import Tree
from .visitors import Transformer, Visitor, v_args, Discard, Transformer_NonRecursive
from .visitors import Transformer, Visitor, v_args, Discard, Inline, Transformer_NonRecursive
from .visitors import InlineTransformer, inline_args # XXX Deprecated
from .exceptions import (ParseError, LexError, GrammarError, UnexpectedToken,
UnexpectedInput, UnexpectedCharacters, LarkError)
Expand Down
20 changes: 16 additions & 4 deletions lark/visitors.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@ class Discard(Exception):
"""
pass

# Transformers
class Inline:
"""When returning an Inline instance in a transformer callback,
the node is inlined, and replaced by its children.
"""
def __init__(self, *items):
self.items = items


# Transformers

class _Decoratable:
"Provides support for decorating methods with @v_args"

Expand Down Expand Up @@ -113,11 +120,16 @@ def _transform_children(self, children):
for c in children:
try:
if isinstance(c, Tree):
yield self._transform_tree(c)
res = self._transform_tree(c)
elif self.__visit_tokens__ and isinstance(c, Token):
yield self._call_userfunc_token(c)
res = self._call_userfunc_token(c)
else:
res = c
if type(res) is Inline:
for i in res.items:
yield i
else:
yield c
yield res
except Discard:
pass

Expand Down
20 changes: 19 additions & 1 deletion tests/test_trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from lark.tree import Tree
from lark.lexer import Token
from lark.visitors import Visitor, Visitor_Recursive, Transformer, Interpreter, visit_children_decor, v_args, Discard
from lark.visitors import Visitor, Visitor_Recursive, Transformer, Interpreter, visit_children_decor, v_args, Discard, Inline


class TestTrees(TestCase):
Expand Down Expand Up @@ -233,6 +233,24 @@ def b(cls, args):
x = MyTransformer().transform( t )
self.assertEqual(x, t2)

def test_inline(self):
class MyTransformer(Transformer):
def b(self, children):
return 'b'

def a(self, children):
return Inline('c', 'd')

t = Tree('root', [
Tree('b', []),
Tree('a', []),
Tree('b', []),
])
t2 = Tree('root', ['b', 'c', 'd', 'b'])

x = MyTransformer().transform( t )
self.assertEqual(x, t2)


if __name__ == '__main__':
unittest.main()

0 comments on commit efc1c82

Please sign in to comment.