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
@@ -1,19 +1,20 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
2
 
3
+ include Rattler::BackEnd::ParserGenerator
3
4
  include Rattler::Parsers
4
5
 
5
- describe Rattler::BackEnd::ParserGenerator::OneOrMoreGenerator do
6
-
6
+ describe OneOrMoreGenerator do
7
+
7
8
  include ParserGeneratorSpecHelper
8
-
9
+
9
10
  let(:one_or_more) { OneOrMore[Match[/w+/]] }
10
-
11
+
11
12
  describe '#gen_basic' do
12
13
 
13
14
  let :one_or_more do
14
15
  OneOrMore[Choice[Match[/[[:alpha:]]/], Match[/[[:digit:]]/]]]
15
16
  end
16
-
17
+
17
18
  context 'when nested' do
18
19
  it 'generates nested one-or-more matching code' do
19
20
  nested_code {|g| g.gen_basic one_or_more }.
@@ -31,7 +32,7 @@ end
31
32
  CODE
32
33
  end
33
34
  end
34
-
35
+
35
36
  context 'when top-level' do
36
37
  it 'generates top level one-or-more matching code' do
37
38
  top_level_code {|g| g.gen_basic one_or_more }.
@@ -48,16 +49,16 @@ a unless a.empty?
48
49
  end
49
50
  end
50
51
  end
51
-
52
+
52
53
  describe '#gen_assert' do
53
-
54
+
54
55
  context 'when nested' do
55
56
  it 'generates nested one-or-more positive lookahead code' do
56
57
  nested_code {|g| g.gen_assert one_or_more }.
57
58
  should == '(@scanner.skip(/(?=w+)/) && true)'
58
59
  end
59
60
  end
60
-
61
+
61
62
  context 'when top-level' do
62
63
  it 'generates nested one-or-more positive lookahead code' do
63
64
  top_level_code {|g| g.gen_assert one_or_more }.
@@ -65,16 +66,16 @@ a unless a.empty?
65
66
  end
66
67
  end
67
68
  end
68
-
69
+
69
70
  describe '#gen_disallow' do
70
-
71
+
71
72
  context 'when nested' do
72
73
  it 'generates nested one-or-more negative lookahead code' do
73
74
  nested_code {|g| g.gen_disallow one_or_more }.
74
75
  should == '(@scanner.skip(/(?!w+)/) && true)'
75
76
  end
76
77
  end
77
-
78
+
78
79
  context 'when top-level' do
79
80
  it 'generates nested one-or-more negative lookahead code' do
80
81
  top_level_code {|g| g.gen_disallow one_or_more }.
@@ -82,12 +83,14 @@ a unless a.empty?
82
83
  end
83
84
  end
84
85
  end
85
-
86
+
86
87
  describe '#gen_dispatch_action' do
87
-
88
+
89
+ let(:code) { NodeCode.new('Word', 'parsed') }
90
+
88
91
  context 'when nested' do
89
92
  it 'generates nested one-or-more matching code with a dispatch action' do
90
- nested_code {|g| g.gen_dispatch_action one_or_more, 'Word', 'parsed' }.
93
+ nested_code {|g| g.gen_dispatch_action one_or_more, code }.
91
94
  should == (<<-CODE).strip
92
95
  begin
93
96
  a = []
@@ -99,10 +102,10 @@ end
99
102
  CODE
100
103
  end
101
104
  end
102
-
105
+
103
106
  context 'when top-level' do
104
107
  it 'generates top level one-or-more matching code with a dispatch action' do
105
- top_level_code {|g| g.gen_dispatch_action one_or_more, 'Word', 'parsed' }.
108
+ top_level_code {|g| g.gen_dispatch_action one_or_more, code }.
106
109
  should == (<<-CODE).strip
107
110
  a = []
108
111
  while r = @scanner.scan(/w+/)
@@ -113,12 +116,14 @@ Word.parsed(select_captures(a)) unless a.empty?
113
116
  end
114
117
  end
115
118
  end
116
-
119
+
117
120
  describe '#gen_direct_action' do
118
-
121
+
122
+ let(:code) { ActionCode.new('|_| _.size') }
123
+
119
124
  context 'when nested' do
120
125
  it 'generates nested one-or-more matching code with a direct action' do
