|
|
@@ -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 |
|
|
|
|
|
|
|
|
|
|
|