lrule.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. '''This file is part of AToMPM - A Tool for Multi-Paradigm Modelling
  2. Copyright 2011 by the AToMPM team and licensed under the LGPL
  3. See COPYING.lesser and README.md in the root of this project for full details'''
  4. from ..util.infinity import INFINITY
  5. from ..tcore.composer import Composer
  6. from ..tcore.matcher import Matcher
  7. from ..tcore.iterator import Iterator
  8. class LRule(Composer):
  9. '''
  10. Applies an inner rule for each match of the LHS.
  11. '''
  12. def __init__(self, LHS, inner_rule, max_iterations=INFINITY):
  13. '''
  14. Applies an inner rule for each match of the LHS.
  15. @param LHS: The pre-condition pattern (LHS + NACs).
  16. @param inner_rule: The rule to apply in the loop.
  17. @param max_iterations: The maximum number of matches of the LHS.
  18. '''
  19. super(LRule, self).__init__()
  20. self.M = Matcher(condition=LHS, max=max_iterations)
  21. self.I = Iterator(max_iterations=max_iterations)
  22. self.inner_rule = inner_rule
  23. def packet_in(self, packet):
  24. self.exception = None
  25. self.is_success = False
  26. # Match
  27. packet = self.M.packet_in(packet)
  28. if not self.M.is_success:
  29. self.exception = self.M.exception
  30. return packet
  31. # Choose the first match
  32. packet = self.I.packet_in(packet)
  33. if not self.I.is_success:
  34. self.exception = self.I.exception
  35. return packet
  36. while True:
  37. # Apply the inner rule
  38. packet = self.inner_rule.packet_in(packet)
  39. if not self.inner_rule.is_success:
  40. if self.inner_rule.exception:
  41. self.exception = self.inner_rule.exception
  42. return packet
  43. # Clean the packet: required since there is no Rewriter in a Query
  44. if len(packet.match_sets[self.I.condition].matches) == 0:
  45. del packet.match_sets[self.I.condition]
  46. # Choose another match
  47. packet = self.I.next_in(packet)
  48. # No more iterations are left
  49. if not self.I.is_success:
  50. if self.I.exception:
  51. self.exception = self.I.exception
  52. else:
  53. # Output success packet
  54. self.is_success = True
  55. return packet