This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

96 righe
2.8 KiB

  1. """This module implements a LALR(1) Parser
  2. """
  3. # Author: Erez Shinan (2017)
  4. # Email : erezshin@gmail.com
  5. from ..common import ParseError, UnexpectedToken
  6. from .lalr_analysis import LALR_Analyzer, Shift
  7. class FinalReduce:
  8. def __init__(self, value):
  9. self.value = value
  10. class Parser:
  11. def __init__(self, parser_conf):
  12. assert all(r.options is None or r.options.priority is None
  13. for r in parser_conf.rules), "LALR doesn't yet support prioritization"
  14. self.analysis = analysis = LALR_Analyzer(parser_conf.rules, parser_conf.start)
  15. analysis.compute_lookahead()
  16. callbacks = {rule: getattr(parser_conf.callback, rule.alias or rule.origin, None)
  17. for rule in analysis.rules}
  18. self.parser = _Parser(analysis.parse_table, callbacks)
  19. self.parse = self.parser.parse
  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)
  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)
  51. assert _action is Shift
  52. state_stack.append(new_state)
  53. value_stack.append(value)
  54. # Main LALR-parser loop
  55. try:
  56. token = next(stream)
  57. i += 1
  58. while True:
  59. action, arg = get_action(token.type)
  60. assert arg != self.end_state
  61. if action is Shift:
  62. state_stack.append(arg)
  63. value_stack.append(token)
  64. if set_state: set_state(arg)
  65. token = next(stream)
  66. i += 1
  67. else:
  68. reduce(arg)
  69. except StopIteration:
  70. pass
  71. while True:
  72. _action, arg = get_action('$END')
  73. if _action is Shift:
  74. assert arg == self.end_state
  75. val ,= value_stack
  76. return val
  77. else:
  78. reduce(arg)