This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

77 lignes
2.3 KiB

  1. from ..common import ParseError, UnexpectedToken
  2. from .lalr_analysis import LALR_Analyzer, ACTION_SHIFT
  3. class Parser(object):
  4. def __init__(self, parser_conf):
  5. self.analysis = LALR_Analyzer(parser_conf.rules, parser_conf.start)
  6. self.analysis.compute_lookahead()
  7. self.callbacks = {rule: getattr(parser_conf.callback, rule.alias or rule.origin, None)
  8. for rule in self.analysis.rules}
  9. def parse(self, seq, set_state=None):
  10. i = 0
  11. stream = iter(seq)
  12. states_idx = self.analysis.states_idx
  13. state_stack = [self.analysis.init_state_idx]
  14. value_stack = []
  15. if set_state: set_state(self.analysis.init_state_idx)
  16. def get_action(key):
  17. state = state_stack[-1]
  18. try:
  19. return states_idx[state][key]
  20. except KeyError:
  21. expected = states_idx[state].keys()
  22. raise UnexpectedToken(token, expected, seq, i)
  23. def reduce(rule, size):
  24. if size:
  25. s = value_stack[-size:]
  26. del state_stack[-size:]
  27. del value_stack[-size:]
  28. else:
  29. s = []
  30. res = self.callbacks[rule](s)
  31. if len(state_stack) == 1 and rule.origin == self.analysis.start_symbol:
  32. return res
  33. _action, new_state = get_action(rule.origin)
  34. assert _action == ACTION_SHIFT
  35. state_stack.append(new_state)
  36. value_stack.append(res)
  37. # Main LALR-parser loop
  38. try:
  39. token = next(stream)
  40. i += 1
  41. while True:
  42. action, arg = get_action(token.type)
  43. if action == ACTION_SHIFT:
  44. state_stack.append(arg)
  45. value_stack.append(token)
  46. if set_state: set_state(arg)
  47. token = next(stream)
  48. i += 1
  49. else:
  50. reduce(*arg)
  51. except StopIteration:
  52. pass
  53. while True:
  54. _action, rule = get_action('$end')
  55. assert _action == 'reduce'
  56. res = reduce(*rule)
  57. if res:
  58. assert state_stack == [self.analysis.init_state_idx] and not value_stack, len(state_stack)
  59. return res