rattler 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. data/README.rdoc +57 -37
  2. data/features/command_line/dest_option.feature +8 -21
  3. data/features/command_line/lib_option.feature +37 -0
  4. data/features/command_line/parser_generator.feature +7 -4
  5. data/features/grammar/back_reference.feature +37 -0
  6. data/features/grammar/fail.feature +3 -3
  7. data/features/grammar/labels.feature +11 -3
  8. data/features/grammar/list_matching.feature +14 -5
  9. data/features/grammar/literal.feature +30 -4
  10. data/features/grammar/nonterminal.feature +1 -1
  11. data/features/grammar/ordered_choice.feature +2 -2
  12. data/features/grammar/skip_operator.feature +1 -1
  13. data/features/grammar/symantic_action.feature +7 -7
  14. data/features/grammar/whitespace.feature +2 -2
  15. data/features/step_definitions/grammar_steps.rb +2 -2
  16. data/lib/rattler/back_end.rb +1 -0
  17. data/lib/rattler/back_end/compiler.rb +19 -20
  18. data/lib/rattler/back_end/optimizer.rb +100 -0
  19. data/lib/rattler/back_end/optimizer/composite_reducing.rb +18 -0
  20. data/lib/rattler/back_end/optimizer/flatten_choice.rb +31 -0
  21. data/lib/rattler/back_end/optimizer/flatten_sequence.rb +59 -0
  22. data/lib/rattler/back_end/optimizer/flattening.rb +17 -0
  23. data/lib/rattler/back_end/optimizer/inline_regular_rules.rb +46 -0
  24. data/lib/rattler/back_end/optimizer/join_match_capturing_sequence.rb +71 -0
  25. data/lib/rattler/back_end/optimizer/join_match_choice.rb +37 -0
  26. data/lib/rattler/back_end/optimizer/join_match_matching_sequence.rb +38 -0
  27. data/lib/rattler/back_end/optimizer/join_match_sequence.rb +17 -0
  28. data/lib/rattler/back_end/optimizer/join_predicate_bare_match.rb +68 -0
  29. data/lib/rattler/back_end/optimizer/join_predicate_match.rb +17 -0
  30. data/lib/rattler/back_end/optimizer/join_predicate_nested_match.rb +37 -0
  31. data/lib/rattler/back_end/optimizer/join_predicate_or_bare_match.rb +68 -0
  32. data/lib/rattler/back_end/optimizer/join_predicate_or_match.rb +17 -0
  33. data/lib/rattler/back_end/optimizer/join_predicate_or_nested_match.rb +36 -0
  34. data/lib/rattler/back_end/optimizer/match_joining.rb +60 -0
  35. data/lib/rattler/back_end/optimizer/optimization.rb +94 -0
  36. data/lib/rattler/back_end/optimizer/optimization_context.rb +72 -0
  37. data/lib/rattler/back_end/optimizer/optimization_sequence.rb +37 -0
  38. data/lib/rattler/back_end/optimizer/optimize_children.rb +46 -0
  39. data/lib/rattler/back_end/optimizer/reduce_repeat_match.rb +44 -0
  40. data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rb +32 -0
  41. data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rb +43 -0
  42. data/lib/rattler/back_end/optimizer/simplify_token_match.rb +38 -0
  43. data/lib/rattler/back_end/parser_generator.rb +21 -14
  44. data/lib/rattler/back_end/parser_generator/apply_generator.rb +35 -35
  45. data/lib/rattler/back_end/parser_generator/assert_generator.rb +29 -30
  46. data/lib/rattler/back_end/parser_generator/back_reference_generator.rb +93 -0
  47. data/lib/rattler/back_end/parser_generator/choice_generator.rb +33 -49
  48. data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +14 -14
  49. data/lib/rattler/back_end/parser_generator/disallow_generator.rb +29 -30
  50. data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +11 -13
  51. data/lib/rattler/back_end/parser_generator/expr_generator.rb +36 -56
  52. data/lib/rattler/back_end/parser_generator/fail_generator.rb +18 -18
  53. data/lib/rattler/back_end/parser_generator/group_match.rb +18 -0
  54. data/lib/rattler/back_end/parser_generator/group_match_generator.rb +76 -0
  55. data/lib/rattler/back_end/parser_generator/label_generator.rb +25 -6
  56. data/lib/rattler/back_end/parser_generator/list1_generator.rb +7 -7
  57. data/lib/rattler/back_end/parser_generator/list_generating.rb +19 -20
  58. data/lib/rattler/back_end/parser_generator/list_generator.rb +5 -5
  59. data/lib/rattler/back_end/parser_generator/match_generator.rb +52 -52
  60. data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +6 -6
  61. data/lib/rattler/back_end/parser_generator/optional_generator.rb +30 -29
  62. data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +8 -8
  63. data/lib/rattler/back_end/parser_generator/repeat_generating.rb +23 -25
  64. data/lib/rattler/back_end/parser_generator/rule_generator.rb +27 -79
  65. data/lib/rattler/back_end/parser_generator/rule_set_generator.rb +102 -0
  66. data/lib/rattler/back_end/parser_generator/sequence_generator.rb +49 -41
  67. data/lib/rattler/back_end/parser_generator/skip_generator.rb +14 -20
  68. data/lib/rattler/back_end/parser_generator/skip_propogating.rb +4 -4
  69. data/lib/rattler/back_end/parser_generator/sub_generating.rb +6 -0
  70. data/lib/rattler/back_end/parser_generator/token_generator.rb +12 -12
  71. data/lib/rattler/back_end/parser_generator/token_propogating.rb +2 -2
  72. data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +4 -4
  73. data/lib/rattler/grammar.rb +4 -3
  74. data/lib/rattler/grammar/analysis.rb +91 -0
  75. data/lib/rattler/grammar/grammar.rb +37 -25
  76. data/lib/rattler/grammar/grammar_parser.rb +19 -11
  77. data/lib/rattler/grammar/metagrammar.rb +569 -800
  78. data/lib/rattler/grammar/rattler.rtlr +162 -144
  79. data/lib/rattler/parsers.rb +5 -1
  80. data/lib/rattler/parsers/action_code.rb +29 -15
  81. data/lib/rattler/parsers/apply.rb +5 -5
  82. data/lib/rattler/parsers/assert.rb +4 -18
  83. data/lib/rattler/parsers/back_reference.rb +46 -0
  84. data/lib/rattler/parsers/choice.rb +6 -39
  85. data/lib/rattler/parsers/combinator_parser.rb +32 -0
  86. data/lib/rattler/parsers/combining.rb +3 -29
  87. data/lib/rattler/parsers/direct_action.rb +27 -30
  88. data/lib/rattler/parsers/disallow.rb +4 -18
  89. data/lib/rattler/parsers/dispatch_action.rb +30 -25
  90. data/lib/rattler/parsers/label.rb +9 -18
  91. data/lib/rattler/parsers/list.rb +3 -34
  92. data/lib/rattler/parsers/list1.rb +4 -36
  93. data/lib/rattler/parsers/list_parser.rb +64 -0
  94. data/lib/rattler/parsers/match.rb +7 -42
  95. data/lib/rattler/parsers/node_code.rb +44 -0
  96. data/lib/rattler/parsers/one_or_more.rb +7 -27
  97. data/lib/rattler/parsers/optional.rb +5 -25
  98. data/lib/rattler/parsers/parser.rb +16 -44
  99. data/lib/rattler/parsers/parser_dsl.rb +13 -3
  100. data/lib/rattler/parsers/predicate.rb +4 -12
  101. data/lib/rattler/parsers/rule.rb +18 -19
  102. data/lib/rattler/parsers/rule_set.rb +63 -0
  103. data/lib/rattler/parsers/sequence.rb +12 -46
  104. data/lib/rattler/parsers/skip.rb +12 -26
  105. data/lib/rattler/parsers/token.rb +6 -21
  106. data/lib/rattler/parsers/zero_or_more.rb +6 -26
  107. data/lib/rattler/runner.rb +66 -28
  108. data/lib/rattler/runtime/extended_packrat_parser.rb +26 -20
  109. data/lib/rattler/runtime/packrat_parser.rb +17 -21
  110. data/lib/rattler/runtime/parser.rb +12 -2
  111. data/lib/rattler/runtime/recursive_descent_parser.rb +3 -11
  112. data/lib/rattler/util.rb +2 -1
  113. data/lib/rattler/util/graphviz.rb +29 -0
  114. data/lib/rattler/util/graphviz/digraph_builder.rb +71 -0
  115. data/lib/rattler/util/graphviz/node_builder.rb +84 -0
  116. data/lib/rattler/util/node.rb +37 -19
  117. data/lib/rattler/util/parser_spec_helper.rb +61 -35
  118. data/spec/rattler/back_end/compiler_spec.rb +6 -860
  119. data/spec/rattler/back_end/optimizer/flatten_choice_spec.rb +70 -0
  120. data/spec/rattler/back_end/optimizer/flatten_sequence_spec.rb +130 -0
  121. data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rb +80 -0
  122. data/spec/rattler/back_end/optimizer/join_match_capturing_sequence_spec.rb +241 -0
  123. data/spec/rattler/back_end/optimizer/join_match_choice_spec.rb +100 -0
  124. data/spec/rattler/back_end/optimizer/join_match_matching_sequence_spec.rb +112 -0
  125. data/spec/rattler/back_end/optimizer/join_predicate_bare_match_spec.rb +194 -0
  126. data/spec/rattler/back_end/optimizer/join_predicate_nested_match_spec.rb +180 -0
  127. data/spec/rattler/back_end/optimizer/join_predicate_or_bare_match_spec.rb +153 -0
  128. data/spec/rattler/back_end/optimizer/join_predicate_or_nested_match_spec.rb +153 -0
  129. data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rb +98 -0
  130. data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rb +226 -0
  131. data/spec/rattler/back_end/optimizer/simplify_token_match_spec.rb +85 -0
  132. data/spec/rattler/back_end/parser_generator/apply_generator_spec.rb +38 -33
  133. data/spec/rattler/back_end/parser_generator/assert_generator_spec.rb +38 -33
  134. data/spec/rattler/back_end/parser_generator/back_reference_generator_spec.rb +181 -0
  135. data/spec/rattler/back_end/parser_generator/choice_generator_spec.rb +38 -33
  136. data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rb +38 -33
  137. data/spec/rattler/back_end/parser_generator/disallow_generator_spec.rb +38 -33
  138. data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rb +38 -33
  139. data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rb +185 -0
  140. data/spec/rattler/back_end/parser_generator/label_generator_spec.rb +38 -33
  141. data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +10 -5
  142. data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +10 -5
  143. data/spec/rattler/back_end/parser_generator/match_generator_spec.rb +38 -33
  144. data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rb +38 -33
  145. data/spec/rattler/back_end/parser_generator/optional_generator_spec.rb +38 -33
  146. data/spec/rattler/back_end/parser_generator/rule_generator_spec.rb +13 -46
  147. data/spec/rattler/back_end/parser_generator/rule_set_generator_spec.rb +97 -0
  148. data/spec/rattler/back_end/parser_generator/sequence_generator_spec.rb +38 -33
  149. data/spec/rattler/back_end/parser_generator/skip_generator_spec.rb +38 -33
  150. data/spec/rattler/back_end/parser_generator/token_generator_spec.rb +38 -33
  151. data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rb +39 -34
  152. data/spec/rattler/back_end/shared_compiler_examples.rb +885 -0
  153. data/spec/rattler/grammar/analysis_spec.rb +167 -0
  154. data/spec/rattler/grammar/grammar_parser_spec.rb +169 -179
  155. data/spec/rattler/grammar/grammar_spec.rb +24 -21
  156. data/spec/rattler/parsers/action_code_spec.rb +64 -19
  157. data/spec/rattler/parsers/apply_spec.rb +9 -9
  158. data/spec/rattler/parsers/back_reference_spec.rb +38 -0
  159. data/spec/rattler/parsers/combinator_parser_spec.rb +14 -0
  160. data/spec/rattler/parsers/direct_action_spec.rb +16 -2
  161. data/spec/rattler/parsers/dispatch_action_spec.rb +15 -32
  162. data/spec/rattler/parsers/fail_spec.rb +6 -4
  163. data/spec/rattler/parsers/label_spec.rb +10 -28
  164. data/spec/rattler/parsers/node_code_spec.rb +48 -0
  165. data/spec/rattler/parsers/parser_dsl_spec.rb +1 -1
  166. data/spec/rattler/parsers/rule_set_spec.rb +35 -0
  167. data/spec/rattler/parsers/sequence_spec.rb +15 -24
  168. data/spec/rattler/runtime/extended_packrat_parser_spec.rb +22 -17
  169. data/spec/rattler/runtime/packrat_parser_spec.rb +1 -1
  170. data/spec/rattler/runtime/parse_node_spec.rb +15 -19
  171. data/spec/rattler/runtime/recursive_descent_parser_spec.rb +1 -1
  172. data/spec/rattler/runtime/shared_parser_examples.rb +61 -28
  173. data/spec/rattler/util/graphviz/node_builder_spec.rb +84 -0
  174. data/spec/rattler/util/node_spec.rb +92 -65
  175. data/spec/rattler_spec.rb +16 -16
  176. data/spec/support/combinator_parser_spec_helper.rb +19 -18
  177. data/spec/support/compiler_spec_helper.rb +56 -87
  178. data/spec/support/runtime_parser_spec_helper.rb +6 -14
  179. metadata +117 -22
  180. data/features/grammar/regex.feature +0 -24
  181. data/lib/rattler/parsers/match_joining.rb +0 -67
  182. data/lib/rattler/parsers/rules.rb +0 -43
