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
@@ -8,16 +8,35 @@ module Rattler::BackEnd::ParserGenerator
8
8
  include TokenPropogating
9
9
  include SkipPropogating
10
10
 
11
- def gen_basic(label)
12
- generate label.child, :basic
11
+ def gen_basic(label, scope={})
12
+ generate label.child, :basic, scope
13
13
  end
14
14
 
15
- def gen_dispatch_action(label, target, method_name)
16
- generate label.child, :dispatch_action, target, method_name
15
+ def gen_dispatch_action(label, code, scope={})
16
+ generate label.child, :dispatch_action, code, scope
17
17
  end
18
18
 
19
- def gen_direct_action(label, code)
20
- generate label.child, :direct_action, code
19
+ def gen_direct_action_nested(label, code, scope={})
20
+ atomic_block { gen_direct_action_top_level label, code, scope }
21
+ end
22
+
23
+ def gen_direct_action_top_level(label, code, scope={})
24
+ scope = gen_capturing label.child, scope, label.label
25
+ (@g << ' &&').newline << '(' << code.bind(scope, [result_name]) << ')'
26
+ end
27
+
28
+ private
29
+
30
+ def gen_capturing(child, scope, label)
31
+ if child.capturing?
32
+ @g.surround("(#{result_name} = ", ')') do
33
+ generate child, :basic_nested, scope
34
+ end
35
+ scope.merge(label => result_name)
36
+ else
37
+ generate child, :intermediate, scope
38
+ scope
39
+ end
21
40
  end
22
41
 
23
42
  end
@@ -8,16 +8,16 @@ module Rattler::BackEnd::ParserGenerator
8
8
  include NestedSubGenerating
9
9
  include PredicatePropogating
10
10
 
11
- def gen_skip_top_level(list)
11
+ def gen_skip_top_level(list, scope={})
12
12
  (@g << "#{result_name} = false").newline
13
13
  (@g << "#{saved_pos_name} = nil").newline
14
14
  @g << 'while '
15
- generate list.child, :intermediate_skip
15
+ generate list.child, :intermediate_skip, scope
16
16
  @g.block '' do
17
17
  (@g << "#{result_name} = true").newline
18
18
  (@g << "#{saved_pos_name} = @scanner.pos").newline
19
19
  @g << 'break unless '
20
- generate list.sep_parser, :intermediate_skip
20
+ generate list.sep_parser, :intermediate_skip, scope
21
21
  end.newline
22
22
  @g << "@scanner.pos = #{saved_pos_name} unless #{saved_pos_name}.nil?"
23
23
  @g.newline << result_name
@@ -44,12 +44,12 @@ module Rattler::BackEnd::ParserGenerator
44
44
  class TopLevelList1Generator < List1Generator #:nodoc:
45
45
  include TopLevel
46
46
 
47
- def gen_assert(parser)
48
- generate parser.child, :assert_top_level
47
+ def gen_assert(parser, scope = {})
48
+ generate parser.child, :assert_top_level, scope
49
49
  end
50
50
 
51
- def gen_disallow(parser)
52
- generate parser.child, :disallow_top_level
51
+ def gen_disallow(parser, scope = {})
52
+ generate parser.child, :disallow_top_level, scope
53
53
  end
54
54
 
55
55
  end
@@ -4,55 +4,54 @@ module Rattler::BackEnd::ParserGenerator
4
4
  # @private
5
5
  module ListGenerating #:nodoc:
6
6
 
7
- def gen_basic_nested(list)
8
- atomic_block { gen_basic_top_level list }
7
+ def gen_basic_nested(list, scope={})
8
+ atomic_block { gen_basic_top_level list, scope }
9
9
  end
10
10
 
11
- def gen_basic_top_level(list)
12
- list.capturing? ? gen_capturing(list) : gen_skip_top_level(list)
11
+ def gen_basic_top_level(list, scope={})
12
+ list.capturing? ? gen_capturing(list, scope) : gen_skip_top_level(list, scope)
13
13
  end
14
14
 
15
- def gen_dispatch_action_nested(list, target, method_name)
15
+ def gen_dispatch_action_nested(list, code, scope={})
16
16
  atomic_block do
17
- gen_dispatch_action_top_level list, target, method_name
17
+ gen_dispatch_action_top_level list, code, scope
18
18
  end
19
19
  end
20
20
 
21
- def gen_dispatch_action_top_level(list, target, method_name)
22
- gen_capturing list do |a|
23
- dispatch_action_result target, method_name,
24
- :array_expr => "select_captures(#{a})"
21
+ def gen_dispatch_action_top_level(list, code, scope={})
22
+ gen_capturing list, scope do |a|
23
+ code.bind scope, "select_captures(#{a})"
25
24
  end
