From d77f93c818e98da03d11d7ef5e40de78f3639a91 Mon Sep 17 00:00:00 2001 From: Erez Shinan Date: Sat, 10 Mar 2018 12:01:08 +0200 Subject: [PATCH] Standalone generator working again. Updated examples --- examples/standalone/json_parser.py | 325 ++++++++++++++--------------- lark/parse_tree_builder.py | 4 +- 2 files changed, 157 insertions(+), 172 deletions(-) diff --git a/examples/standalone/json_parser.py b/examples/standalone/json_parser.py index f249f61..8c51baf 100644 --- a/examples/standalone/json_parser.py +++ b/examples/standalone/json_parser.py @@ -1,4 +1,4 @@ -# The file was automatically generated by Lark v0.5.2 +# The file was automatically generated by Lark v0.5.5 # # # Lark Stand-alone Generator Tool @@ -92,11 +92,12 @@ class ParseError(Exception): pass class UnexpectedToken(ParseError): - def __init__(self, token, expected, seq, index): + def __init__(self, token, expected, seq, index, considered_rules=None): self.token = token self.expected = expected self.line = getattr(token, 'line', '?') self.column = getattr(token, 'column', '?') + self.considered_rules = considered_rules try: context = ' '.join(['%r(%s)' % (t.value, t.type) for t in seq[index:index+5]]) @@ -115,7 +116,7 @@ class UnexpectedToken(ParseError): class Tree(object): def __init__(self, data, children): self.data = data - self.children = list(children) + self.children = children def __repr__(self): return 'Tree(%s, %s)' % (self.data, self.children) @@ -125,14 +126,14 @@ class Tree(object): def _pretty(self, level, indent_str): if len(self.children) == 1 and not isinstance(self.children[0], Tree): - return [ indent_str*level, self._pretty_label(), '\t', '%s' % self.children[0], '\n'] + return [ indent_str*level, self._pretty_label(), '\t', '%s' % (self.children[0],), '\n'] l = [ indent_str*level, self._pretty_label(), '\n' ] for n in self.children: if isinstance(n, Tree): l += n._pretty(level+1, indent_str) else: - l += [ indent_str*(level+1), '%s' % n, '\n' ] + l += [ indent_str*(level+1), '%s' % (n,), '\n' ] return l @@ -289,9 +290,11 @@ class LexError(Exception): pass class UnexpectedInput(LexError): - def __init__(self, seq, lex_pos, line, column, allowed=None): + def __init__(self, seq, lex_pos, line, column, allowed=None, considered_rules=None): context = seq[lex_pos:lex_pos+5] message = "No token defined for: '%s' in %r at line %d col %d" % (seq[lex_pos], context, line, column) + if allowed: + message += '\n\nExpecting: %s\n' % allowed super(UnexpectedInput, self).__init__(message) @@ -299,6 +302,7 @@ class UnexpectedInput(LexError): self.column = column self.context = context self.allowed = allowed + self.considered_rules = considered_rules class Token(Str): def __new__(cls, type_, value, pos_in_stream=None, line=None, column=None): @@ -358,9 +362,10 @@ class _Lex: def lex(self, stream, newline_types, ignore_types): newline_types = list(newline_types) - newline_types = list(newline_types) + ignore_types = list(ignore_types) line_ctr = LineCounter() + t = None while True: lexer = self.lexer for mre, type_from_index in lexer.mres: @@ -372,9 +377,16 @@ 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) - lexer = yield t + yield t + else: + if type_ in lexer.callback: + t = Token(type_, value, line_ctr.char_pos, line_ctr.line, line_ctr.column) + lexer.callback[type_](t) line_ctr.feed(value, type_ in newline_types) + if t: + t.end_line = line_ctr.line + t.end_column = line_ctr.column break else: if line_ctr.char_pos < len(stream): @@ -396,15 +408,9 @@ class UnlessCallback: -class NodeBuilder: - def __init__(self, tree_class, name): - self.tree_class = tree_class - self.name = name - - def __call__(self, children): - return self.tree_class(self.name, children) +from functools import partial -class Expand1: +class ExpandSingleChild: def __init__(self, node_builder): self.node_builder = node_builder @@ -414,57 +420,17 @@ class Expand1: else: return self.node_builder(children) -class Factory: - def __init__(self, cls, *args): - self.cls = cls - self.args = args - - def __call__(self, node_builder): - return self.cls(node_builder, *self.args) - -class TokenWrapper: +class CreateToken: "Used for fixing the results of scanless parsing" - def __init__(self, node_builder, token_name): + def __init__(self, token_name, node_builder): self.node_builder = node_builder self.token_name = token_name def __call__(self, children): return self.node_builder( [Token(self.token_name, ''.join(children))] ) -def identity(node_builder): - return node_builder - - -class ChildFilter: - def __init__(self, node_builder, to_include): - self.node_builder = node_builder - self.to_include = to_include - - def __call__(self, children): - filtered = [] - for i, to_expand in self.to_include: - if to_expand: - filtered += children[i].children - else: - filtered.append(children[i]) - - return self.node_builder(filtered) - -def create_rule_handler(expansion, keep_all_tokens, filter_out): - # if not keep_all_tokens: - to_include = [(i, not is_terminal(sym) and sym.startswith('_')) - for i, sym in enumerate(expansion) - if keep_all_tokens - or not ((is_terminal(sym) and sym.startswith('_')) or sym in filter_out) - ] - - if len(to_include) < len(expansion) or any(to_expand for i, to_expand in to_include): - return Factory(ChildFilter, to_include) - - # else, if no filtering required.. - return identity class PropagatePositions: def __init__(self, node_builder): @@ -483,12 +449,40 @@ class PropagatePositions: for a in reversed(children): with suppress(AttributeError): res.end_line = a.end_line - res.end_col = a.end_col + res.end_column = a.end_column break return res +class ChildFilter: + def __init__(self, to_include, node_builder): + self.node_builder = node_builder + self.to_include = to_include + + def __call__(self, children): + filtered = [] + for i, to_expand in self.to_include: + if to_expand: + if filtered: + filtered += children[i].children + else: # Optimize for left-recursion + filtered = children[i].children + else: + filtered.append(children[i]) + + return self.node_builder(filtered) + +def _should_expand(sym): + return not is_terminal(sym) and sym.startswith('_') + +def maybe_create_child_filter(expansion, filter_out): + to_include = [(i, _should_expand(sym)) for i, sym in enumerate(expansion) if sym not in filter_out] + + if len(to_include) < len(expansion) or any(to_expand for i, to_expand in to_include): + return partial(ChildFilter, to_include) + + class Callback(object): pass @@ -503,22 +497,20 @@ class ParseTreeBuilder: self.user_aliases = {} def _init_builders(self, rules): - filter_out = set() - for rule in rules: - if rule.options and rule.options.filter_out: - assert rule.origin.startswith('_') # Just to make sure - filter_out.add(rule.origin) + filter_out = {rule.origin for rule in rules if rule.options and rule.options.filter_out} + filter_out |= {sym for rule in rules for sym in rule.expansion if is_terminal(sym) and sym.startswith('_')} + assert all(x.startswith('_') for x in filter_out) for rule in rules: options = rule.options keep_all_tokens = self.always_keep_all_tokens or (options.keep_all_tokens if options else False) - expand1 = options.expand1 if options else False + expand_single_child = options.expand1 if options else False create_token = options.create_token if options else False wrapper_chain = filter(None, [ - (expand1 and not rule.alias) and Expand1, - create_token and Factory(TokenWrapper, create_token), - create_rule_handler(rule.expansion, keep_all_tokens, filter_out), + create_token and partial(CreateToken, create_token), + (expand_single_child and not rule.alias) and ExpandSingleChild, + maybe_create_child_filter(rule.expansion, () if keep_all_tokens else filter_out), self.propagate_positions and PropagatePositions, ]) @@ -535,7 +527,7 @@ class ParseTreeBuilder: try: f = transformer._get_func(user_callback_name) except AttributeError: - f = NodeBuilder(self.tree_class, user_callback_name) + f = partial(self.tree_class, user_callback_name) self.user_aliases[rule] = rule.alias rule.alias = internal_callback_name @@ -595,9 +587,7 @@ class _Parser: value_stack.append(value) # Main LALR-parser loop - try: - token = next(stream) - i += 1 + for i, token in enumerate(stream): while True: action, arg = get_action(token.type) assert arg != self.end_state @@ -606,12 +596,9 @@ class _Parser: state_stack.append(arg) value_stack.append(token) if set_state: set_state(arg) - token = next(stream) - i += 1 + break # next token else: reduce(arg) - except StopIteration: - pass while True: _action, arg = get_action('$END') @@ -665,27 +652,25 @@ Shift = 0 Reduce = 1 import re MRES = ( -[('(?P(?:(?:\\+|\\-))?(?:(?:(?:[0-9])+(?:e|E)(?:(?:\\+|\\-))?(?:[0-9])+|(?:(?:[0-9])+\\.(?:(?:[0-9])+)?|\\.(?:[0-9])+)(?:(?:e|E)(?:(?:\\+|\\-))?(?:[0-9])+)?)|(?:[0-9])+))|(?P\\"(?:(?:\\\\\\"|[^"]))*\\")|(?P(?:[ \t\x0c' - '\r\n' - '])+)|(?P<__FALSE1>false)|(?P<__NULL2>null)|(?P<__TRUE0>true)|(?P<__COLON>\\:)|(?P<__COMMA>\\,)|(?P<__LBRACE>\\{)|(?P<__LSQB>\\[)|(?P<__RBRACE>\\})|(?P<__RSQB>\\])', - {1: 'SIGNED_NUMBER', - 2: 'ESCAPED_STRING', - 3: 'WS', - 4: '__FALSE1', - 5: '__NULL2', - 6: '__TRUE0', - 7: '__COLON', - 8: '__COMMA', - 9: '__LBRACE', - 10: '__LSQB', - 11: '__RBRACE', - 12: '__RSQB'})] +[(u'(?P(?:(?:\\+|\\-))?(?:(?:(?:[0-9])+(?:e|E)(?:(?:\\+|\\-))?(?:[0-9])+|(?:(?:[0-9])+\\.(?:(?:[0-9])+)?|\\.(?:[0-9])+)(?:(?:e|E)(?:(?:\\+|\\-))?(?:[0-9])+)?)|(?:[0-9])+))|(?P\\"(?:(?:\\\\\\"|[^"]))*\\")|(?P(?:[ \t\x0c\r\n])+)|(?P<__FALSE1>false)|(?P<__NULL2>null)|(?P<__TRUE0>true)|(?P<__COLON>\\:)|(?P<__COMMA>\\,)|(?P<__LBRACE>\\{)|(?P<__LSQB>\\[)|(?P<__RBRACE>\\})|(?P<__RSQB>\\])', + {1: u'SIGNED_NUMBER', + 2: u'ESCAPED_STRING', + 3: u'WS', + 4: u'__FALSE1', + 5: u'__NULL2', + 6: u'__TRUE0', + 7: u'__COLON', + 8: u'__COMMA', + 9: u'__LBRACE', + 10: u'__LSQB', + 11: u'__RBRACE', + 12: u'__RSQB'})] ) LEXER_CALLBACK = ( {} ) -NEWLINE_TYPES = ['WS'] -IGNORE_TYPES = ['WS'] +NEWLINE_TYPES = [u'WS'] +IGNORE_TYPES = [u'WS'] class LexerRegexps: pass lexer_regexps = LexerRegexps() lexer_regexps.mres = [(re.compile(p), d) for p, d in MRES] @@ -695,93 +680,93 @@ lexer = _Lex(lexer_regexps) def lex(stream): return lexer.lex(stream, NEWLINE_TYPES, IGNORE_TYPES) RULES = { - 0: Rule('start', ['value'], None, RuleOptions(False, True, None, None, False)), - 1: Rule('value', ['object'], None, RuleOptions(False, True, None, None, False)), - 2: Rule('value', ['array'], None, RuleOptions(False, True, None, None, False)), - 3: Rule('value', ['string'], None, RuleOptions(False, True, None, None, False)), - 4: Rule('value', ['SIGNED_NUMBER'], 'number', RuleOptions(False, True, None, None, False)), - 5: Rule('value', ['__TRUE0'], 'true', RuleOptions(False, True, None, None, False)), - 6: Rule('value', ['__FALSE1'], 'false', RuleOptions(False, True, None, None, False)), - 7: Rule('value', ['__NULL2'], 'null', RuleOptions(False, True, None, None, False)), - 8: Rule('array', ['__LSQB', 'value', '__anon_star_0', '__RSQB'], None, RuleOptions(False, False, None, None, False)), - 9: Rule('array', ['__LSQB', 'value', '__RSQB'], None, RuleOptions(False, False, None, None, False)), - 10: Rule('array', ['__LSQB', '__RSQB'], None, RuleOptions(False, False, None, None, False)), - 11: Rule('object', ['__LBRACE', 'pair', '__anon_star_1', '__RBRACE'], None, RuleOptions(False, False, None, None, False)), - 12: Rule('object', ['__LBRACE', 'pair', '__RBRACE'], None, RuleOptions(False, False, None, None, False)), - 13: Rule('object', ['__LBRACE', '__RBRACE'], None, RuleOptions(False, False, None, None, False)), - 14: Rule('pair', ['string', '__COLON', 'value'], None, RuleOptions(False, False, None, None, False)), - 15: Rule('string', ['ESCAPED_STRING'], None, RuleOptions(False, False, None, None, False)), - 16: Rule('__anon_star_0', ['__COMMA', 'value'], None, None), - 17: Rule('__anon_star_0', ['__anon_star_0', '__COMMA', 'value'], None, None), - 18: Rule('__anon_star_1', ['__COMMA', 'pair'], None, None), - 19: Rule('__anon_star_1', ['__anon_star_1', '__COMMA', 'pair'], None, None), + 0: Rule(u'start', [u'value'], None, RuleOptions(False, True, None, None, False)), + 1: Rule(u'value', [u'string'], None, RuleOptions(False, True, None, None, False)), + 2: Rule(u'value', [u'__TRUE0'], u'true', RuleOptions(False, True, None, None, False)), + 3: Rule(u'value', [u'array'], None, RuleOptions(False, True, None, None, False)), + 4: Rule(u'value', [u'__NULL2'], u'null', RuleOptions(False, True, None, None, False)), + 5: Rule(u'value', [u'SIGNED_NUMBER'], u'number', RuleOptions(False, True, None, None, False)), + 6: Rule(u'value', [u'object'], None, RuleOptions(False, True, None, None, False)), + 7: Rule(u'value', [u'__FALSE1'], u'false', RuleOptions(False, True, None, None, False)), + 8: Rule(u'array', ['__LSQB', u'value', '__RSQB'], None, RuleOptions(False, False, None, None, False)), + 9: Rule(u'array', ['__LSQB', u'value', '__anon_star_0', '__RSQB'], None, RuleOptions(False, False, None, None, False)), + 10: Rule(u'array', ['__LSQB', '__RSQB'], None, RuleOptions(False, False, None, None, False)), + 11: Rule(u'object', ['__LBRACE', u'pair', '__anon_star_1', '__RBRACE'], None, RuleOptions(False, False, None, None, False)), + 12: Rule(u'object', ['__LBRACE', '__RBRACE'], None, RuleOptions(False, False, None, None, False)), + 13: Rule(u'object', ['__LBRACE', u'pair', '__RBRACE'], None, RuleOptions(False, False, None, None, False)), + 14: Rule(u'pair', [u'string', '__COLON', u'value'], None, RuleOptions(False, False, None, None, False)), + 15: Rule(u'string', [u'ESCAPED_STRING'], None, RuleOptions(False, False, None, None, False)), + 16: Rule('__anon_star_0', ['__anon_star_0', '__COMMA', u'value'], None, None), + 17: Rule('__anon_star_0', ['__COMMA', u'value'], None, None), + 18: Rule('__anon_star_1', ['__COMMA', u'pair'], None, None), + 19: Rule('__anon_star_1', ['__anon_star_1', '__COMMA', u'pair'], None, None), } parse_tree_builder = ParseTreeBuilder(RULES.values(), Tree) class ParseTable: pass parse_table = ParseTable() STATES = { - 0: {0: (0, 1), 1: (0, 2), 2: (0, 3), 3: (0, 4), 4: (0, 5), 5: (0, 6), 6: (0, 7), 7: (0, 8), 8: (0, 9), 9: (0, 10), 10: (0, 11), 11: (0, 12)}, - 1: {12: (1, 5), 13: (1, 5), 14: (1, 5), 15: (1, 5)}, - 2: {9: (0, 10), 14: (0, 13), 16: (0, 14), 11: (0, 15)}, - 3: {12: (1, 2), 13: (1, 2), 14: (1, 2), 15: (1, 2)}, - 4: {12: (1, 1), 13: (1, 1), 14: (1, 1), 15: (1, 1)}, - 5: {12: (0, 16)}, - 6: {7: (0, 17), 0: (0, 1), 1: (0, 2), 2: (0, 3), 3: (0, 4), 5: (0, 6), 6: (0, 7), 8: (0, 9), 9: (0, 10), 15: (0, 18), 10: (0, 11), 11: (0, 12)}, - 7: {12: (1, 4), 13: (1, 4), 14: (1, 4), 15: (1, 4)}, - 8: {12: (1, 0)}, - 9: {12: (1, 7), 13: (1, 7), 14: (1, 7), 15: (1, 7)}, - 10: {12: (1, 15), 17: (1, 15), 13: (1, 15), 14: (1, 15), 15: (1, 15)}, - 11: {12: (1, 6), 13: (1, 6), 14: (1, 6), 15: (1, 6)}, - 12: {12: (1, 3), 13: (1, 3), 14: (1, 3), 15: (1, 3)}, - 13: {13: (1, 13), 12: (1, 13), 14: (1, 13), 15: (1, 13)}, - 14: {14: (0, 19), 13: (0, 20), 18: (0, 21)}, - 15: {17: (0, 22)}, - 16: {}, - 17: {19: (0, 23), 15: (0, 24), 13: (0, 25)}, - 18: {13: (1, 10), 12: (1, 10), 14: (1, 10), 15: (1, 10)}, - 19: {13: (1, 12), 12: (1, 12), 14: (1, 12), 15: (1, 12)}, - 20: {9: (0, 10), 11: (0, 15), 16: (0, 26)}, - 21: {14: (0, 27), 13: (0, 28)}, - 22: {5: (0, 6), 1: (0, 2), 0: (0, 1), 8: (0, 9), 2: (0, 3), 3: (0, 4), 9: (0, 10), 6: (0, 7), 10: (0, 11), 11: (0, 12), 7: (0, 29)}, - 23: {15: (0, 30), 13: (0, 31)}, - 24: {13: (1, 9), 12: (1, 9), 14: (1, 9), 15: (1, 9)}, - 25: {5: (0, 6), 1: (0, 2), 0: (0, 1), 8: (0, 9), 2: (0, 3), 3: (0, 4), 7: (0, 32), 9: (0, 10), 6: (0, 7), 10: (0, 11), 11: (0, 12)}, - 26: {13: (1, 18), 14: (1, 18)}, - 27: {13: (1, 11), 12: (1, 11), 14: (1, 11), 15: (1, 11)}, - 28: {16: (0, 33), 9: (0, 10), 11: (0, 15)}, - 29: {13: (1, 14), 14: (1, 14)}, - 30: {13: (1, 8), 12: (1, 8), 14: (1, 8), 15: (1, 8)}, - 31: {5: (0, 6), 1: (0, 2), 0: (0, 1), 7: (0, 34), 8: (0, 9), 2: (0, 3), 3: (0, 4), 9: (0, 10), 6: (0, 7), 10: (0, 11), 11: (0, 12)}, - 32: {15: (1, 16), 13: (1, 16)}, - 33: {13: (1, 19), 14: (1, 19)}, - 34: {15: (1, 17), 13: (1, 17)}, + 0: {0: (1, 4), 1: (1, 4), 2: (1, 4), 3: (1, 4)}, + 1: {1: (1, 14), 2: (1, 14)}, + 2: {0: (0, 29), 1: (0, 32), 4: (0, 9)}, + 3: {1: (0, 13), 2: (0, 12)}, + 4: {0: (1, 1), 1: (1, 1), 2: (1, 1), 3: (1, 1)}, + 5: {0: (1, 10), 1: (1, 10), 2: (1, 10), 3: (1, 10)}, + 6: {2: (0, 15), 5: (0, 27), 6: (0, 16), 7: (0, 26)}, + 7: {5: (0, 34), 6: (0, 16), 7: (0, 26)}, + 8: {0: (1, 2), 1: (1, 2), 2: (1, 2), 3: (1, 2)}, + 9: {0: (0, 11), 1: (0, 22)}, + 10: {0: (1, 6), 1: (1, 6), 2: (1, 6), 3: (1, 6)}, + 11: {0: (1, 9), 1: (1, 9), 2: (1, 9), 3: (1, 9)}, + 12: {0: (1, 11), 1: (1, 11), 2: (1, 11), 3: (1, 11)}, + 13: {5: (0, 20), 6: (0, 16), 7: (0, 26)}, + 14: {6: (0, 16), 7: (0, 4), 8: (0, 6), 9: (0, 31), 10: (0, 24), 11: (0, 10), 12: (0, 21), 13: (0, 17), 14: (0, 33), 15: (0, 0), 16: (0, 19), 17: (0, 8)}, + 15: {0: (1, 12), 1: (1, 12), 2: (1, 12), 3: (1, 12)}, + 16: {0: (1, 15), 1: (1, 15), 2: (1, 15), 3: (1, 15), 18: (1, 15)}, + 17: {3: (1, 0)}, + 18: {}, + 19: {0: (1, 3), 1: (1, 3), 2: (1, 3), 3: (1, 3)}, + 20: {1: (1, 19), 2: (1, 19)}, + 21: {0: (1, 5), 1: (1, 5), 2: (1, 5), 3: (1, 5)}, + 22: {6: (0, 16), 7: (0, 4), 8: (0, 6), 9: (0, 31), 10: (0, 24), 11: (0, 10), 12: (0, 21), 13: (0, 30), 15: (0, 0), 16: (0, 19), 17: (0, 8)}, + 23: {6: (0, 16), 7: (0, 4), 8: (0, 6), 9: (0, 31), 10: (0, 24), 11: (0, 10), 12: (0, 21), 13: (0, 1), 15: (0, 0), 16: (0, 19), 17: (0, 8)}, + 24: {0: (0, 5), 6: (0, 16), 7: (0, 4), 8: (0, 6), 9: (0, 31), 10: (0, 24), 11: (0, 10), 12: (0, 21), 13: (0, 2), 15: (0, 0), 16: (0, 19), 17: (0, 8)}, + 25: {0: (1, 13), 1: (1, 13), 2: (1, 13), 3: (1, 13)}, + 26: {18: (0, 23)}, + 27: {1: (0, 7), 2: (0, 25), 19: (0, 3)}, + 28: {0: (1, 17), 1: (1, 17)}, + 29: {0: (1, 8), 1: (1, 8), 2: (1, 8), 3: (1, 8)}, + 30: {0: (1, 16), 1: (1, 16)}, + 31: {0: (1, 7), 1: (1, 7), 2: (1, 7), 3: (1, 7)}, + 32: {6: (0, 16), 7: (0, 4), 8: (0, 6), 9: (0, 31), 10: (0, 24), 11: (0, 10), 12: (0, 21), 13: (0, 28), 15: (0, 0), 16: (0, 19), 17: (0, 8)}, + 33: {3: (0, 18)}, + 34: {1: (1, 18), 2: (1, 18)}, } TOKEN_TYPES = ( -{0: '__TRUE0', - 1: '__LBRACE', - 2: 'array', - 3: 'object', - 4: 'start', - 5: '__LSQB', - 6: 'SIGNED_NUMBER', - 7: 'value', - 8: '__NULL2', - 9: 'ESCAPED_STRING', - 10: '__FALSE1', - 11: 'string', - 12: '$END', - 13: '__COMMA', - 14: '__RBRACE', - 15: '__RSQB', - 16: 'pair', - 17: '__COLON', - 18: '__anon_star_1', - 19: '__anon_star_0'} +{0: '__RSQB', + 1: '__COMMA', + 2: '__RBRACE', + 3: '$END', + 4: '__anon_star_0', + 5: u'pair', + 6: u'ESCAPED_STRING', + 7: u'string', + 8: '__LBRACE', + 9: u'__FALSE1', + 10: '__LSQB', + 11: u'object', + 12: u'SIGNED_NUMBER', + 13: u'value', + 14: 'start', + 15: u'__NULL2', + 16: u'array', + 17: u'__TRUE0', + 18: '__COLON', + 19: '__anon_star_1'} ) parse_table.states = {s: {TOKEN_TYPES[t]: (a, RULES[x] if a is Reduce else x) for t, (a, x) in acts.items()} for s, acts in STATES.items()} -parse_table.start_state = 0 -parse_table.end_state = 16 +parse_table.start_state = 14 +parse_table.end_state = 18 class Lark_StandAlone: def __init__(self, transformer=None, postlex=None): callback = parse_tree_builder.create_callback(transformer=transformer) diff --git a/lark/parse_tree_builder.py b/lark/parse_tree_builder.py index c56483b..e84b01d 100644 --- a/lark/parse_tree_builder.py +++ b/lark/parse_tree_builder.py @@ -1,11 +1,11 @@ -from functools import partial - from .common import is_terminal, GrammarError from .utils import suppress from .lexer import Token from .grammar import Rule ###{standalone +from functools import partial + class ExpandSingleChild: def __init__(self, node_builder):