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
@@ -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