lrule.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. '''*****************************************************************************
  2. AToMPM - A Tool for Multi-Paradigm Modelling
  3. Copyright (c) 2011 Eugene Syriani
  4. This file is part of AToMPM.
  5. AToMPM is free software: you can redistribute it and/or modify it under the
  6. terms of the GNU Lesser General Public License as published by the Free Software
  7. Foundation, either version 3 of the License, or (at your option) any later
  8. version.
  9. AToMPM is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  11. PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with AToMPM. If not, see <http://www.gnu.org/licenses/>.
  14. *****************************************************************************'''
  15. from ..util.infinity import INFINITY
  16. from ..tcore.composer import Composer
  17. from ..tcore.matcher import Matcher
  18. from ..tcore.iterator import Iterator
  19. class LRule(Composer):
  20. '''
  21. Applies an inner rule for each match of the LHS.
  22. '''
  23. def __init__(self, LHS, inner_rule, max_iterations=INFINITY):
  24. '''
  25. Applies an inner rule for each match of the LHS.
  26. @param LHS: The pre-condition pattern (LHS + NACs).
  27. @param inner_rule: The rule to apply in the loop.
  28. @param max_iterations: The maximum number of matches of the LHS.
  29. '''
  30. super(LRule, self).__init__()
  31. self.M = Matcher(condition=LHS, max=max_iterations)
  32. self.I = Iterator(max_iterations=max_iterations)
  33. self.inner_rule = inner_rule
  34. def packet_in(self, packet):
  35. self.exception = None
  36. self.is_success = False
  37. # Match
  38. packet = self.M.packet_in(packet)
  39. if not self.M.is_success:
  40. self.exception = self.M.exception
  41. return packet
  42. # Choose the first match
  43. packet = self.I.packet_in(packet)
  44. if not self.I.is_success:
  45. self.exception = self.I.exception
  46. return packet
  47. while True:
  48. # Apply the inner rule
  49. packet = self.inner_rule.packet_in(packet)
  50. if not self.inner_rule.is_success:
  51. if self.inner_rule.exception:
  52. self.exception = self.inner_rule.exception
  53. return packet
  54. # Clean the packet: required since there is no Rewriter in a Query
  55. if len(packet.match_sets[self.I.condition].matches) == 0:
  56. del packet.match_sets[self.I.condition]
  57. # Choose another match
  58. packet = self.I.next_in(packet)
  59. # No more iterations are left
  60. if not self.I.is_success:
  61. if self.I.exception:
  62. self.exception = self.I.exception
  63. else:
  64. # Output success packet
  65. self.is_success = True
  66. return packet