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
@@ -15,41 +15,10 @@ module Rattler::Parsers
15
15
  #
16
16
  # @author Jason Arhart
17
17
  #
18
- class List < Parser
19
- include Combining
18
+ class List < ListParser
19
+ protected
20
20
 
21
- # @private
22
- def self.parsed(results, *_) #:nodoc:
23
- self[*results]
24
- end
25
-
26
- # Create a new list parser that matches terms with +term_parser+ and
27
- # separators with +sep_parser+
28
- def self.[](term_parser, sep_parser)
29
- self.new(term_parser, :sep_parser => sep_parser)
30
- end
31
-
32
- # Parse terms matched by the term parser in a list with separators matched
33
- # by the separator parser. Return the terms in an array, or +true+ if the
34
- # term parser is not <tt>capturing?</tt>.
35
- #
36
- # @param (see Parser#parse_labeled)
37
- #
38
- # @return [Array, true] an array containing the term parser's parse results,
39
- # or +true+ if the term parser is not <tt>capturing?</tt>
40
- def parse(scanner, rules, labeled = {})
41
- a = []
42
- p = scanner.pos
43
- while result = child.parse(scanner, rules)
44
- p = scanner.pos
45
- a << result
46
- break unless sep_parser.parse(scanner, rules)
47
- end
48
- scanner.pos = p
49
- capturing? ? a : true
50
- end
51
-
52
- def variable_capture_count?
21
+ def enough?(results)
53
22
  true
54
23
  end
55
24
 
@@ -15,43 +15,11 @@ module Rattler::Parsers
15
15
  #
16
16
  # @author Jason Arhart
17
17
  #
18
- class List1 < Parser
19
- include Combining
18
+ class List1 < ListParser
19
+ protected
20
20
 
21
- # @private
22
- def self.parsed(results, *_) #:nodoc:
23
- self[*results]
24
- end
25
-
26
- # Create a new list1 parser that matches terms with +term_parser+ and
27
- # separators with +sep_parser+
28
- def self.[](term_parser, sep_parser)
29
- self.new(term_parser, :sep_parser => sep_parser)
30
- end
31
-
32
- # Parse terms matched by the term parser in a list with separators matched
33
- # by the separator parser. Return the terms in an array, or +true+ if the
34
- # term parser is not <tt>capturing?</tt>, or +false+ if no terms matched..
35
- #
36
- # @param (see Parser#parse_labeled)
37
- #
38
- # @return [Array, true] an array containing the term parser's parse results,
39
- # or +true+ if the term parser is not <tt>capturing?</tt>, or +false+ if
40
- # no terms matched.
41
- def parse(scanner, rules, labeled = {})
42
- a = []
43
- p = scanner.pos
44
- while result = child.parse(scanner, rules)
45
- p = scanner.pos
46
- a << result
47
- break unless sep_parser.parse(scanner, rules)
48
- end
49
- scanner.pos = p
50
- (capturing? ? a : true) unless a.empty?
51
- end
52
-
53
- def variable_capture_count?
54
- true
21
+ def enough?(results)
22
+ not results.empty?
55
23
  end
56
24
 
57
25
  end
