| @@ -7,31 +7,41 @@ from ..common import ParseError, UnexpectedToken | |||||
| from .lalr_analysis import LALR_Analyzer, ACTION_SHIFT | from .lalr_analysis import LALR_Analyzer, ACTION_SHIFT | ||||
| class Parser(object): | |||||
| class Parser: | |||||
| def __init__(self, parser_conf): | 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" | 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): | def parse(self, seq, set_state=None): | ||||
| i = 0 | i = 0 | ||||
| token = None | token = None | ||||
| stream = iter(seq) | 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 = [] | value_stack = [] | ||||
| if set_state: set_state(self.analysis.init_state_idx) | |||||
| if set_state: set_state(self.init_state) | |||||
| def get_action(key): | def get_action(key): | ||||
| state = state_stack[-1] | state = state_stack[-1] | ||||
| try: | try: | ||||
| return states_idx[state][key] | |||||
| return states[state][key] | |||||
| except KeyError: | except KeyError: | ||||
| expected = states_idx[state].keys() | |||||
| expected = states[state].keys() | |||||
| raise UnexpectedToken(token, expected, seq, i) | raise UnexpectedToken(token, expected, seq, i) | ||||
| @@ -45,7 +55,7 @@ class Parser(object): | |||||
| res = self.callbacks[rule](s) | 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 | return res | ||||
| _action, new_state = get_action(rule.origin) | _action, new_state = get_action(rule.origin) | ||||
| @@ -76,7 +86,7 @@ class Parser(object): | |||||
| assert _action == 'reduce' | assert _action == 'reduce' | ||||
| res = reduce(*rule, end=True) | res = reduce(*rule, end=True) | ||||
| if res: | 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 | return res | ||||