This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

91 行
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. ###}