@@ -0,0 +1,64 @@
1
+ #
2
+ # = rattler/parsers/list.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+
8
+ require 'rattler/parsers'
9
+
10
+ module Rattler::Parsers
11
+ #
12
+ # +ListParser+ matches terms matched by a term parser in a list with
13
+ # separators matched by a separator parser.
14
+ #
15
+ # @author Jason Arhart
16
+ #
17
+ class ListParser < Parser
18
+ include Combining
19
+
20
+ # @private
21
+ def self.parsed(results, *_) #:nodoc:
22
+ self[*results]
23
+ end
24
+
25
+ # Create a new list parser that matches terms with +term_parser+ and
26
+ # separators with +sep_parser+
27
+ def self.[](term_parser, sep_parser)
28
+ self.new(term_parser, sep_parser.skip)
29
+ end
30
+
31
+ def term_parser
32
+ children[0]
33
+ end
34
+
35
+ def sep_parser
36
+ children[1]
37
+ end
38
+
39
+ # Parse terms matched by the term parser in a list with separators matched
40
+ # by the separator parser. Return the terms in an array, or +true+ if the
41
+ # term parser is not <tt>capturing?</tt>.
42
+ #
43
+ # @param (see Parser#parse_labeled)
44
+ #
45
+ # @return [Array, true] an array containing the term parser's parse results,
46
+ # or +true+ if the term parser is not <tt>capturing?</tt>
47
+ def parse(scanner, rules, scope = {})
48
+ a = []
49
+ p = scanner.pos
50
+ while result = term_parser.parse(scanner, rules, scope)
51
+ p = scanner.pos
52
+ a << result
53
+ break unless sep_parser.parse(scanner, rules, scope)
54
+ end
55
+ scanner.pos = p
56
+ (capturing? ? a : true) if enough? a
57
+ end
58
+
59
+ def variable_capture_count?
60
+ true
61
+ end
62
+
63
+ end
64
+ end
@@ -16,7 +16,7 @@ module Rattler::Parsers
16
16
  # @author Jason Arhart
17
17
  #
18
18
  class Match < Parser
19
-
19
+
20
20
  # Create a new parser that matches with +re+.
21
21
  #
22
22
  # @param [Regexp] re the pattern to match
@@ -26,62 +26,27 @@ module Rattler::Parsers
26
26
  def self.[](re)
27
27
  self.new(:re => re)
28
28
  end
29
-
29
+
30
30
  # @private
31
31
  def self.parsed(results, *_) #:nodoc:
32
32
  self[eval(results.first)]
33
33
  end
34
-
34
+
35
35
  # If the +Regexp+ matches at the parse position, return the matched
36
36
  # string, otherwise return a false value.
37
37
  #
38
38
  # @param (see Parser#parse_labeled)
39
39
  #
40
40
  # @return the matched string, or +nil+
41
- def parse(scanner, rules, labeled = {})
41
+ def parse(scanner, rules, scope={})
42
42
  scanner.scan re
43
43
  end
44
-
44
+
45
45
  # @param (see Parser#with_ws)
46
46
  # @return (see Parser#with_ws)
47
47
  def with_ws(ws)
