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