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
@@ -0,0 +1,38 @@
1
+ #
2
+ # = rattler/back_end/optimizer/simplify_token_match.rb
3
+ #
4
+ # Author:: Jason Arhart
5
+ # Documentation:: Author
6
+ #
7
+ require 'rattler'
8
+
9
+ module Rattler::BackEnd::Optimizer
10
+ #
11
+ # A token wrapping a terminal parser is redundant.
12
+ #
13
+ # @author Jason Arhart
14
+ #
15
+ class SimplifyTokenMatch < Optimization
16
+
17
+ include Rattler::Parsers
18
+
19
+ protected
20
+
21
+ def _applies_to?(parser, context)
22
+ parser.is_a? Token and
23
+ terminal? parser.child
24
+ end
25
+
26
+ def _apply(parser, context)
27
+ parser.child
28
+ end
29
+
30
+ def terminal?(parser)
31
+ case parser
32
+ when Match, Token, BackReference then true
33
+ else false
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -14,6 +14,7 @@ module Rattler::BackEnd
14
14
  #
15
15
  module ParserGenerator
16
16
 
17
+ autoload :RuleSetGenerator, 'rattler/back_end/parser_generator/rule_set_generator'
17
18
  autoload :RuleGenerator, 'rattler/back_end/parser_generator/rule_generator'
18
19
  autoload :ExprGenerator, 'rattler/back_end/parser_generator/expr_generator'
19
20
  autoload :GeneratorHelper, 'rattler/back_end/parser_generator/generator_helper'
@@ -39,12 +40,15 @@ module Rattler::BackEnd
39
40
  autoload :TokenGenerator, 'rattler/back_end/parser_generator/token_generator'
40
41
  autoload :SkipGenerator, 'rattler/back_end/parser_generator/skip_generator'
41
42
  autoload :LabelGenerator, 'rattler/back_end/parser_generator/label_generator'
43
+ autoload :BackReferenceGenerator, 'rattler/back_end/parser_generator/back_reference_generator'
42
44
  autoload :FailGenerator, 'rattler/back_end/parser_generator/fail_generator'
43
45
  autoload :RepeatGenerating, 'rattler/back_end/parser_generator/repeat_generating'
44
46
  autoload :ListGenerating, 'rattler/back_end/parser_generator/list_generating'
45
47
  autoload :PredicatePropogating, 'rattler/back_end/parser_generator/predicate_propogating'
46
48
  autoload :TokenPropogating, 'rattler/back_end/parser_generator/token_propogating'
47
49
  autoload :SkipPropogating, 'rattler/back_end/parser_generator/skip_propogating'
50
+ autoload :GroupMatchGenerator, 'rattler/back_end/parser_generator/group_match_generator'
51
+ autoload :GroupMatch, 'rattler/back_end/parser_generator/group_match'
48
52
  autoload :GEN_METHOD_NAMES, 'rattler/back_end/parser_generator/gen_method_names'
49
53
 
50
54
  # Generate parsing code for a parser model using a ruby generator +g+.
@@ -52,50 +56,53 @@ module Rattler::BackEnd
52
56
  # @overload generate(g, grammar)
53
57
  # @param [RubyGenerator] g the ruby generator to use
54
58
  # @param [Rattler::Grammar::Grammar] grammar the grammar model
55
- # @return nil
59
+ # @return g
56
60
  #
57
61
  # @overload generate(g, rules)
58
62
  # @param [RubyGenerator] g the ruby generator to use
59
63
  # @param [Rules] rules the parse rules
60
- # @return nil
64
+ # @return g
61
65
  #
62
66
  # @overload generate(g, rule)
63
67
  # @param [RubyGenerator] g the ruby generator to use
64
68
  # @param [Rule] rule the parse rule
65
- # @return nil
69
+ # @return g
66
70
  #
67
71
  # @overload generate(g, parser)