121
- nested_code {|g| g.gen_direct_action one_or_more, ActionCode.new('|_| _.size') }.
126
+ nested_code {|g| g.gen_direct_action one_or_more, code }.
122
127
  should == (<<-CODE).strip
123
128
  begin
124
129
  a = []
@@ -130,10 +135,10 @@ end
130
135
  CODE
131
136
  end
132
137
  end
133
-
138
+
134
139
  context 'when top-level' do
135
140
  it 'generates top level one-or-more matching code with a direct action' do
136
- top_level_code {|g| g.gen_direct_action one_or_more, ActionCode.new('|_| _.size') }.
141
+ top_level_code {|g| g.gen_direct_action one_or_more, code }.
137
142
  should == (<<-CODE).strip
138
143
  a = []
139
144
  while r = @scanner.scan(/w+/)
@@ -144,9 +149,9 @@ end
144
149
  end
145
150
  end
146
151
  end
147
-
152
+
148
153
  describe '#gen_token' do
149
-
154
+
150
155
  context 'when nested' do
151
156
  it 'generates nested one-or-more matching code' do
152
157
  nested_code {|g| g.gen_token one_or_more }.
@@ -161,7 +166,7 @@ end
161
166
  CODE
162
167
  end
163
168
  end
164
-
169
+
165
170
  context 'when top-level' do
166
171
  it 'generates top level one-or-more matching code' do
167
172
  top_level_code {|g| g.gen_token one_or_more }.
@@ -175,9 +180,9 @@ a.join unless a.empty?
175
180
  end
176
181
  end
177
182
  end
178
-
183
+
179
184
  describe '#gen_skip' do
180
-
185
+
181
186
  context 'when nested' do
182
187
  it 'generates nested one-or-more skipping code' do
183
188
  nested_code {|g| g.gen_skip one_or_more }.
@@ -192,7 +197,7 @@ end
192
197
  CODE
193
198
  end
194
199
  end
195
-
200
+
196
201
  context 'when top-level' do
197
202
  it 'generates top level one-or-more skipping code' do
198
203
  top_level_code {|g| g.gen_skip one_or_more }.
@@ -206,7 +211,7 @@ r
206
211
  end
207
212
  end
208
213
  end
209
-
214
+
210
215
  describe '#gen_intermediate' do
211
216
  it 'generates nested one-or-more matching code' do
212
217
  nested_code {|g| g.gen_intermediate one_or_more }.
@@ -221,21 +226,21 @@ end
221
226
  CODE
222
227
  end
223
228
  end
224
-
229
+
225
230
  describe '#gen_intermediate_assert' do
226
231
  it 'generates nested one-or-more positive lookahead code' do
227
232
  nested_code {|g| g.gen_assert one_or_more }.
228
233
  should == '(@scanner.skip(/(?=w+)/) && true)'
229
234
  end
230
235
  end
231
-
236
+
232
237
  describe '#gen_intermediate_disallow' do
233
238
  it 'generates nested one-or-more negative lookahead code' do
234
239
  nested_code {|g| g.gen_disallow one_or_more }.
235
240
  should == '(@scanner.skip(/(?!w+)/) && true)'
236
241
  end
237
242
  end
238
-
243
+
239
244
  describe '#gen_intermediate_skip' do
240
245
  it 'generates nested one-or-more skipping code' do
241
246
  nested_code {|g| g.gen_intermediate_skip one_or_more }.
@@ -250,5 +255,5 @@ end
250
255
  CODE
251
256
  end
252
257
  end
253
-
258
+
254
259
  end
@@ -1,22 +1,23 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
2
 
3
+ include Rattler::BackEnd::ParserGenerator
3
4
  include Rattler::Parsers
4
5
 
5
- describe Rattler::BackEnd::ParserGenerator::OptionalGenerator do
6
-
6
+ describe OptionalGenerator do
7
+
7
8
  include ParserGeneratorSpecHelper
8
-
9
+
9
10
  let(:optional) { Optional[Match[/w+/]] }
10
-
11
+
11
12
  describe '#gen_basic' do
12
-
13
+
13
14
  context 'when nested' do
14
15
  it 'generates nested optional matching code' do
15
16
  nested_code {|g| g.gen_basic optional }.
