This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

91 rader
2.7 KiB

  1. """This module implements a LALR(1) Parser
  2. """
  3. # Author: Erez Shinan (2017)
  4. # Email : erezshin@gmail.com
  5. from ..common import UnexpectedToken
  6. from .lalr_analysis import LALR_Analyzer, Shift
  7. class Parser:
  8. def __init__(self, parser_conf):
  9. assert all(r.options is None or r.options.priority is None
  10. for r in parser_conf.rules), "LALR doesn't yet support prioritization"
  11. analysis = LALR_Analyzer(parser_conf)
  12. analysis.compute_lookahead()
  13. callbacks = {rule: getattr(parser_conf.callback, rule.alias or rule.origin, None)
  14. for rule in parser_conf.rules}
  15. self._parse_table = analysis.parse_table
  16. self.parser_conf = parser_conf
  17. self.parser = _Parser(analysis.parse_table, callbacks)
  18. self.parse = self.parser.parse
  19. ###{standalone
  20. class _Parser:
  21. def __init__(self, parse_table, callbacks):
  22. self.states = parse_table.states
  23. self.start_state = parse_table.start_state
  24. self.end_state = parse_table.end_state
  25. self.callbacks = callbacks
  26. def parse(self, seq, set_state=None):
  27. i = 0
  28. token = None
  29. stream = iter(seq)
  30. states = self.states
  31. state_stack = [self.start_state]
  32. value_stack = []
  33. if set_state: set_state(self.start_state)
  34. def get_action(key):
  35. state = state_stack[-1]
  36. try:
  37. return states[state][key]
  38. except KeyError:
  39. expected = states[state].keys()
  40. raise UnexpectedToken(token, expected, seq, i, state=state)
  41. def reduce(rule):
  42. size = len(rule.expansion)
  43. if size:
  44. s = value_stack[-size:]
  45. del state_stack[-size:]
  46. del value_stack[-size:]
  47. else:
  48. s = []
  49. value = self.callbacks[rule](s)
  50. _action, new_state = get_action(rule.origin.name)
  51. assert _action is Shift
  52. state_stack.append(new_state)
  53. value_stack.append(value)
  54. # Main LALR-parser loop
  55. for i, token in enumerate(stream):
  56. while True:
  57. action, arg = get_action(token.type)
  58. assert arg != self.end_state
  59. if action is Shift:
  60. state_stack.append(arg)
  61. value_stack.append(token)
  62. if set_state: set_state(arg)
  63. break # next token
  64. else:
  65. reduce(arg)
  66. while True:
  67. _action, arg = get_action('$END')
  68. if _action is Shift:
  69. assert arg == self.end_state
  70. val ,= value_stack
  71. return val
  72. else:
  73. reduce(arg)
  74. ###}