68
72
  # @param [RubyGenerator] g the ruby generator to use
69
73
  # @param [Parser] parser the parser model
70
- # @return nil
74
+ # @return g
71
75
  #
72
- def self.generate(g, parser)
73
- RuleGenerator.new(g).generate(parser)
74
- nil
76
+ def self.generate(g, parser, opts={})
77
+ unless opts[:no_optimize]
78
+ parser = ::Rattler::BackEnd::Optimizer.optimize(parser, opts)
79
+ end
80
+ RuleSetGenerator.new(g).generate(parser, opts)
81
+ g
75
82
  end
76
83
 
77
84
  # Generate parsing code for +parser+ using a new {RubyGenerator} with the
78
85
  # given options and return the generated code.
79
86
  #
80
- # @overload code_for(grammar, options)
87
+ # @overload code_for(grammar, opts)
81
88
  # @param [Rattler::Grammar::Grammar] grammar the grammar model
82
89
  # @return [String] the generated code
83
90
  #
84
- # @overload code_for(rules, options)
91
+ # @overload code_for(rules, opts)
85
92
  # @param [Rules] rules the parse rules
86
93
  # @return [String] the generated code
87
94
  #
88
- # @overload code_for(rule, options)
95
+ # @overload code_for(rule, opts)
89
96
  # @param [Rule] rule the parse rule
90
97
  # @return [String] the generated code
91
98
  #
92
- # @overload code_for(parser, options)
99
+ # @overload code_for(parser, opts)
93
100
  # @param [Parser] parser the parser model
94
101
  # @return [String] the generated code
95
102
  #
96
- def self.code_for(parser, options={})
97
- ::Rattler::BackEnd::RubyGenerator.code(options) {|g| generate(g, parser) }
103
+ def self.code_for(parser, opts={})
104
+ ::Rattler::BackEnd::RubyGenerator.code(opts) {|g| generate g, parser, opts }
98
105
  end
99
106
 
100
107
  end
101
- end
108
+ end
@@ -1,87 +1,87 @@
1
1
  require 'rattler/back_end/parser_generator'
2
2
 
3
3
  module Rattler::BackEnd::ParserGenerator
4
-
4
+
5
5
  # @private
6
6
  class ApplyGenerator < ExprGenerator #:nodoc:
7
-
8
- def gen_basic(apply)
7
+
8
+ def gen_basic(apply, scope={})
9
9
  @g << "match(:#{apply.rule_name})"
10
10
  end
11
-
12
- def gen_assert_nested(apply)
11
+
12
+ def gen_assert_nested(apply, scope={})
13
13
  atomic_block { gen_assert_top_level apply }
14
14
  end
15
-
16
- def gen_assert_top_level(apply)
15
+
16
+ def gen_assert_top_level(apply, scope={})
17
17
  lookahead do
18
18
  @g.surround("#{result_name} = (", ')') { gen_skip_top_level apply }
19
19
  @g.newline
20
20
  end
21
21
  @g << result_name
22
22
  end
23
-
24
- def gen_disallow_nested(apply)
23
+
24
+ def gen_disallow_nested(apply, scope={})
25
25
  atomic_block { gen_disallow_top_level apply }
26
26
  end
27
-
28
- def gen_disallow_top_level(apply)
27
+
28
+ def gen_disallow_top_level(apply, scope={})
29
29
  lookahead do
30
30
  @g.surround("#{result_name} = !", '') { gen_basic_nested apply }
31
31
  @g.newline
32
32
  end
33
33
  @g << result_name
34
34
  end
35
-
36
- def gen_dispatch_action_nested(apply, target, method_name)
37
- atomic_expr { gen_dispatch_action_top_level apply, target, method_name }
35
+
36
+ def gen_dispatch_action_nested(apply, code, scope={})
37
+ atomic_expr { gen_dispatch_action_top_level apply, code }
38
38
  end