16
17
  should == '((r = @scanner.scan(/w+/)) ? [r] : [])'
17
18
  end
18
19
  end
19
-
20
+
20
21
  context 'when top-level' do
21
22
  it 'generates top level optional matching code' do
22
23
  top_level_code {|g| g.gen_basic optional }.
@@ -24,42 +25,44 @@ describe Rattler::BackEnd::ParserGenerator::OptionalGenerator do
24
25
  end
25
26
  end
26
27
  end
27
-
28
+
28
29
  describe '#gen_assert' do
29
-
30
+
30
31
  context 'when nested' do
31
32
  it 'generates "true"' do
32
33
  nested_code {|g| g.gen_assert optional }.should == 'true'
33
34
  end
34
35
  end
35
-
36
+
36
37
  context 'when top-level' do
37
38
  it 'generates "true"' do
38
39
  top_level_code {|g| g.gen_assert optional }.should == 'true'
39
40
  end
40
41
  end
41
42
  end
42
-
43
+
43
44
  describe '#gen_disallow' do
44
-
45
+
45
46
  context 'when nested' do
46
47
  it 'generates "false"' do
47
48
  nested_code {|g| g.gen_disallow optional }.should == 'false'
48
49
  end
49
50
  end
50
-
51
+
51
52
  context 'when top-level' do
52
53
  it 'generates "false"' do
53
54
  top_level_code {|g| g.gen_disallow optional }.should == 'false'
54
55
  end
55
56
  end
56
57
  end
57
-
58
+
58
59
  describe '#gen_dispatch_action' do
59
-
60
+
61
+ let(:code) { NodeCode.new('Word', 'parsed') }
62
+
60
63
  context 'when nested' do
61
64
  it 'generates nested optional matching code with a dispatch action' do
62
- nested_code {|g| g.gen_dispatch_action optional, 'Word', 'parsed' }.
65
+ nested_code {|g| g.gen_dispatch_action optional, code }.
63
66
  should == (<<-CODE).strip
64
67
  begin
65
68
  r = @scanner.scan(/w+/)
@@ -68,10 +71,10 @@ end
68
71
  CODE
69
72
  end
70
73
  end
71
-
74
+
72
75
  context 'when top-level' do
73
76
  it 'generates top level optional matching code with a dispatch action' do
74
- top_level_code {|g| g.gen_dispatch_action optional, 'Word', 'parsed' }.
77
+ top_level_code {|g| g.gen_dispatch_action optional, code }.
75
78
  should == (<<-CODE).strip
76
79
  r = @scanner.scan(/w+/)
77
80
  Word.parsed(r ? [r] : [])
@@ -79,12 +82,14 @@ Word.parsed(r ? [r] : [])
79
82
  end
80
83
  end
81
84
  end
82
-
85
+
83
86
  describe '#gen_direct_action' do
84
-
87
+
88
+ let(:code) { ActionCode.new('|_| _.size') }
89
+
85
90
  context 'when nested' do
86
91
  it 'generates nested optional matching code with a direct action' do
87
- nested_code {|g| g.gen_direct_action optional, ActionCode.new('|_| _.size') }.
92
+ nested_code {|g| g.gen_direct_action optional, code }.
88
93
  should == (<<-CODE).strip
89
94
  begin
90
95
  r = @scanner.scan(/w+/)
@@ -93,10 +98,10 @@ end
93
98
  CODE
94
99
  end
95
100
  end
96
-
101
+
97
102
  context 'when top-level' do
98
103
  it 'generates top level optional matching code with a direct action' do
99
- top_level_code {|g| g.gen_direct_action optional, ActionCode.new('|_| _.size') }.
104
+ top_level_code {|g| g.gen_direct_action optional, code }.
100
105
  should == (<<-CODE).strip
101
106
  r = @scanner.scan(/w+/)
102
107
  ((r ? [r] : []).size)
@@ -104,9 +109,9 @@ r = @scanner.scan(/w+/)
104
109
  end
105
110
  end
106
111
  end
107
-
112
+
108
113
  describe '#gen_token' do
109
-
114
+
110
115
  context 'when nested' do
111
116
  it 'generates nested optional matching code' do
112
117
  nested_code {|g| g.gen_token optional }.
@@ -117,7 +122,7 @@ end
117
122
  CODE
