|
|
@@ -235,6 +235,7 @@ class Lark(Serialize): |
|
|
|
grammar = read() |
|
|
|
|
|
|
|
cache_fn = None |
|
|
|
cache_md5 = None |
|
|
|
if isinstance(grammar, STRING_TYPE): |
|
|
|
self.source_grammar = grammar |
|
|
|
if self.options.use_bytes: |
|
|
@@ -243,33 +244,37 @@ class Lark(Serialize): |
|
|
|
if sys.version_info[0] == 2 and self.options.use_bytes != 'force': |
|
|
|
raise ConfigurationError("`use_bytes=True` may have issues on python2." |
|
|
|
"Use `use_bytes='force'` to use it at your own risk.") |
|
|
|
|
|
|
|
|
|
|
|
if self.options.cache: |
|
|
|
if self.options.parser != 'lalr': |
|
|
|
raise ConfigurationError("cache only works with parser='lalr' for now") |
|
|
|
|
|
|
|
unhashable = ('transformer', 'postlex', 'lexer_callbacks', 'edit_terminals') |
|
|
|
options_str = ''.join(k+str(v) for k, v in options.items() if k not in unhashable) |
|
|
|
from . import __version__ |
|
|
|
s = grammar + options_str + __version__ |
|
|
|
cache_md5 = hashlib.md5(s.encode()).hexdigest() |
|
|
|
|
|
|
|
if isinstance(self.options.cache, STRING_TYPE): |
|
|
|
cache_fn = self.options.cache |
|
|
|
else: |
|
|
|
if self.options.cache is not True: |
|
|
|
raise ConfigurationError("cache argument must be bool or str") |
|
|
|
unhashable = ('transformer', 'postlex', 'lexer_callbacks', 'edit_terminals') |
|
|
|
from . import __version__ |
|
|
|
options_str = ''.join(k+str(v) for k, v in options.items() if k not in unhashable) |
|
|
|
s = grammar + options_str + __version__ |
|
|
|
md5 = hashlib.md5(s.encode()).hexdigest() |
|
|
|
cache_fn = tempfile.gettempdir() + '/.lark_cache_%s.tmp' % md5 |
|
|
|
|
|
|
|
cache_fn = tempfile.gettempdir() + '/.lark_cache_%s.tmp' % cache_md5 |
|
|
|
|
|
|
|
if FS.exists(cache_fn): |
|
|
|
logger.debug('Loading grammar from cache: %s', cache_fn) |
|
|
|
# Remove options that aren't relevant for loading from cache |
|
|
|
for name in (set(options) - _LOAD_ALLOWED_OPTIONS): |
|
|
|
del options[name] |
|
|
|
with FS.open(cache_fn, 'rb') as f: |
|
|
|
try: |
|
|
|
self._load(f, **options) |
|
|
|
except Exception: |
|
|
|
raise RuntimeError("Failed to load Lark from cache: %r. Try to delete the file and run again." % cache_fn) |
|
|
|
return |
|
|
|
file_md5 = f.readline().rstrip(b'\n') |
|
|
|
if file_md5 == cache_md5.encode(): |
|
|
|
try: |
|
|
|
self._load(f, **options) |
|
|
|
except Exception: |
|
|
|
raise RuntimeError("Failed to load Lark from cache: %r. Try to delete the file and run again." % cache_fn) |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
# Parse the grammar file and compose the grammars |
|
|
@@ -277,7 +282,7 @@ class Lark(Serialize): |
|
|
|
else: |
|
|
|
assert isinstance(grammar, Grammar) |
|
|
|
self.grammar = grammar |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.options.lexer == 'auto': |
|
|
|
if self.options.parser == 'lalr': |
|
|
@@ -353,6 +358,7 @@ class Lark(Serialize): |
|
|
|
if cache_fn: |
|
|
|
logger.debug('Saving grammar to cache: %s', cache_fn) |
|
|
|
with FS.open(cache_fn, 'wb') as f: |
|
|
|
f.write(b'%s\n' % cache_md5.encode()) |
|
|
|
self.save(f) |
|
|
|
|
|
|
|
if __doc__: |
|
|
|