rattler 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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