Browse Source

Fix for #818 + tests

tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.11.3
MegaIng1 5 years ago
parent
commit
c621eeb369
3 changed files with 29 additions and 8 deletions
  1. +4
    -5
      lark/lark.py
  2. +1
    -1
      lark/parsers/lalr_parser.py
  3. +24
    -2
      tests/test_parser.py

+ 4
- 5
lark/lark.py View File

@@ -338,9 +338,7 @@ class Lark(Serialize):
rule.options.priority = None rule.options.priority = None


# TODO Deprecate lexer_callbacks? # TODO Deprecate lexer_callbacks?
lexer_callbacks = (_get_lexer_callbacks(self.options.transformer, self.terminals)
if self.options.transformer
else {})
lexer_callbacks = {}
lexer_callbacks.update(self.options.lexer_callbacks) lexer_callbacks.update(self.options.lexer_callbacks)


self.lexer_conf = LexerConf(self.terminals, re_module, self.ignore_tokens, self.options.postlex, lexer_callbacks, self.options.g_regex_flags, use_bytes=self.options.use_bytes) self.lexer_conf = LexerConf(self.terminals, re_module, self.ignore_tokens, self.options.postlex, lexer_callbacks, self.options.g_regex_flags, use_bytes=self.options.use_bytes)
@@ -370,7 +368,7 @@ class Lark(Serialize):


def _prepare_callbacks(self): def _prepare_callbacks(self):
self.parser_class = get_frontend(self.options.parser, self.options.lexer) self.parser_class = get_frontend(self.options.parser, self.options.lexer)
self._callbacks = None
self._callbacks = {}
# we don't need these callbacks if we aren't building a tree # we don't need these callbacks if we aren't building a tree
if self.options.ambiguity != 'forest': if self.options.ambiguity != 'forest':
self._parse_tree_builder = ParseTreeBuilder( self._parse_tree_builder = ParseTreeBuilder(
@@ -380,7 +378,8 @@ class Lark(Serialize):
self.options.parser != 'lalr' and self.options.ambiguity == 'explicit', self.options.parser != 'lalr' and self.options.ambiguity == 'explicit',
self.options.maybe_placeholders self.options.maybe_placeholders
) )
self._callbacks = self._parse_tree_builder.create_callback(self.options.transformer)
self._callbacks.update(self._parse_tree_builder.create_callback(self.options.transformer))
self._callbacks.update(_get_lexer_callbacks(self.options.transformer, self.terminals))


def _build_parser(self): def _build_parser(self):
self._prepare_callbacks() self._prepare_callbacks()


+ 1
- 1
lark/parsers/lalr_parser.py View File

@@ -101,7 +101,7 @@ class ParserState(object):
# shift once and return # shift once and return
assert not is_end assert not is_end
state_stack.append(arg) state_stack.append(arg)
value_stack.append(token)
value_stack.append(token if token.type not in callbacks else callbacks[token.type](token))
return return
else: else:
# reduce+shift as many times as necessary # reduce+shift as many times as necessary


+ 24
- 2
tests/test_parser.py View File

@@ -10,7 +10,7 @@ from copy import copy, deepcopy


from lark.utils import Py36, isascii from lark.utils import Py36, isascii


from lark import Token
from lark import Token, Transformer_NonRecursive


try: try:
from cStringIO import StringIO as cStringIO from cStringIO import StringIO as cStringIO
@@ -34,7 +34,7 @@ from lark import logger
from lark.lark import Lark from lark.lark import Lark
from lark.exceptions import GrammarError, ParseError, UnexpectedToken, UnexpectedInput, UnexpectedCharacters from lark.exceptions import GrammarError, ParseError, UnexpectedToken, UnexpectedInput, UnexpectedCharacters
from lark.tree import Tree from lark.tree import Tree
from lark.visitors import Transformer, Transformer_InPlace, v_args
from lark.visitors import Transformer, Transformer_InPlace, v_args, Transformer_InPlaceRecursive
from lark.grammar import Rule from lark.grammar import Rule
from lark.lexer import TerminalDef, Lexer, TraditionalLexer from lark.lexer import TerminalDef, Lexer, TraditionalLexer
from lark.indenter import Indenter from lark.indenter import Indenter
@@ -162,6 +162,28 @@ class TestParsers(unittest.TestCase):
r = p.parse("x") r = p.parse("x")
self.assertEqual( r.children, ["X!"] ) self.assertEqual( r.children, ["X!"] )


def test_visit_tokens2(self):
g = """
start: add+
add: NUM "+" NUM
NUM: /\d+/
%ignore " "
"""
text = "1+2 3+4"
expected = Tree('start', [3, 7])
for base in (Transformer, Transformer_InPlace, Transformer_NonRecursive, Transformer_InPlaceRecursive):
class T(base):
def add(self, children):
return sum(children)
def NUM(self, token):
return int(token)
parser = Lark(g, parser='lalr', transformer=T())
result = parser.parse(text)
self.assertEqual(result, expected)

def test_vargs_meta(self): def test_vargs_meta(self):


@v_args(meta=True) @v_args(meta=True)


Loading…
Cancel
Save