|
- # This module provide a LALR puppet, which is used to debugging and error handling
-
- from copy import deepcopy
-
- from .lalr_analysis import Shift, Reduce
-
- class ParserPuppet:
- def __init__(self, parser, state_stack, value_stack, start, stream, set_state):
- self.parser = parser
- self._state_stack = state_stack
- self._value_stack = value_stack
- self._start = start
- self._stream = stream
- self._set_state = set_state
-
- self.result = None
-
- def feed_token(self, token):
- """Advance the parser state, as if it just recieved `token` from the lexer
-
- """
- end_state = self.parser.parse_table.end_states[self._start]
- state_stack = self._state_stack
- value_stack = self._value_stack
-
- state = state_stack[-1]
- action, arg = self.parser.parse_table.states[state][token.type]
- assert arg != end_state
-
- while action is Reduce:
- rule = arg
- size = len(rule.expansion)
- if size:
- s = value_stack[-size:]
- del state_stack[-size:]
- del value_stack[-size:]
- else:
- s = []
-
- value = self.parser.callbacks[rule](s)
-
- _action, new_state = self.parser.parse_table.states[state_stack[-1]][rule.origin.name]
- assert _action is Shift
- state_stack.append(new_state)
- value_stack.append(value)
-
- if state_stack[-1] == end_state:
- self.result = value_stack[-1]
- return self.result
-
- state = state_stack[-1]
- action, arg = self.parser.parse_table.states[state][token.type]
- assert arg != end_state
-
- assert action is Shift
- state_stack.append(arg)
- value_stack.append(token)
-
- def copy(self):
- return type(self)(
- self.parser,
- list(self._state_stack),
- deepcopy(self._value_stack),
- self._start,
- self._stream,
- self._set_state,
- )
-
- def pretty():
- print("Puppet choices:")
- for k, v in self.choices.items():
- print('\t-', k, '->', v)
- print('stack size:', len(self._state_stack))
-
- def choices(self):
- return self.parser.parse_table.states[self._state_stack[-1]]
-
- def resume_parse(self):
- return self.parser.parse(self._stream, self._start, self._set_state, self._value_stack, self._state_stack)
|