39
-
40
- def gen_dispatch_action_top_level(apply, target, method_name)
39
+
40
+ def gen_dispatch_action_top_level(apply, code, scope={})
41
41
  @g.surround("(#{result_name} = ", ')') { gen_basic apply }
42
- @g << ' && ' << dispatch_action_result(target, method_name)
42
+ @g << ' && ' << code.bind(scope, "[#{result_name}]")
43
43
  end
44
-
45
- def gen_direct_action_nested(apply, action)
46
- atomic_expr { gen_direct_action_top_level apply, action }
44
+
45
+ def gen_direct_action_nested(apply, code, scope={})
46
+ atomic_expr { gen_direct_action_top_level apply, code }
47
47
  end
48
-
49
- def gen_direct_action_top_level(apply, action)
48
+
49
+ def gen_direct_action_top_level(apply, code, scope={})
50
50
  @g.surround("(#{result_name} = ", ')') { gen_basic apply }
51
- @g << ' && ' << direct_action_result(action)
51
+ @g << ' && (' << code.bind(scope, [result_name]) << ')'
52
52
  end
53
-
54
- def gen_skip_nested(apply)
53
+
54
+ def gen_skip_nested(apply, scope={})
55
55
  atomic_expr { gen_skip_top_level apply }
56
56
  end
57
-
58
- def gen_skip_top_level(apply)
57
+
58
+ def gen_skip_top_level(apply, scope={})
59
59
  gen_intermediate_skip apply
60
60
  @g << ' && true'
61
61
  end
62
-
63
- def gen_intermediate_skip(apply)
62
+
63
+ def gen_intermediate_skip(apply, scope={})
64
64
  gen_basic apply
65
65
  end
66
-
66
+
67
67
  end
68
-
68
+
69
69
  # @private
70
70
  class NestedApplyGenerator < ApplyGenerator #:nodoc:
71
71
  include Nested
72
72
  end
73
-
73
+
74
74
  def ApplyGenerator.nested(*args)
75
75
  NestedApplyGenerator.new(*args)
76
76
  end
77
-
77
+
78
78
  # @private
79
79
  class TopLevelApplyGenerator < ApplyGenerator #:nodoc:
80
80
  include TopLevel
81
81
  end
82
-
82
+
83
83
  def ApplyGenerator.top_level(*args)
84
84
  TopLevelApplyGenerator.new(*args)
85
85
  end
86
-
86
+
87
87
  end
@@ -5,67 +5,66 @@ module Rattler::BackEnd::ParserGenerator
5
5
  # @private
6
6
  class AssertGenerator < ExprGenerator #:nodoc:
7
7
 
8
- def gen_basic(assert)
9
- generate assert.child, :assert
8
+ def gen_basic(assert, scope={})
9
+ generate assert.child, :assert, scope
10
10
  end
11
11
 
12
- def gen_assert(assert)
13
- gen_basic assert
12
+ def gen_assert(assert, scope={})
13
+ gen_basic assert, scope
14
14
  end
15
15
 
16
- def gen_disallow(assert)
16
+ def gen_disallow(assert, scope={})
17
17
  @g << 'false'
18
18
  end
19
19
 
20
- def gen_skip_nested(assert)
21
- gen_basic_nested assert
20
+ def gen_skip_nested(assert, scope={})
21
+ gen_basic_nested assert, scope
22
22
  end
23
23
 
24
- def gen_skip_top_level(assert)
25
- gen_basic_top_level assert
24
+ def gen_skip_top_level(assert, scope={})
25
+ gen_basic_top_level assert, scope
26
26
  end
27
27
 
28
- def gen_dispatch_action_nested(assert, target, method_name)
29
- atomic_block { gen_dispatch_action_top_level assert, target, method_name }
28
+ def gen_dispatch_action_nested(assert, code, scope={})
29
+ atomic_block { gen_dispatch_action_top_level assert, code, scope }
30
30
  end
31
31
 
