diff --git a/lark/parsers/lalr_parser.py b/lark/parsers/lalr_parser.py index bd519d1..07b3a0c 100644 --- a/lark/parsers/lalr_parser.py +++ b/lark/parsers/lalr_parser.py @@ -7,31 +7,41 @@ from ..common import ParseError, UnexpectedToken from .lalr_analysis import LALR_Analyzer, ACTION_SHIFT -class Parser(object): +class Parser: def __init__(self, parser_conf): assert all(o is None or o.priority is None for n,x,a,o in parser_conf.rules), "LALR doesn't yet support prioritization" - self.analysis = LALR_Analyzer(parser_conf.rules, parser_conf.start) - self.analysis.compute_lookahead() - self.callbacks = {rule: getattr(parser_conf.callback, rule.alias or rule.origin, None) - for rule in self.analysis.rules} + self.analysis = analysis = LALR_Analyzer(parser_conf.rules, parser_conf.start) + analysis.compute_lookahead() + callbacks = {rule: getattr(parser_conf.callback, rule.alias or rule.origin, None) + for rule in analysis.rules} + + self.parser = _Parser(analysis.states_idx, analysis.init_state_idx, analysis.start_symbol, callbacks) + self.parse = self.parser.parse + +class _Parser: + def __init__(self, states, init_state, start_symbol, callbacks): + self.states = states + self.init_state = init_state + self.start_symbol = start_symbol + self.callbacks = callbacks def parse(self, seq, set_state=None): i = 0 token = None stream = iter(seq) - states_idx = self.analysis.states_idx + states = self.states - state_stack = [self.analysis.init_state_idx] + state_stack = [self.init_state] value_stack = [] - if set_state: set_state(self.analysis.init_state_idx) + if set_state: set_state(self.init_state) def get_action(key): state = state_stack[-1] try: - return states_idx[state][key] + return states[state][key] except KeyError: - expected = states_idx[state].keys() + expected = states[state].keys() raise UnexpectedToken(token, expected, seq, i) @@ -45,7 +55,7 @@ class Parser(object): res = self.callbacks[rule](s) - if end and len(state_stack) == 1 and rule.origin == self.analysis.start_symbol: + if end and len(state_stack) == 1 and rule.origin == self.start_symbol: return res _action, new_state = get_action(rule.origin) @@ -76,7 +86,7 @@ class Parser(object): assert _action == 'reduce' res = reduce(*rule, end=True) if res: - assert state_stack == [self.analysis.init_state_idx] and not value_stack, len(state_stack) + assert state_stack == [self.init_state] and not value_stack, len(state_stack) return res