Browse Source

Bugfix: Callbacks now work for terminals with UnlessCallback (Issue #317)

tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.6.6
Erez Shinan 5 years ago
parent
commit
1b5f734c49
1 changed files with 18 additions and 2 deletions
  1. +18
    -2
      lark/lexer.py

+ 18
- 2
lark/lexer.py View File

@@ -151,6 +151,8 @@ class _Lex:
t = Token(type_, value, line_ctr.char_pos, line_ctr.line, line_ctr.column)
if t.type in lexer.callback:
t = lexer.callback[t.type](t)
if not isinstance(t, Token):
raise ValueError("Callbacks must return a token (returned %r)" % t)
yield t
else:
if type_ in lexer.callback:
@@ -179,6 +181,17 @@ class UnlessCallback:
break
return t

class CallChain:
def __init__(self, callback1, callback2, cond):
self.callback1 = callback1
self.callback2 = callback2
self.cond = cond

def __call__(self, t):
t2 = self.callback1(t)
return self.callback2(t) if self.cond(t2) else t2


###}


@@ -274,8 +287,11 @@ class TraditionalLexer(Lexer):
assert all(self.callback.values())

for type_, f in user_callbacks.items():
assert type_ not in self.callback
self.callback[type_] = f
if type_ in self.callback:
# Already a callback there, probably UnlessCallback
self.callback[type_] = CallChain(self.callback[type_], f, lambda t: t.type == type_)
else:
self.callback[type_] = f

self.terminals = terminals



Loading…
Cancel
Save