This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.3 KiB

  1. # This module provide a LALR puppet, which is used to debugging and error handling
  2. from copy import deepcopy
  3. from .lalr_analysis import Shift, Reduce
  4. class ParserPuppet:
  5. def __init__(self, parser, state_stack, value_stack, start, stream, set_state):
  6. self.parser = parser
  7. self._state_stack = state_stack
  8. self._value_stack = value_stack
  9. self._start = start
  10. self._stream = stream
  11. self._set_state = set_state
  12. self.result = None
  13. def feed_token(self, token):
  14. end_state = self.parser.parse_table.end_states[self._start]
  15. state_stack = self._state_stack
  16. value_stack = self._value_stack
  17. state = state_stack[-1]
  18. action, arg = self.parser.parse_table.states[state][token.type]
  19. assert arg != end_state
  20. while action is Reduce:
  21. rule = arg
  22. size = len(rule.expansion)
  23. if size:
  24. s = value_stack[-size:]
  25. del state_stack[-size:]
  26. del value_stack[-size:]
  27. else:
  28. s = []
  29. value = self.parser.callbacks[rule](s)
  30. _action, new_state = self.parser.parse_table.states[state_stack[-1]][rule.origin.name]
  31. assert _action is Shift
  32. state_stack.append(new_state)
  33. value_stack.append(value)
  34. if state_stack[-1] == end_state:
  35. self.result = value_stack[-1]
  36. return self.result
  37. state = state_stack[-1]
  38. action, arg = self.parser.parse_table.states[state][token.type]
  39. assert arg != end_state
  40. assert action is Shift
  41. state_stack.append(arg)
  42. value_stack.append(token)
  43. def copy(self):
  44. return type(self)(
  45. self.parser,
  46. list(self._state_stack),
  47. deepcopy(self._value_stack),
  48. self._start,
  49. self._stream,
  50. self._set_state,
  51. )
  52. def pretty():
  53. print("Puppet choices:")
  54. for k, v in self.choices.items():
  55. print('\t-', k, '->', v)
  56. print('stack size:', len(self._state_stack))
  57. def choices(self):
  58. return self.parser.parse_table.states[self._state_stack[-1]]
  59. def resume_parse(self):
  60. return self.parser.parse(self._stream, self._start, self._set_state, self._value_stack, self._state_stack)