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.
- data/README.rdoc +57 -37
- data/features/command_line/dest_option.feature +8 -21
- data/features/command_line/lib_option.feature +37 -0
- data/features/command_line/parser_generator.feature +7 -4
- data/features/grammar/back_reference.feature +37 -0
- data/features/grammar/fail.feature +3 -3
- data/features/grammar/labels.feature +11 -3
- data/features/grammar/list_matching.feature +14 -5
- data/features/grammar/literal.feature +30 -4
- data/features/grammar/nonterminal.feature +1 -1
- data/features/grammar/ordered_choice.feature +2 -2
- data/features/grammar/skip_operator.feature +1 -1
- data/features/grammar/symantic_action.feature +7 -7
- data/features/grammar/whitespace.feature +2 -2
- data/features/step_definitions/grammar_steps.rb +2 -2
- data/lib/rattler/back_end.rb +1 -0
- data/lib/rattler/back_end/compiler.rb +19 -20
- data/lib/rattler/back_end/optimizer.rb +100 -0
- data/lib/rattler/back_end/optimizer/composite_reducing.rb +18 -0
- data/lib/rattler/back_end/optimizer/flatten_choice.rb +31 -0
- data/lib/rattler/back_end/optimizer/flatten_sequence.rb +59 -0
- data/lib/rattler/back_end/optimizer/flattening.rb +17 -0
- data/lib/rattler/back_end/optimizer/inline_regular_rules.rb +46 -0
- data/lib/rattler/back_end/optimizer/join_match_capturing_sequence.rb +71 -0
- data/lib/rattler/back_end/optimizer/join_match_choice.rb +37 -0
- data/lib/rattler/back_end/optimizer/join_match_matching_sequence.rb +38 -0
- data/lib/rattler/back_end/optimizer/join_match_sequence.rb +17 -0
- data/lib/rattler/back_end/optimizer/join_predicate_bare_match.rb +68 -0
- data/lib/rattler/back_end/optimizer/join_predicate_match.rb +17 -0
- data/lib/rattler/back_end/optimizer/join_predicate_nested_match.rb +37 -0
- data/lib/rattler/back_end/optimizer/join_predicate_or_bare_match.rb +68 -0
- data/lib/rattler/back_end/optimizer/join_predicate_or_match.rb +17 -0
- data/lib/rattler/back_end/optimizer/join_predicate_or_nested_match.rb +36 -0
- data/lib/rattler/back_end/optimizer/match_joining.rb +60 -0
- data/lib/rattler/back_end/optimizer/optimization.rb +94 -0
- data/lib/rattler/back_end/optimizer/optimization_context.rb +72 -0
- data/lib/rattler/back_end/optimizer/optimization_sequence.rb +37 -0
- data/lib/rattler/back_end/optimizer/optimize_children.rb +46 -0
- data/lib/rattler/back_end/optimizer/reduce_repeat_match.rb +44 -0
- data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rb +32 -0
- data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rb +43 -0
- data/lib/rattler/back_end/optimizer/simplify_token_match.rb +38 -0
- data/lib/rattler/back_end/parser_generator.rb +21 -14
- data/lib/rattler/back_end/parser_generator/apply_generator.rb +35 -35
- data/lib/rattler/back_end/parser_generator/assert_generator.rb +29 -30
- data/lib/rattler/back_end/parser_generator/back_reference_generator.rb +93 -0
- data/lib/rattler/back_end/parser_generator/choice_generator.rb +33 -49
- data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +14 -14
- data/lib/rattler/back_end/parser_generator/disallow_generator.rb +29 -30
- data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +11 -13
- data/lib/rattler/back_end/parser_generator/expr_generator.rb +36 -56
- data/lib/rattler/back_end/parser_generator/fail_generator.rb +18 -18
- data/lib/rattler/back_end/parser_generator/group_match.rb +18 -0
- data/lib/rattler/back_end/parser_generator/group_match_generator.rb +76 -0
- data/lib/rattler/back_end/parser_generator/label_generator.rb +25 -6
- data/lib/rattler/back_end/parser_generator/list1_generator.rb +7 -7
- data/lib/rattler/back_end/parser_generator/list_generating.rb +19 -20
- data/lib/rattler/back_end/parser_generator/list_generator.rb +5 -5
- data/lib/rattler/back_end/parser_generator/match_generator.rb +52 -52
- data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +6 -6
- data/lib/rattler/back_end/parser_generator/optional_generator.rb +30 -29
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +8 -8
- data/lib/rattler/back_end/parser_generator/repeat_generating.rb +23 -25
- data/lib/rattler/back_end/parser_generator/rule_generator.rb +27 -79
- data/lib/rattler/back_end/parser_generator/rule_set_generator.rb +102 -0
- data/lib/rattler/back_end/parser_generator/sequence_generator.rb +49 -41
- data/lib/rattler/back_end/parser_generator/skip_generator.rb +14 -20
- data/lib/rattler/back_end/parser_generator/skip_propogating.rb +4 -4
- data/lib/rattler/back_end/parser_generator/sub_generating.rb +6 -0
- data/lib/rattler/back_end/parser_generator/token_generator.rb +12 -12
- data/lib/rattler/back_end/parser_generator/token_propogating.rb +2 -2
- data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +4 -4
- data/lib/rattler/grammar.rb +4 -3
- data/lib/rattler/grammar/analysis.rb +91 -0
- data/lib/rattler/grammar/grammar.rb +37 -25
- data/lib/rattler/grammar/grammar_parser.rb +19 -11
- data/lib/rattler/grammar/metagrammar.rb +569 -800
- data/lib/rattler/grammar/rattler.rtlr +162 -144
- data/lib/rattler/parsers.rb +5 -1
- data/lib/rattler/parsers/action_code.rb +29 -15
- data/lib/rattler/parsers/apply.rb +5 -5
- data/lib/rattler/parsers/assert.rb +4 -18
- data/lib/rattler/parsers/back_reference.rb +46 -0
- data/lib/rattler/parsers/choice.rb +6 -39
- data/lib/rattler/parsers/combinator_parser.rb +32 -0
- data/lib/rattler/parsers/combining.rb +3 -29
- data/lib/rattler/parsers/direct_action.rb +27 -30
- data/lib/rattler/parsers/disallow.rb +4 -18
- data/lib/rattler/parsers/dispatch_action.rb +30 -25
- data/lib/rattler/parsers/label.rb +9 -18
- data/lib/rattler/parsers/list.rb +3 -34
- data/lib/rattler/parsers/list1.rb +4 -36
- data/lib/rattler/parsers/list_parser.rb +64 -0
- data/lib/rattler/parsers/match.rb +7 -42
- data/lib/rattler/parsers/node_code.rb +44 -0
- data/lib/rattler/parsers/one_or_more.rb +7 -27
- data/lib/rattler/parsers/optional.rb +5 -25
- data/lib/rattler/parsers/parser.rb +16 -44
- data/lib/rattler/parsers/parser_dsl.rb +13 -3
- data/lib/rattler/parsers/predicate.rb +4 -12
- data/lib/rattler/parsers/rule.rb +18 -19
- data/lib/rattler/parsers/rule_set.rb +63 -0
- data/lib/rattler/parsers/sequence.rb +12 -46
- data/lib/rattler/parsers/skip.rb +12 -26
- data/lib/rattler/parsers/token.rb +6 -21
- data/lib/rattler/parsers/zero_or_more.rb +6 -26
- data/lib/rattler/runner.rb +66 -28
- data/lib/rattler/runtime/extended_packrat_parser.rb +26 -20
- data/lib/rattler/runtime/packrat_parser.rb +17 -21
- data/lib/rattler/runtime/parser.rb +12 -2
- data/lib/rattler/runtime/recursive_descent_parser.rb +3 -11
- data/lib/rattler/util.rb +2 -1
- data/lib/rattler/util/graphviz.rb +29 -0
- data/lib/rattler/util/graphviz/digraph_builder.rb +71 -0
- data/lib/rattler/util/graphviz/node_builder.rb +84 -0
- data/lib/rattler/util/node.rb +37 -19
- data/lib/rattler/util/parser_spec_helper.rb +61 -35
- data/spec/rattler/back_end/compiler_spec.rb +6 -860
- data/spec/rattler/back_end/optimizer/flatten_choice_spec.rb +70 -0
- data/spec/rattler/back_end/optimizer/flatten_sequence_spec.rb +130 -0
- data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rb +80 -0
- data/spec/rattler/back_end/optimizer/join_match_capturing_sequence_spec.rb +241 -0
- data/spec/rattler/back_end/optimizer/join_match_choice_spec.rb +100 -0
- data/spec/rattler/back_end/optimizer/join_match_matching_sequence_spec.rb +112 -0
- data/spec/rattler/back_end/optimizer/join_predicate_bare_match_spec.rb +194 -0
- data/spec/rattler/back_end/optimizer/join_predicate_nested_match_spec.rb +180 -0
- data/spec/rattler/back_end/optimizer/join_predicate_or_bare_match_spec.rb +153 -0
- data/spec/rattler/back_end/optimizer/join_predicate_or_nested_match_spec.rb +153 -0
- data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rb +98 -0
- data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rb +226 -0
- data/spec/rattler/back_end/optimizer/simplify_token_match_spec.rb +85 -0
- data/spec/rattler/back_end/parser_generator/apply_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/assert_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/back_reference_generator_spec.rb +181 -0
- data/spec/rattler/back_end/parser_generator/choice_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/disallow_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rb +185 -0
- data/spec/rattler/back_end/parser_generator/label_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +10 -5
- data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +10 -5
- data/spec/rattler/back_end/parser_generator/match_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/optional_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/rule_generator_spec.rb +13 -46
- data/spec/rattler/back_end/parser_generator/rule_set_generator_spec.rb +97 -0
- data/spec/rattler/back_end/parser_generator/sequence_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/skip_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/token_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rb +39 -34
- data/spec/rattler/back_end/shared_compiler_examples.rb +885 -0
- data/spec/rattler/grammar/analysis_spec.rb +167 -0
- data/spec/rattler/grammar/grammar_parser_spec.rb +169 -179
- data/spec/rattler/grammar/grammar_spec.rb +24 -21
- data/spec/rattler/parsers/action_code_spec.rb +64 -19
- data/spec/rattler/parsers/apply_spec.rb +9 -9
- data/spec/rattler/parsers/back_reference_spec.rb +38 -0
- data/spec/rattler/parsers/combinator_parser_spec.rb +14 -0
- data/spec/rattler/parsers/direct_action_spec.rb +16 -2
- data/spec/rattler/parsers/dispatch_action_spec.rb +15 -32
- data/spec/rattler/parsers/fail_spec.rb +6 -4
- data/spec/rattler/parsers/label_spec.rb +10 -28
- data/spec/rattler/parsers/node_code_spec.rb +48 -0
- data/spec/rattler/parsers/parser_dsl_spec.rb +1 -1
- data/spec/rattler/parsers/rule_set_spec.rb +35 -0
- data/spec/rattler/parsers/sequence_spec.rb +15 -24
- data/spec/rattler/runtime/extended_packrat_parser_spec.rb +22 -17
- data/spec/rattler/runtime/packrat_parser_spec.rb +1 -1
- data/spec/rattler/runtime/parse_node_spec.rb +15 -19
- data/spec/rattler/runtime/recursive_descent_parser_spec.rb +1 -1
- data/spec/rattler/runtime/shared_parser_examples.rb +61 -28
- data/spec/rattler/util/graphviz/node_builder_spec.rb +84 -0
- data/spec/rattler/util/node_spec.rb +92 -65
- data/spec/rattler_spec.rb +16 -16
- data/spec/support/combinator_parser_spec_helper.rb +19 -18
- data/spec/support/compiler_spec_helper.rb +56 -87
- data/spec/support/runtime_parser_spec_helper.rb +6 -14
- metadata +117 -22
- data/features/grammar/regex.feature +0 -24
- data/lib/rattler/parsers/match_joining.rb +0 -67
- 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
|
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,
|
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,
|
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,
|
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,
|
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
|
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,
|
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,
|
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,
|
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,
|
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
|
-
|
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
|
-
|
51
|
-
match(:b)
|
18
|
+
apply :match_a!
|
52
19
|
end
|
53
20
|
|
54
21
|
# @private
|
55
|
-
def
|
56
|
-
@scanner.scan("
|
22
|
+
def match_a! #:nodoc:
|
23
|
+
@scanner.scan("a") ||
|
24
|
+
match(:b)
|
57
25
|
end
|
58
|
-
|
59
|
-
end
|
26
|
+
CODE
|
60
27
|
end
|
61
28
|
end
|
62
|
-
|
63
|
-
end
|
29
|
+
|
30
|
+
end
|