26
25
  end
27
26
 
28
- def gen_direct_action_nested(list, action)
27
+ def gen_direct_action_nested(list, code, scope={})
29
28
  atomic_block do
30
- gen_direct_action_top_level list, action
29
+ gen_direct_action_top_level list, code, scope
31
30
  end
32
31
  end
33
32
 
34
- def gen_direct_action_top_level(list, action)
35
- gen_capturing list do |a|
36
- direct_action_result action, :bind_args => ["select_captures(#{a})"]
33
+ def gen_direct_action_top_level(list, code, scope={})
34
+ gen_capturing list, scope do |a|
35
+ '(' + code.bind(scope, ["select_captures(#{a})"]) + ')'
37
36
  end
38
37
  end
39
38
 
40
- def gen_skip_nested(list)
41
- atomic_block { gen_skip_top_level list }
39
+ def gen_skip_nested(list, scope={})
40
+ atomic_block { gen_skip_top_level list, scope }
42
41
  end
43
42
 
44
43
  protected
45
44
 
46
- def gen_capturing(list)
45
+ def gen_capturing(list, scope={})
47
46
  (@g << "#{accumulator_name} = []").newline
48
47
  (@g << "#{saved_pos_name} = nil").newline
49
48
  @g << "while #{result_name} = "
50
- generate list.child, :basic
49
+ generate list.child, :basic, scope
51
50
  @g.block '' do
52
51
  (@g << "#{saved_pos_name} = @scanner.pos").newline
53
52
  (@g << "#{accumulator_name} << #{result_name}").newline
54
53
  @g << 'break unless '
55
- generate list.sep_parser, :intermediate_skip
54
+ generate list.sep_parser, :intermediate_skip, scope
56
55
  end.newline
57
56
  @g << "@scanner.pos = #{saved_pos_name} unless #{saved_pos_name}.nil?"
58
57
  @g.newline
@@ -7,22 +7,22 @@ module Rattler::BackEnd::ParserGenerator
7
7
  include ListGenerating
8
8
  include NestedSubGenerating
9
9
 
10
- def gen_assert(optional)
10
+ def gen_assert(optional, scope={})
11
11
  @g << 'true'
12
12
  end
13
13
 
14
- def gen_disallow(optional)
14
+ def gen_disallow(optional, scope={})
15
15
  @g << 'false'
16
16
  end
17
17
 
18
- def gen_skip_top_level(list)
18
+ def gen_skip_top_level(list, scope={})
19
19
  (@g << "#{saved_pos_name} = nil").newline
20
20
  @g << 'while '
21
- generate list.child, :intermediate_skip
21
+ generate list.child, :intermediate_skip, scope
22
22
  @g.block '' do
23
23
  (@g << "#{saved_pos_name} = @scanner.pos").newline
24
24
  @g << 'break unless '
25
- generate list.sep_parser, :intermediate_skip
25
+ generate list.sep_parser, :intermediate_skip, scope
26
26
  end.newline
27
27
  @g << "@scanner.pos = #{saved_pos_name} unless #{saved_pos_name}.nil?"
28
28
  @g.newline << true
@@ -1,93 +1,93 @@
1
1
  require 'rattler/back_end/parser_generator'
2
2
 
3
3
  module Rattler::BackEnd::ParserGenerator
4
-
4
+
5
5
  # @private
6
6
  class MatchGenerator < ExprGenerator #:nodoc:
7
-
8
- def gen_basic(match)
7
+
8
+ def gen_basic(match, scope={})
9
9
  @g << "@scanner.scan(#{match.re.inspect})"
10
10
  end
11
-
12
- def gen_assert_nested(match)
13
- atomic_expr { gen_assert_top_level match }
11
+
12
+ def gen_assert_nested(match, scope={})
13
+ atomic_expr { gen_assert_top_level match, scope }
14
14
  end
15
-
16
- def gen_assert_top_level(match)
17
- gen_intermediate_assert match
15
+
16
+ def gen_assert_top_level(match, scope={})
17
+ gen_intermediate_assert match, scope
18
18
  @g << ' && true'
19
19
  end
20
-
21
- def gen_disallow_nested(match)
22
- atomic_expr { gen_disallow_top_level match }
20
+
21
+ def gen_disallow_nested(match, scope={})
22
+ atomic_expr { gen_disallow_top_level match, scope }
23
23
  end
24
-
25
- def gen_disallow_top_level(match)
26
- gen_intermediate_disallow match
24
+
25
+ def gen_disallow_top_level(match, scope={})
26
+ gen_intermediate_disallow match, scope
27
27
  @g << ' && true'
28
28
  end