32
- def gen_dispatch_action_top_level(assert, target, method_name)
33
- gen_action assert,
34
- dispatch_action_result(target, method_name, :array_expr => '[]')
32
+ def gen_dispatch_action_top_level(assert, code, scope={})
33
+ gen_action assert, code.bind(scope, '[]'), scope
35
34
  end
36
35
 
37
- def gen_direct_action_nested(assert, code)
38
- atomic_block { gen_direct_action_top_level assert, code }
36
+ def gen_direct_action_nested(assert, code, scope={})
37
+ atomic_block { gen_direct_action_top_level assert, code, scope }
39
38
  end
40
39
 
41
- def gen_direct_action_top_level(assert, code)
42
- gen_action assert, direct_action_result(code)
40
+ def gen_direct_action_top_level(assert, code, scope={})
41
+ gen_action assert, "(#{code.bind scope, []})", scope
43
42
  end
44
43
 
45
- def gen_token_nested(assert)
46
- atomic_block { gen_token_top_level assert }
44
+ def gen_token_nested(assert, scope={})
45
+ atomic_block { gen_token_top_level assert, scope }
47
46
  end
48
47
 
49
- def gen_token_top_level(assert)
50
- gen_action assert, "''"
48
+ def gen_token_top_level(assert, scope={})
49
+ gen_action assert, "''", scope
51
50
  end
52
51
 
53
- def gen_intermediate(assert)
54
- generate assert.child, :intermediate_assert
52
+ def gen_intermediate(assert, scope={})
53
+ generate assert.child, :intermediate_assert, scope
55
54
  end
56
55
 
57
- def gen_intermediate_assert(assert)
58
- gen_intermediate assert
56
+ def gen_intermediate_assert(assert, scope={})
57
+ gen_intermediate assert, scope
59
58
  end
60
59
 
61
- def gen_intermediate_skip(assert)
62
- gen_intermediate assert
60
+ def gen_intermediate_skip(assert, scope={})
61
+ gen_intermediate assert, scope
63
62
  end
64
63
 
65
64
  private
66
65
 
67
- def gen_action(assert, result_code)
68
- gen_intermediate assert
66
+ def gen_action(assert, result_code, scope={})
67
+ gen_intermediate assert, scope
69
68
  (@g << ' &&').newline << result_code
70
69
  end
71
70
 
