Browse Source

Added support for returning Inline in transformers (Issue #763)

gm/2021-09-23T00Z/github.com--lark-parser-lark/inline
Erez Sh 4 years ago
parent
commit
efc1c82221
3 changed files with 36 additions and 6 deletions
  1. +1
    -1
      lark/__init__.py
  2. +16
    -4
      lark/visitors.py
  3. +19
    -1
      tests/test_trees.py

+ 1
- 1
lark/__init__.py View File

@@ -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)


+ 16
- 4
lark/visitors.py View File

@@ -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"

@@ -113,11 +120,16 @@ class Transformer(_Decoratable):
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



+ 19
- 1
tests/test_trees.py View File

@@ -8,7 +8,7 @@ import functools

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):
@@ -233,6 +233,24 @@ class TestTrees(TestCase):
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()

Loading…
Cancel
Save