29
-
30
- def gen_dispatch_action_nested(match, target, method_name)
31
- atomic_block { gen_dispatch_action_top_level match, target, method_name }
29
+
30
+ def gen_dispatch_action_nested(match, code, scope={})
31
+ atomic_block { gen_dispatch_action_top_level match, code, scope }
32
32
  end
33
-
34
- def gen_dispatch_action_top_level(match, target, method_name)
35
- @g.surround("(#{result_name} = ", ')') { gen_basic match }
36
- (@g << ' &&').newline << dispatch_action_result(target, method_name)
33
+
34
+ def gen_dispatch_action_top_level(match, code, scope={})
35
+ @g.surround("(#{result_name} = ", ')') { gen_basic match, scope }
36
+ (@g << ' &&').newline << code.bind(scope, "[#{result_name}]")
37
37
  end
38
-
39
- def gen_direct_action_nested(match, code)
40
- atomic_block { gen_direct_action_top_level match, code }
38
+
39
+ def gen_direct_action_nested(match, code, scope={})
40
+ atomic_block { gen_direct_action_top_level match, code, scope }
41
41
  end
42
-
43
- def gen_direct_action_top_level(match, code)
44
- @g.surround("(#{result_name} = ", ')') { gen_basic match }
45
- (@g << ' &&').newline << direct_action_result(code)
42
+
43
+ def gen_direct_action_top_level(match, code, scope={})
44
+ @g.surround("(#{result_name} = ", ')') { gen_basic match, scope }
45
+ (@g << ' &&').newline << '(' << code.bind(scope, [result_name]) << ')'
46
46
  end
47
-
48
- def gen_token(match)
49
- gen_basic match
47
+
48
+ def gen_token(match, scope={})
49
+ gen_basic match, scope
50
50
  end
51
-
52
- def gen_skip_nested(match)
53
- atomic_expr { gen_skip_top_level match }
51
+
52
+ def gen_skip_nested(match, scope={})
53
+ atomic_expr { gen_skip_top_level match, scope }
54
54
  end
55
-
56
- def gen_skip_top_level(match)
57
- gen_intermediate_skip match
55
+
56
+ def gen_skip_top_level(match, scope={})
57
+ gen_intermediate_skip match, scope
58
58
  @g << ' && true'
59
59
  end
60
-
61
- def gen_intermediate_assert(match)
62
- @g << "@scanner.skip(#{match.assert_re.inspect})"
60
+
61
+ def gen_intermediate_assert(match, scope={})
62
+ @g << "@scanner.skip(#{/(?=#{match.re.source})/.inspect})"
63
63
  end
64
-
65
- def gen_intermediate_disallow(match)
66
- @g << "@scanner.skip(#{match.disallow_re.inspect})"
64
+
65
+ def gen_intermediate_disallow(match, scope={})
66
+ @g << "@scanner.skip(#{/(?!#{match.re.source})/.inspect})"
67
67
  end
68
-
69
- def gen_intermediate_skip(match)
68
+
69
+ def gen_intermediate_skip(match, scope={})
70
70
  @g << "@scanner.skip(#{match.re.inspect})"
71
71
  end
72
-
72
+
73
73
  end
74
-
74
+
75
75
  # @private
76
76
  class NestedMatchGenerator < MatchGenerator #:nodoc:
77
77
  include Nested
78
78
  end
79
-
79
+
80
80
  def MatchGenerator.nested(*args)
81
81
  NestedMatchGenerator.new(*args)
82
82
  end
83
-
83
+
84
84
  # @private
85
85
  class TopLevelMatchGenerator < MatchGenerator #:nodoc:
86
86
  include TopLevel
87
87
  end
88
-
88
+
89
89
  def MatchGenerator.top_level(*args)
90
90
  TopLevelMatchGenerator.new(*args)
91
91
  end
92
-
92
+
93
93
  end
@@ -8,10 +8,10 @@ module Rattler::BackEnd::ParserGenerator
8
8
  include NestedSubGenerating
9
9
  include PredicatePropogating
10
10
 
11
- def gen_skip_top_level(one_or_more)
11
+ def gen_skip_top_level(one_or_more, scope={})
12
12
  (@g << "#{result_name} = false").newline
13
13
  @g << 'while '
14
- generate one_or_more.child, :intermediate_skip
14
+ generate one_or_more.child, :intermediate_skip, scope
15
15
  @g.block('') { @g << "#{result_name} = true" }.newline
16
16
  @g << result_name
17
17
  end
@@ -37,12 +37,12 @@ module Rattler::BackEnd::ParserGenerator
37
37
  class TopLevelOneOrMoreGenerator < OneOrMoreGenerator #:nodoc:
38
38
  include TopLevel
39
39
 
40
- def gen_assert(parser)
41
- generate parser.child, :assert_top_level
40
+ def gen_assert(parser, scope = {})
41
+ generate parser.child, :assert_top_level, scope
42
42
  end