@@ -0,0 +1,93 @@
1
+ require 'rattler/back_end/parser_generator'
2
+
3
+ module Rattler::BackEnd::ParserGenerator
4
+
5
+ # @private
6
+ class BackReferenceGenerator < ExprGenerator #:nodoc:
7
+
8
+ def gen_basic(ref, scope={})
9
+ @g << "@scanner.scan(#{ref.re_expr(scope)})"
10
+ end
11
+
12
+ def gen_assert_nested(ref, scope={})
13
+ atomic_expr { gen_assert_top_level ref, scope }
14
+ end
15
+
16
+ def gen_assert_top_level(ref, scope={})
17
+ gen_intermediate_assert ref, scope
18
+ @g << ' && true'
19
+ end
20
+
21
+ def gen_disallow_nested(ref, scope={})
22
+ atomic_expr { gen_disallow_top_level ref, scope }
23
+ end
24
+
25
+ def gen_disallow_top_level(ref, scope={})
26
+ gen_intermediate_disallow ref, scope
27
+ @g << ' && true'
28
+ end
29
+
30
+ def gen_dispatch_action_nested(ref, code, scope={})
31
+ atomic_block { gen_dispatch_action_top_level ref, code, scope }
32
+ end
33
+
34
+ def gen_dispatch_action_top_level(ref, code, scope={})
35
+ @g.surround("(#{result_name} = ", ')') { gen_basic ref, scope }
36
+ (@g << ' &&').newline << code.bind(scope, "[#{result_name}]")
37
+ end
38
+
39
+ def gen_direct_action_nested(ref, code, scope={})
40
+ atomic_block { gen_direct_action_top_level ref, code, scope }
41
+ end
42
+
43
+ def gen_direct_action_top_level(ref, code, scope={})
44
+ @g.surround("(#{result_name} = ", ')') { gen_basic ref, scope }
45
+ (@g << ' &&').newline << '(' << code.bind(scope, [result_name]) << ')'
46
+ end
47
+
48
+ def gen_token(ref, scope={})
49
+ gen_basic ref, scope
50
+ end
51
+
52
+ def gen_skip_nested(ref, scope={})
53
+ atomic_expr { gen_skip_top_level ref, scope }
54
+ end
55
+
56
+ def gen_skip_top_level(ref, scope={})
57
+ gen_intermediate_skip ref, scope
58
+ @g << ' && true'
59
+ end
60
+
61
+ def gen_intermediate_assert(ref, scope={})
62
+ @g << "@scanner.skip(/(?=#{ref.re_source(scope)})/)"
63
+ end
64
+
65
+ def gen_intermediate_disallow(ref, scope={})
66
+ @g << "@scanner.skip(/(?!#{ref.re_source(scope)})/)"
67
+ end
68
+
69
+ def gen_intermediate_skip(ref, scope={})
70
+ @g << "@scanner.skip(#{ref.re_expr(scope)})"
71
+ end
72
+
73
+ end
74
+
75
+ # @private
76
+ class NestedBackReferenceGenerator < BackReferenceGenerator #:nodoc:
77
+ include Nested
78
+ end
79
+
80
+ def BackReferenceGenerator.nested(*args)
81
+ NestedBackReferenceGenerator.new(*args)
82
+ end
83
+
84
+ # @private
85
+ class TopLevelBackReferenceGenerator < BackReferenceGenerator #:nodoc:
86
+ include TopLevel
87
+ end
88
+
89
+ def BackReferenceGenerator.top_level(*args)
90
+ TopLevelBackReferenceGenerator.new(*args)
91
+ end
92
+
93
+ end
@@ -6,100 +6,84 @@ module Rattler::BackEnd::ParserGenerator
6
6
  class ChoiceGenerator < ExprGenerator #:nodoc:
7
7
  include NestedSubGenerating
8
8
 
9
- def gen_basic_nested(choice)
10
- atomic_block { gen_basic_top_level choice }
9
+ def gen_basic_nested(choice, scope={})
10
+ atomic_block { gen_basic_top_level choice, scope }
11
11
  end
12
12
 
13
- def gen_basic_top_level(choice)
14
- @g.intersperse_nl(choice, ' ||') {|_| generate _ }
13
+ def gen_basic_top_level(choice, scope={})
14
+ @g.intersperse_nl(choice, ' ||') {|_| generate _, :basic, scope }
15
15
  end
16
16
 
17
- def gen_assert_nested(choice)
18
- atomic_expr { gen_assert_top_level choice }
17
+ def gen_assert_nested(choice, scope={})
18
+ atomic_expr { gen_assert_top_level choice, scope }
19
19
  end
20
20
 
21
- def gen_assert_top_level(choice)
22
- gen_intermediate_assert choice
21
+ def gen_assert_top_level(choice, scope={})
22
+ gen_intermediate_assert choice, scope
23
23
  @g << ' && true'
24
24
  end
25
25
 
26
- def gen_disallow(choice)
26
+ def gen_disallow(choice, scope={})
27
27
  @g << '!'
28
- gen_intermediate_assert choice
28
+ gen_intermediate_assert choice, scope
29
29
  end
30
30
 
31
- def gen_dispatch_action_nested(choice, target, method_name)
32
- atomic_block { gen_dispatch_action_top_level choice, target, method_name }
31
+ def gen_dispatch_action_nested(choice, code, scope={})
32
+ atomic_block { gen_dispatch_action_top_level choice, code, scope }
33
33
  end