118
123
  end
119
124
  end
120
-
125
+
121
126
  context 'when top-level' do
122
127
  it 'generates top level optional matching code' do
123
128
  top_level_code {|g| g.gen_token optional }.
@@ -125,9 +130,9 @@ end
125
130
  end
126
131
  end
127
132
  end
128
-
133
+
129
134
  describe '#gen_skip' do
130
-
135
+
131
136
  context 'when nested' do
132
137
  it 'generates nested optional skipping code' do
133
138
  nested_code {|g| g.gen_skip optional }.
@@ -139,7 +144,7 @@ end
139
144
  CODE
140
145
  end
141
146
  end
142
-
147
+
143
148
  context 'when top-level' do
144
149
  it 'generates top level optional skipping code' do
145
150
  top_level_code {|g| g.gen_skip optional }.
@@ -150,26 +155,26 @@ true
150
155
  end
151
156
  end
152
157
  end
153
-
158
+
154
159
  describe '#gen_intermediate' do
155
160
  it 'generates nested optional matching code' do
156
161
  nested_code {|g| g.gen_intermediate optional }.
157
162
  should == '((r = @scanner.scan(/w+/)) ? [r] : [])'
158
163
  end
159
164
  end
160
-
165
+
161
166
  describe '#gen_intermediate_assert' do
162
167
  it 'generates "true"' do
163
168
  nested_code {|g| g.gen_intermediate_assert optional }.should == 'true'
164
169
  end
165
170
  end
166
-
171
+
167
172
  describe '#gen_intermediate_disallow' do
168
173
  it 'generates "false"' do
169
174
  nested_code {|g| g.gen_intermediate_disallow optional }.should == 'false'
170
175
  end
171
176
  end
172
-
177
+
173
178
  describe '#gen_intermediate_skip' do
174
179
  it 'generates nested optional skipping code' do
175
180
  nested_code {|g| g.gen_intermediate_skip optional }.
@@ -181,5 +186,5 @@ end
181
186
  CODE
182
187
  end
183
188
  end
184
-
189
+
185
190
  end
@@ -3,61 +3,28 @@ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
3
3
  include Rattler::Parsers
4
4
 
5
5
  describe Rattler::BackEnd::ParserGenerator::RuleGenerator do
6
-
6
+
7
7
  include ParserGeneratorSpecHelper
8
-
9
- let(:rules) { Rules[
10
- Rule[:a, Choice[
11
- Match['a'],
12
- Apply[:b]
13
- ]],
14
- Rule[:b, Match['b']]
15
- ] }
16
-
8
+
17
9
  describe '#generate' do
18
- context 'given rules with no start rule defined' do
19
- it 'generates #match_<rule> methods' do
20
- generated_code {|g| g.generate rules }.
21
- should == (<<-CODE).strip
22
- # @private
23
- def match_a #:nodoc:
24
- @scanner.scan("a") ||
25
- match(:b)
26
- end
27
10
 
28
- # @private
29
- def match_b #:nodoc:
30
- @scanner.scan("b")
31
- end
32
- CODE
33
- end
34
- end
35
-
36
- context 'given rules with a start rule defined' do
37
-
38
- before { rules.start_rule = :a }
39
-
40
- it 'generates #start_rule and #match_<rule> methods' do
41
- generated_code {|g| g.generate rules }.
42
- should == (<<-CODE).strip
43
- # @private
44
- def start_rule #:nodoc:
45
- :a
46
- end
11
+ let(:rule) { Rule[:a, Choice[Match['a'], Apply[:b]]] }
47
12
 
13
+ it 'generates #match_<rule> methods' do
14
+ generated_code {|g| g.generate rule }.
15
+ should == (<<-CODE).strip
48
16
  # @private
49
17
  def match_a #:nodoc:
50
- @scanner.scan("a") ||
51
- match(:b)
18
+ apply :match_a!
52
19
  end
53
20
 
54
21
  # @private
55
- def match_b #:nodoc:
56
- @scanner.scan("b")
22
+ def match_a! #:nodoc:
23
+ @scanner.scan("a") ||
24
+ match(:b)
57
25
  end
58
- CODE
59
- end
26
+ CODE
60
27
  end
61
28
  end
62
-
63
- end
29
+
30
+ end