@@ -0,0 +1,36 @@
1
+ #
2
+ # = rattler/back_end/optimizer/join_predicate_or_nested_match.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # A predicate and an adjacent skip of a Regexp match in a Choice can be
12
+ # joined into a single skip of a Regexp match.
13
+ #
14
+ # @author Jason Arhart
15
+ #
16
+ class JoinPredicateOrNestedMatch < JoinPredicateOrBareMatch
17
+ include CompositeReducing
18
+
19
+ include Rattler::Parsers
20
+
21
+ protected
22
+
23
+ def reduce(*pair)
24
+ pair.find {|_| _.is_a? Skip }.with_child super
25
+ end
26
+
27
+ def prepare_pattern(parser)
28
+ super(parser.is_a?(Skip) ? parser.child : parser)
29
+ end
30
+
31
+ def eligible_match?(parser)
32
+ parser.is_a? Skip and super parser.child
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,60 @@
1
+ require 'rattler'
2
+
3
+ module Rattler::BackEnd::Optimizer
4
+ # @private
5
+ module MatchJoining #:nodoc:
6
+
7
+ include CompositeReducing
8
+
9
+ include Rattler::Parsers
10
+
11
+ protected
12
+
13
+ def _applies_to?(parser, context)
14
+ any_neighbors?(parser) {|_| eligible_child? _ }
15
+ end
16
+
17
+ def _apply(parser, context)
18
+ new_children = []
19
+ matches = []
20
+ for child in parser
21
+ if eligible_child? child
22
+ matches << child
23
+ else
24
+ join_matches(matches) {|match| new_children << match }
25
+ matches = []
26
+ new_children << child
27
+ end
28
+ end
29
+ join_matches(matches) {|match| new_children << match }
30
+ finish_reduce parser, new_children
31
+ end
32
+
33
+ def any_neighbors?(parser)
34
+ parser.each_cons(2).any? {|a| a.all? {|_| yield _ } }
35
+ end
36
+
37
+ def join_matches(matches)
38
+ unless matches.empty?
39
+ yield create_match(join_patterns(create_patterns(matches)))
40
+ end
41
+ end
42
+
43
+ def create_patterns(matches)
44
+ matches.map {|_| create_pattern _ }
45
+ end
46
+
47
+ def join_patterns(patterns)
48
+ patterns.join
49
+ end
50
+
51
+ def create_pattern(match)
52
+ match.re.source
53
+ end
54
+
55
+ def create_match(pattern)
56
+ Match[Regexp.new(pattern)]
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,94 @@
1
+ #
2
+ # = rattler/back_end/optimizer/optimization.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+ require 'singleton'
9
+
10
+ module Rattler::BackEnd::Optimizer
11
+ #
12
+ # An +Optimization+ represents a simple transformation of a parser model into
13
+ # an equivalent model that can result in more efficient parsing code.
14
+ # Subclasses override <tt>#_applies_to?</tt> and <tt>#_apply</tt> to define
15
+ # an optimization.
16
+ #
17
+ # @author Jason Arhart
18
+ #
19
+ class Optimization
20
+
21
+ class <<self
22
+ def instance
23
+ @instance ||= self.new
24
+ end
25
+
26
+ # @see Rattler::BackEnd::Optimizer::Optimization#>>
27
+ def >>(other)
28
+ instance >> (other.respond_to?(:instance) ? other.instance : other)
29
+ end
30
+
31
+ # @see Rattler::BackEnd::Optimizer::Optimization#match
32
+ def apply(*args)
33
+ instance.apply(*args)
34
+ end
35
+
36
+ # @see Rattler::BackEnd::Optimizer::Optimization#applies_to?
37
+ def applies_to?(*args)
38
+ instance.applies_to?(*args)
39
+ end
40
+ end
41
+
42
+ def initialize
43
+ @applies_to_cache = Hash.new {|h, k| h[k] = {} }
44
+ end
45
+
46
+ # Return a new optimzation that sequences this optimzation and +other+,
47
+ # i.e. the new optimzation applies this optimzation, then applies +other+
48
+ # to the result.
49
+ #
50
+ # @param [Rattler::BackEnd::Optimizer::Optimization] other the optimization
51
+ # to apply after this one
52
+ #
53
+ # @return [Rattler::BackEnd::Optimizer::Optimization] a new optimzation
54
+ # that sequences this optimzation and +other+
55
+ def >>(other)
56
+ OptimizationSequence.new(self, other)
57
+ end
58
+
59
+ # Apply the optimzation to +parser+ in +context+ if
60
+ # <tt>#applies_to?(parser, context)</tt> is +true+.
61
+ #
62
+ # @param [Rattler::Parsers::Parser] parser the parser to be optimized
63
+ # @param [Rattler::BackEnd::Optimizer::OptimizationContext] context
64
+ #
65
+ # @return [Rattler::Parsers::Parser] the optimized parser
66
+ def apply(parser, context)
67
+ applies_to?(parser, context) ? _apply(parser, context) : parser
68
+ end
69
+
70
+ # Return +true+ if this optimzation applies to +parser+ in +context+.
71
+ #
72
+ # @param [Rattler::Parsers::Parser] parser a parser model
73
+ # @param [Rattler::BackEnd::Optimizer::OptimizationContext] context
74
+ #
75
+ # @return [Boolean] +true+ if this optimzation applies to +parser+ in
76
+ # +context+
77
+ def applies_to?(parser, context)
78
+ @applies_to_cache[context].fetch(parser) do
79
+ @applies_to_cache[context][parser] = _applies_to?(parser, context)
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def optimize(parser, context)
86
+ optimizations.apply(parser, context)
87
+ end
88
+
89
+ def optimizations
90
+ ::Rattler::BackEnd::Optimizer.optimizations
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,72 @@
1
+ #
2
+ # = rattler/back_end/optimizer/optimization_context.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler/back_end/optimizer'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # +OptimizationContext+ provides contextual information to optimzations.
12
+ #
13
+ # @author Jason Arhart
14
+ #
15
+ class OptimizationContext
16
+
17
+ @@cache = Hash.new {|h, attrs| h[attrs] = self.new(attrs) }
18
+
19
+ def self.[](attrs)
20
+ @@cache[attrs]
21
+ end
22
+
23
+ def initialize(attrs)
24
+ @attrs = attrs
25
+ @rules = @attrs[:rules]
26
+ end
27
+
28
+ attr_reader :type, :rules
29
+
30
+ def start_rule
31
+ rules && rules.start_rule
32
+ end
33
+
34
+ def analysis
35
+ rules && rules.analysis
36
+ end
37
+
38
+ def capturing?
39
+ @attrs[:type] == :capturing
40
+ end
41
+
42
+ def matching?
43
+ @attrs[:type] == :matching
44
+ end
45
+
46
+ def standalone?
47
+ start_rule && @attrs[:standalone]
48
+ end
49
+
50
+ def relavent?(rule)
51
+ (not standalone? and not rule.attrs[:inline]) or
52
+ analysis.referenced?(rule.name)
53
+ end
54
+
55
+ def with(new_attrs)
56
+ self.class[@attrs.merge new_attrs]
57
+ end
58
+
59
+ def method_missing(symbol, *args)
60
+ if args.empty? and @attrs.has_key? symbol
61
+ @attrs[symbol]
62
+ else
63
+ super
64
+ end
65
+ end
66
+
67
+ def respond_to?(symbol)
68
+ super or @attrs.has_key? symbol
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,37 @@
1
+ #
2
+ # = rattler/back_end/optimizer/optimization.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # An +OptimizationSequence+ sequences a pair of optimzations so that applying
12
+ # the sequence applies the first optimization, then applies the second
13
+ # optimzation to the result.
14
+ #
15
+ # @author Jason Arhart
16
+ #
17
+ class OptimizationSequence < Optimization
18
+
19
+ def initialize(init, last)
20
+ super()
21
+ @init = init
22
+ @last = last
23
+ end
24
+
25
+ protected
26
+
27
+ def _applies_to?(parser, context)
28
+ @last.applies_to? parser, context or
29
+ @init.applies_to? parser, context
30
+ end
31
+
32
+ def _apply(parser, context)
33
+ @last.apply(@init.apply(parser, context), context)
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # = rattler/back_end/optimizer/flatten_choice.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # Optimizes all of the children of a parser model in the appropriate context.
12
+ #
13
+ # @author Jason Arhart
14
+ #
15
+ class OptimizeChildren < Optimization
16
+
17
+ include Rattler::Parsers
18
+
19
+ protected
20
+
21
+ def _applies_to?(parser, context)
22
+ !parser.children.empty? and
23
+ (parser.any? do |_|
24
+ optimizations.applies_to? _, child_context(parser, context)
25
+ end)
26
+ end
27
+
28
+ def _apply(parser, context)
29
+ parser.with_children(parser.map do |_|
30
+ optimize _, child_context(parser, context)
31
+ end)
32
+ end
33
+
34
+ private
35
+
36
+ def child_context(parser, context)
37
+ case parser
38
+ when Assert, Disallow, Token, Skip
39
+ context.with :type => :matching
40
+ else
41
+ context
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,44 @@
1
+ #
2
+ # = rattler/back_end/optimizer/reduce_repeat_match.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # A repeat of a Regexp match can be reduced to a single Regexp match.
12
+ #
13
+ # @author Jason Arhart
14
+ #
15
+ class ReduceRepeatMatch < Optimization
16
+
17
+ include Rattler::Parsers
18
+
19
+ protected
20
+
21
+ def _applies_to?(parser, context)
22
+ context.matching? and
23
+ case parser
24
+ when ZeroOrMore, OneOrMore, Optional
25
+ parser.child.is_a?(Match)
26
+ end
27
+ end
28
+
29
+ def _apply(parser, context)
30
+ Match[Regexp.new("(?>#{parser.child.re.source})#{suffix parser}")]
31
+ end
32
+
33
+ private
34
+
35
+ def suffix(parser)
36
+ case parser
37
+ when ZeroOrMore then '*'
38
+ when OneOrMore then '+'
39
+ when Optional then '?'
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,32 @@
1
+ #
2
+ # = rattler/back_end/optimizer/remove_meaningless_wrapper.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # Token, skip, and symantic action wrappers only have meaning in a capturing
12
+ # context.
13
+ #
14
+ # @author Jason Arhart
15
+ #
16
+ class RemoveMeaninglessWrapper < Optimization
17
+
18
+ include Rattler::Parsers
19
+
20
+ protected
21
+
22
+ def _applies_to?(parser, context)
23
+ context.matching? and
24
+ [Token, Skip, DispatchAction, DirectAction].any? {|_| parser.is_a? _ }
25
+ end
26
+
27
+ def _apply(parser, context)
28
+ parser.child
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ #
2
+ # = rattler/back_end/optimizer/simplify_redundant_repeat.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # A repeat of a repeat can be simplified to a simple repeat.
12
+ #
13
+ # @author Jason Arhart
14
+ #
15
+ class SimplifyRedundantRepeat < Optimization
16
+
17
+ include Rattler::Parsers
18
+
19
+ @@repeat_types = [ZeroOrMore, OneOrMore, Optional]
20
+
21
+ protected
22
+
23
+ def _applies_to?(parser, context)
24
+ context.matching? and
25
+ [parser, parser.child].all? {|_| repeat? _ }
26
+ end
27
+
28
+ def _apply(parser, context)
29
+ if @@repeat_types.any? {|_| parser.is_a?(_) and parser.child.is_a?(_) }
30
+ parser.child
31
+ else
32
+ ZeroOrMore[parser.child.child]
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def repeat?(parser)
39
+ @@repeat_types.any? {|_| parser.is_a? _ }
40
+ end
41
+
42
+ end
43
+ end