43
43
 
44
- def gen_disallow(parser)
45
- generate parser.child, :disallow_top_level
44
+ def gen_disallow(parser, scope = {})
45
+ generate parser.child, :disallow_top_level, scope
46
46
  end
47
47
 
48
48
  end
@@ -6,74 +6,75 @@ module Rattler::BackEnd::ParserGenerator
6
6
  class OptionalGenerator < ExprGenerator #:nodoc:
7
7
  include NestedSubGenerating
8
8
 
9
- def gen_basic_nested(optional)
10
- atomic_expr { gen_basic_top_level optional }
9
+ def gen_basic_nested(optional, scope={})
10
+ atomic_expr { gen_basic_top_level optional, scope }
11
11
  end
12
12
 
13
- def gen_basic_top_level(optional)
13
+ def gen_basic_top_level(optional, scope={})
14
14
  if optional.capturing?
15
- @g.surround("(#{result_name} = ", ')') { generate optional.child }
15
+ @g.surround("(#{result_name} = ", ')') do
16
+ generate optional.child, :basic, scope
17
+ end
16
18
  @g << " ? [#{result_name}] : []"
17
19
  else
18
- gen_skip_top_level optional
20
+ gen_skip_top_level optional, scope
19
21
  end
20
22
  end
21
23
 
22
- def gen_assert(optional)
24
+ def gen_assert(optional, scope={})
23
25
  @g << 'true'
24
26
  end
25
27
 
26
- def gen_disallow(optional)
28
+ def gen_disallow(optional, scope={})
27
29
  @g << 'false'
28
30
  end
29
31
 
30
- def gen_dispatch_action_nested(optional, target, method_name)
31
- atomic_block { gen_dispatch_action_top_level optional, target, method_name }
32
+ def gen_dispatch_action_nested(optional, code, scope={})
33
+ atomic_block { gen_dispatch_action_top_level optional, code, scope }
32
34
  end
33
35
 
34
- def gen_dispatch_action_top_level(optional, target, method_name)
36
+ def gen_dispatch_action_top_level(optional, code, scope={})
35
37
  @g << "#{result_name} = "
36
- generate optional.child
37
- @g.newline << dispatch_action_result(target, method_name,
38
- :array_expr => "#{result_name} ? [#{result_name}] : []")
38
+ generate optional.child, :basic, scope
39
+ @g.newline << code.bind(scope, "#{result_name} ? [#{result_name}] : []")
39
40
  end
40
41
 
41
- def gen_direct_action_nested(optional, action)
42
- atomic_block { gen_direct_action_top_level optional, action }
42
+ def gen_direct_action_nested(optional, code, scope={})
43
+ atomic_block { gen_direct_action_top_level optional, code, scope }
43
44
  end
44
45
 
45
- def gen_direct_action_top_level(optional, action)
46
+ def gen_direct_action_top_level(optional, code, scope={})
46
47
  @g << "#{result_name} = "
47
- generate optional.child
48
- @g.newline << direct_action_result(action,
49
- :bind_args => ["(#{result_name} ? [#{result_name}] : [])"])
48
+ generate optional.child, :basic, scope
49
+ @g.newline <<
50
+ '(' << code.bind(scope, ["(#{result_name} ? [#{result_name}] : [])"]) << ')'
50
51
  end
51
52
 
52
- def gen_token_nested(optional)
53
- atomic_block { gen_token_top_level optional }
53
+ def gen_token_nested(optional, scope={})
54
+ atomic_block { gen_token_top_level optional, scope }
54
55
  end
55
56
 
56
- def gen_token_top_level(optional)
57
- generate optional.child, :token
57
+ def gen_token_top_level(optional, scope={})
58
+ generate optional.child, :token, scope
58
59
  @g << " || ''"
59
60
  end
60
61
 
61
- def gen_skip_nested(optional)
62
- atomic_block { gen_skip_top_level optional }
62
+ def gen_skip_nested(optional, scope={})
63
+ atomic_block { gen_skip_top_level optional, scope }
63
64
  end
64
65
 
65
- def gen_skip_top_level(optional)
66
- generate optional.child, :intermediate_skip
66
+ def gen_skip_top_level(optional, scope={})
67
+ generate optional.child, :intermediate_skip, scope
67
68
  @g.newline << 'true'
68
69
  end
69
70
 
70
71
  private
71
72
 
72
- def gen_capturing(optional)
73
+ def gen_capturing(optional, scope={})
73
74
  if optional.capturing?
74
75
  yield
75
76
  else
76
- gen_skip_top_level optional
77
+ gen_skip_top_level optional, scope
77
78
  end
78
79
  end
79
80