Quellcode durchsuchen

Resolved cyclic dependency by moving deserialize_lexer_conf out of MakeParsingFrontend.deserialize

tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.11.3
MegaIng1 vor 3 Jahren
Ursprung
Commit
3d5729d5d2
3 geänderte Dateien mit 21 neuen und 13 gelöschten Zeilen
  1. +9
    -4
      lark/lark.py
  2. +11
    -8
      lark/parser_frontends.py
  3. +1
    -1
      tests/test_parser.py

+ 9
- 4
lark/lark.py Datei anzeigen

@@ -367,7 +367,6 @@ class Lark(Serialize):
return TraditionalLexer(lexer_conf)

def _prepare_callbacks(self):
self.parser_class = get_frontend(self.options.parser, self.options.lexer)
self._callbacks = {}
# we don't need these callbacks if we aren't building a tree
if self.options.ambiguity != 'forest':
@@ -382,6 +381,7 @@ class Lark(Serialize):
self._callbacks.update(_get_lexer_callbacks(self.options.transformer, self.terminals))

def _build_parser(self):
self.parser_class = get_frontend(self.options.parser, self.options.lexer)
self._prepare_callbacks()
parser_conf = ParserConf(self.rules, self._callbacks, self.options.start)
return self.parser_class(self.lexer_conf, parser_conf, options=self.options)
@@ -421,16 +421,21 @@ class Lark(Serialize):
self.options = LarkOptions.deserialize(options, memo)
self.rules = [Rule.deserialize(r, memo) for r in data['rules']]
self.source_path = '<deserialized>'
self.parser_class = get_frontend(self.options.parser, self.options.lexer)
self.lexer_conf = self.parser_class.deserialize_lexer_conf( # We need the terminals list to for _prepare_callbacks
data['parser'],
memo,
self.options)
self.terminals = self.lexer_conf.terminals
self._terminals_dict = {t.name: t for t in self.terminals}
self._prepare_callbacks()
self.parser = self.parser_class.deserialize(
data['parser'],
memo,
self.lexer_conf,
self._callbacks,
self.options, # Not all, but multiple attributes are used
)
self.lexer_conf = self.parser.lexer_conf
self.terminals = self.parser.lexer_conf.terminals
self._terminals_dict = {t.name: t for t in self.terminals}
return self

@classmethod


+ 11
- 8
lark/parser_frontends.py Datei anzeigen

@@ -38,23 +38,26 @@ class MakeParsingFrontend:
parser_conf.parser_type = self.parser_type
lexer_conf.lexer_type = self.lexer_type
return ParsingFrontend(lexer_conf, parser_conf, options)
@classmethod
def deserialize(cls, data, memo, callbacks, options):
lexer_conf = LexerConf.deserialize(data['lexer_conf'], memo)
parser_conf = ParserConf.deserialize(data['parser_conf'], memo)
parser = LALR_Parser.deserialize(data['parser'], memo, callbacks, options.debug)
parser_conf.callbacks = callbacks

def deserialize_lexer_conf(cls, data, memo, options):
# We need lexer_conf earley to have the terminals that we need to produce the callback list for paser_conf
# So we split deserialize into two methods
terminals = [item for item in memo.values() if isinstance(item, TerminalDef)]
lexer_conf = LexerConf.deserialize(data['lexer_conf'], memo)
lexer_conf.callbacks = _get_lexer_callbacks(options.transformer, terminals)
lexer_conf.re_module = regex if options.regex else re
lexer_conf.use_bytes = options.use_bytes
lexer_conf.g_regex_flags = options.g_regex_flags
lexer_conf.skip_validation = True
lexer_conf.postlex = options.postlex
return lexer_conf

@classmethod
def deserialize(cls, data, memo, lexer_conf, callbacks, options):
parser_conf = ParserConf.deserialize(data['parser_conf'], memo)
parser = LALR_Parser.deserialize(data['parser'], memo, callbacks, options.debug)
parser_conf.callbacks = callbacks
return ParsingFrontend(lexer_conf, parser_conf, options, parser=parser)




+ 1
- 1
tests/test_parser.py Datei anzeigen

@@ -174,7 +174,7 @@ class TestParsers(unittest.TestCase):
for base in (Transformer, Transformer_InPlace, Transformer_NonRecursive, Transformer_InPlaceRecursive):
class T(base):
def add(self, children):
return sum(children)
return sum(children if isinstance(children, list) else children.children)
def NUM(self, token):
return int(token)


Laden…
Abbrechen
Speichern