48
- Skip[ws] & self
49
- end
50
-
51
- # @private
52
- def re_optional #:nodoc:
53
- Match[/#{atomic_re.source}?/]
54
- end
55
-
56
- # @private
57
- def re_zero_or_more #:nodoc:
58
- Match[/#{atomic_re.source}*/]
59
- end
60
-
61
- # @private
62
- def re_one_or_more #:nodoc:
63
- Match[/#{atomic_re.source}+/]
48
+ ws.skip & self
64
49
  end
65
-
66
- # @private
67
- def assert_re #:nodoc:
68
- /(?=#{re.source})/
69
- end
70
-
71
- # @private
72
- def disallow_re #:nodoc:
73
- /(?!#{re.source})/
74
- end
75
-
76
- # @private
77
- def atomic_re #:nodoc:
78
- /(?>#{re.source})/
79
- end
80
-
81
- # @private
82
- def as_match #:nodoc:
83
- self
84
- end
85
-
50
+
86
51
  end
87
52
  end
@@ -0,0 +1,44 @@
1
+ #
2
+ # = rattler/parsers/node_code.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+
8
+ require 'rattler/parsers'
9
+
10
+ module Rattler::Parsers
11
+ # @private
12
+ class NodeCode #:nodoc:
13
+
14
+ def self.bindable_code(action)
15
+ self.new(action.target, action.method_name)
16
+ end
17
+
18
+ def initialize(target_name, method_name)
19
+ @target_name = target_name
20
+ @method_name = method_name
21
+ end
22
+
23
+ attr_reader :target_name, :method_name
24
+
25
+ def bind(scope, bind_args)
26
+ args = [array_expr(bind_args)]
27
+ if not scope.empty?
28
+ labeled = '{' + scope.map {|k, v| ":#{k} => #{v}"}.join(', ') + '}'
29
+ args << ":labeled => #{labeled}"
30
+ end
31
+ t = target_name == 'self' ? '' : "#{target_name}."
32
+ "#{t}#{method_name}(#{args.join ', '})"
33
+ end
34
+
35
+ def array_expr(bind_args)
36
+ if bind_args.respond_to? :to_str
37
+ bind_args
38
+ else
39
+ '[' + bind_args.join(', ') + ']'
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -16,12 +16,12 @@ module Rattler::Parsers
16
16
  #
17
17
  class OneOrMore < Parser
18
18
  include Combining
19
-
19
+
20
20
  # Parse using the wrapped parser repeatedly until it fails. If the
21
21
  # wrapped parser succeeds at least once return the results in an array,
22
22
  # or +true+ if the wrapped parser is not <tt>capturing?</tt>. Return
23
23
  # +false+ if the wrapped parser does not succeed at least once.
24
-
24
+
25
25
  # Parse using the decorated parser as many times as it succeeds. If it does
26
26
  # not succeeds at least once return +false+, otherwise the results in an
27
27
  # array, or +true+ if the decorated parser is not <tt>capturing?</tt>.
@@ -29,39 +29,19 @@ module Rattler::Parsers
29
29
  # @param (see Parser#parse_labeled)
30
30
  #
31
31
  # @return [Array, Boolean] an array containing the decorated parser's parse
32
- # returns, or +true+ if the decorated parser is not <tt>capturing?</tt>,
32
+ # results, or +true+ if the decorated parser is not <tt>capturing?</tt>,
33
33
  # or +false+ if the decorated parser does not succeed at least once.
34
- def parse(scanner, rules, labeled = {})
34
+ def parse(scanner, rules, scope = {})
35
35
  a = []
36
- while result = child.parse(scanner, rules)
36
+ while result = child.parse(scanner, rules, scope)
37
37
  a << result
38
38
  end
39
39
  (capturing? ? a : true) unless a.empty?
40
40
  end
41
-
41
+
42
42
  def variable_capture_count?
43
43
  true
44
44
  end
45
-
46
- # @private
47
- def token_optimized #:nodoc:
48
- to = super
49
- if Match === to.child
50
- to.child.re_one_or_more
51
- else
52
- to
53
- end
54
- end
55
-
56
- # @private
57
- def skip_optimized #:nodoc:
58
- to = super
59
- if Match === to.child
60
- to.child.re_one_or_more
61
- else
62
- to
63
- end
64
- end
65
-
45
+
66
46
  end
67
47
  end
@@ -15,7 +15,7 @@ module Rattler::Parsers
15
15
  #
16
16
  class Optional < Parser
17
17
  include Combining
18
-
18
+
19
19
  # Parse using the decorated parser and always succeed. If the decorated
20
20
  # parser is <tt>capturing?</tt> return the result in an array, or an empty
21
21
  # array if the wrapped parser fails. If the decorated parser is not
@@ -26,37 +26,17 @@ module Rattler::Parsers
26
26
  # @return [Array, true] an array containing the decorated parser's parse
27
27
  # results if it matches or an empty array if not, or always +true+ if the
28
28
  # decorated parser is not <tt>capturing?</tt>
29
- def parse(scanner, rules, labeled = {})
30
- if result = child.parse(scanner, rules)
29
+ def parse(scanner, rules, scope = {})
30
+ if result = child.parse(scanner, rules, scope)
31
31
  capturing? ? [result] : true
32
32
  else
33
33
  capturing? ? [] : true
34
34
  end
35
35
  end
36
-
36
+
37
37
  def variable_capture_count?
38
38
  true
39
39
  end
40
-
41
- # @private
42
- def token_optimized #:nodoc:
43
- to = super
44
- if Match === to.child
45
- to.child.re_optional
46
- else
47
- to
48
- end
49
- end
50
-
51
- # @private
52
- def skip_optimized #:nodoc:
53
- so = super
54
- if Match === so.child
55
- so.child.re_optional
56
- else
57
- so
58
- end
59
- end
60
-
40
+
61
41
  end
62
42
  end
@@ -14,12 +14,12 @@ module Rattler::Parsers
14
14
  # @author Jason Arhart
15
15
  #
16
16
  class Parser < Rattler::Util::Node
17
-
17
+
18
18
  # @private
19
19
  def self.parsed(*args) #:nodoc:
20
20
  self[*args]
21
21
  end
22
-
22
+
23
23
  # Return +true+ if the parser returns parse results on success, or
24
24
  # +false+ if the parser simply returns +true+ on success.
25
25
  #
@@ -28,11 +28,11 @@ module Rattler::Parsers
28
28
  def capturing?
29
29
  true
30
30
  end
31
-
31
+
32
32
  def variable_capture_count?
33
33
  false
34
34
  end
35
-
35
+
36
36
  # Return +true+ if the parser associates a label with parse results. Only
37
37
  # instances of +Label+ should return +true+.
38
38
  #
@@ -40,77 +40,49 @@ module Rattler::Parsers
40
40
  def labeled?
41
41
  false
42
42
  end
43
-
44
- # Parse and on success associate the label with the parse result if
45
- # +labeled?+ and +capturing?+.
46
- #
47
- # @param [StringScanner] scanner the scanner used match patterns
48
- # @param [Rules] rules the parse rules defining the parser
49
- # @param [Hash] labeled a hash for associating labels with children
50
- #
51
- # @return the parse result on success, or a false value on failure
52
- def parse_labeled(scanner, rules, labeled)
53
- parse(scanner, rules, labeled)
54
- end
55
-
43
+
56
44
  # @param [Parser] other the parser to try if this parser fails.
57
45
  # @return a new parser that tries this parser first and if it fails tries
58
46
  # +other+
59
47
  def |(other)
60
48
  Choice[self, other]
61
49
  end
62
-
50
+
63
51
  # @param [Parser] other the next parser to try if this parser succeeds.
64
52
  # @return a new parser that tries both this parser and +other+ and fails
65
53
  # unless both parse in sequence
66
54
  def &(other)
67
55
  Sequence[self, other]
68
56
  end
69
-
57
+
70
58
  # @return a new parser that tries this parser but returns +true+ if it
71
59
  # fails
72
60
  def optional
73
61
  Optional[self]
74
62
  end
75
-
63
+
76
64
  # @return a new parser that tries this parser until it fails and returns
77
65
  # all of the results
78
66
  def zero_or_more
79
67
  ZeroOrMore[self]
80
68
  end
81
-
69
+
82
70
  # @return a new parser that tries this parser until it fails and returns
83
71
  # all of the results if it succeeded at least once and fails otherwise
84
72
  def one_or_more
85
73
  OneOrMore[self]
86
74
  end
87
-
75
+
76
+ # @return a new parser that skips over what this parser matches
77
+ def skip
78
+ Skip[self]
79
+ end
80
+
88
81
  # @param [Parser] ws the parser used to skip whitespace
89
82
  # @return [Parser] a new parser that uses +ws+ to skip whitespace
90
83
  def with_ws(ws)
91
84
  self
92
85
  end
93
-
94
- # @return [Parser] a parser that parses identically but may have a more
95
- # optimized structure
96
- def optimized
97
- self
98
- end
99
-
100
- # @private
101
- def token_optimized #:nodoc:
102
- self
103
- end
104
-
105
- # @private
106
- def skip_optimized #:nodoc:
107
- self
108
- end
109
-
110
- # @private
111
- def as_match #:nodoc:
112
- nil
113
- end
114
-
86
+
115
87
  end
116
88
  end