34
34
 
35
- def gen_dispatch_action_top_level(choice, target, method_name)
36
- gen_action_code choice do |labeled|
37
- dispatch_action_result(target, method_name, :labeled => labeled)
38
- end
35
+ def gen_dispatch_action_top_level(choice, code, scope={})
36
+ gen_action_code(choice) { code.bind scope, "[#{result_name}]" }
39
37
  end
40
38
 
41
- def gen_direct_action_nested(choice, action)
42
- atomic_block { gen_direct_action_top_level choice, action }
39
+ def gen_direct_action_nested(choice, code, scope={})
40
+ atomic_block { gen_direct_action_top_level choice, code }
43
41
  end
44
42
 
45
- def gen_direct_action_top_level(choice, action)
46
- gen_action_code choice do |labeled|
47
- direct_action_result(action, :labeled => labeled)
48
- end
43
+ def gen_direct_action_top_level(choice, code, scope={})
44
+ gen_action_code(choice) { "(#{code.bind scope, [result_name]})" }
49
45
  end
50
46
 
51
- def gen_token_nested(choice)
52
- atomic_block { gen_token_top_level choice }
47
+ def gen_token_nested(choice, scope={})
48
+ atomic_block { gen_token_top_level choice, scope }
53
49
  end
54
50
 
55
- def gen_token_top_level(choice)
56
- @g.intersperse_nl(choice, ' ||') {|_| generate _, :token }
51
+ def gen_token_top_level(choice, scope={})
52
+ @g.intersperse_nl(choice, ' ||') {|_| generate _, :token, scope }
57
53
  end
58
54
 
59
- def gen_skip_nested(choice)
60
- @g.surround('(', ')') { gen_skip_top_level choice }
55
+ def gen_skip_nested(choice, scope={})
56
+ @g.surround('(', ')') { gen_skip_top_level choice, scope }
61
57
  end
62
58
 
63
- def gen_skip_top_level(choice)
64
- gen_intermediate_skip choice
59
+ def gen_skip_top_level(choice, scope={})
60
+ gen_intermediate_skip choice, scope
65
61
  @g << ' && true'
66
62
  end
67
63
 
68
- def gen_intermediate_assert(choice)
64
+ def gen_intermediate_assert(choice, scope={})
69
65
  atomic_block do
70
66
  @g.intersperse_nl(choice, ' ||') do |_|
71
- generate _, :intermediate_assert
67
+ generate _, :intermediate_assert, scope
72
68
  end
73
69
  end
74
70
  end
75
71
 
76
- def gen_intermediate_skip(choice)
72
+ def gen_intermediate_skip(choice, scope={})
77
73
  atomic_block do
78
74
  @g.intersperse_nl(choice, ' ||') do |_|
79
- generate _, :intermediate_skip
75
+ generate _, :intermediate_skip, scope
80
76
  end
81
77
  end
82
78
  end
83
79
 
84
80
  private
85
81
 
86
- def gen_action_code(choice)
87
- labeled = choice.any? {|_| _.labeled? } ? labeled_name : nil
82
+ def gen_action_code(choice, scope={})
88
83
  @g.block("(#{result_name} = begin", 'end)') do
89
- (@g << "#{labeled} = nil").newline if labeled
90
- @g.intersperse_nl(choice, ' ||') do |child|
91
- if child.labeled?
92
- atomic_expr do
93
- @g.surround("(#{result_name} = ", ')') { generate child }
94
- @g << " && (#{labeled} = {:#{child.label} => #{result_name}})"
95
- @g << " && #{result_name}"
96
- end
97
- else
98
- generate child
99
- end
100
- end
84
+ @g.intersperse_nl(choice, ' ||') {|child| generate child }
101
85
  end << ' && '
102
- @g << yield(labeled)
86
+ @g << yield
103
87
  end
104
88
 
105
89
  def labeled_name