rattler 0.2.2 → 0.3.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 +83 -64
- data/features/grammar/comments.feature +24 -0
- data/features/grammar/list_matching.feature +41 -0
- data/features/grammar/symantic_action.feature +30 -12
- data/lib/rattler/back_end/parser_generator/assert_generator.rb +27 -27
- data/lib/rattler/back_end/parser_generator/choice_generator.rb +29 -29
- data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +17 -17
- data/lib/rattler/back_end/parser_generator/disallow_generator.rb +27 -27
- data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +17 -17
- data/lib/rattler/back_end/parser_generator/expr_generator.rb +129 -40
- data/lib/rattler/back_end/parser_generator/label_generator.rb +15 -15
- data/lib/rattler/back_end/parser_generator/list1_generator.rb +61 -0
- data/lib/rattler/back_end/parser_generator/list_generating.rb +71 -0
- data/lib/rattler/back_end/parser_generator/list_generator.rb +57 -0
- data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +14 -15
- data/lib/rattler/back_end/parser_generator/optional_generator.rb +24 -24
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +9 -9
- data/lib/rattler/back_end/parser_generator/repeat_generating.rb +16 -16
- data/lib/rattler/back_end/parser_generator/sequence_generator.rb +40 -40
- data/lib/rattler/back_end/parser_generator/skip_generator.rb +18 -18
- data/lib/rattler/back_end/parser_generator/skip_propogating.rb +5 -5
- data/lib/rattler/back_end/parser_generator/sub_generating.rb +128 -0
- data/lib/rattler/back_end/parser_generator/token_generator.rb +15 -15
- data/lib/rattler/back_end/parser_generator/token_propogating.rb +1 -1
- data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +12 -13
- data/lib/rattler/back_end/parser_generator.rb +10 -7
- data/lib/rattler/grammar/grammar_parser.rb +16 -21
- data/lib/rattler/grammar/metagrammar.rb +1039 -1035
- data/lib/rattler/grammar/rattler.rtlr +28 -28
- data/lib/rattler/parsers/action_code.rb +20 -9
- data/lib/rattler/parsers/fail.rb +7 -1
- data/lib/rattler/parsers/list.rb +57 -0
- data/lib/rattler/parsers/list1.rb +58 -0
- data/lib/rattler/parsers/parser_dsl.rb +60 -38
- data/lib/rattler/parsers.rb +5 -3
- data/lib/rattler/runtime/extended_packrat_parser.rb +88 -20
- data/lib/rattler/runtime/packrat_parser.rb +21 -14
- data/lib/rattler/runtime/parser.rb +74 -18
- data/lib/rattler/runtime/recursive_descent_parser.rb +15 -46
- data/spec/rattler/back_end/compiler_spec.rb +173 -107
- data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +304 -0
- data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +288 -0
- data/spec/rattler/grammar/grammar_parser_spec.rb +65 -76
- data/spec/rattler/parsers/action_code_spec.rb +84 -34
- data/spec/rattler/parsers/direct_action_spec.rb +56 -34
- data/spec/rattler/parsers/fail_spec.rb +20 -0
- data/spec/rattler/parsers/list1_spec.rb +82 -0
- data/spec/rattler/parsers/list_spec.rb +82 -0
- data/spec/rattler/parsers/parser_dsl_spec.rb +48 -19
- data/spec/rattler/runtime/extended_packrat_parser_spec.rb +0 -1
- metadata +92 -173
- data/bin/rtlr.bat +0 -3
- data/lib/rattler/back_end/parser_generator/generator_helper.rb +0 -130
- data/lib/rattler/back_end/parser_generator/generators.rb +0 -86
- data/lib/rattler/back_end/parser_generator/nested_generators.rb +0 -15
- data/lib/rattler/back_end/parser_generator/top_level_generators.rb +0 -15
@@ -2,28 +2,28 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
|
3
3
|
describe Rattler::BackEnd::Compiler do
|
4
4
|
include CompilerSpecHelper
|
5
|
-
|
5
|
+
|
6
6
|
subject { described_class }
|
7
|
-
|
7
|
+
|
8
8
|
describe '.compile_parser' do
|
9
|
-
|
9
|
+
|
10
10
|
context 'given parse rules' do
|
11
|
-
|
11
|
+
|
12
12
|
let(:rules) { define_parser do
|
13
13
|
rule(:word) { match /\w+/ }
|
14
14
|
rule(:space) { match /\s*/ }
|
15
15
|
end }
|
16
|
-
|
16
|
+
|
17
17
|
let(:parser_base) { Rattler::Runtime::RecursiveDescentParser }
|
18
|
-
|
18
|
+
|
19
19
|
let(:result) { described_class.compile_parser(parser_base, rules) }
|
20
|
-
|
20
|
+
|
21
21
|
it 'compiles a match_xxx method for each rule' do
|
22
22
|
result.should have_method(:match_word)
|
23
23
|
result.should have_method(:match_space)
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
########## match ##########
|
28
28
|
context 'given a match rule' do
|
29
29
|
let(:rules) { define_parser do
|
@@ -33,7 +33,7 @@ describe Rattler::BackEnd::Compiler do
|
|
33
33
|
it { should compile(rules).test_parsing ' 4' }
|
34
34
|
it { should compile(rules).test_parsing 'foo' }
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
########## choice ##########
|
38
38
|
context 'given a choice rule' do
|
39
39
|
let(:rules) { define_parser do
|
@@ -41,10 +41,10 @@ describe Rattler::BackEnd::Compiler do
|
|
41
41
|
match(/[[:alpha:]]+/) & match(/[[:digit:]]+/)
|
42
42
|
end
|
43
43
|
end }
|
44
|
-
|
44
|
+
|
45
45
|
it { should compile(rules).test_parsing('abc123').twice }
|
46
46
|
it { should compile(rules).test_parsing '==' }
|
47
|
-
|
47
|
+
|
48
48
|
context 'with nested choices' do
|
49
49
|
let(:rules) { define_parser do
|
50
50
|
rule(:foo) do
|
@@ -55,7 +55,7 @@ describe Rattler::BackEnd::Compiler do
|
|
55
55
|
it { should compile(rules).test_parsing('abcd').repeating(4).times }
|
56
56
|
it { should compile(rules).test_parsing '123' }
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
context 'with nested sequences' do
|
60
60
|
let(:rules) { define_parser do
|
61
61
|
rule(:foo) do
|
@@ -66,7 +66,7 @@ describe Rattler::BackEnd::Compiler do
|
|
66
66
|
it { should compile(rules).test_parsing('abcd').twice }
|
67
67
|
it { should compile(rules).test_parsing '123' }
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
context 'with nested optional parsers' do
|
71
71
|
let(:rules) { define_parser do
|
72
72
|
rule(:foo) do
|
@@ -77,7 +77,7 @@ describe Rattler::BackEnd::Compiler do
|
|
77
77
|
it { should compile(rules).test_parsing '123' }
|
78
78
|
end
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
########## sequence ##########
|
82
82
|
context 'given a sequence rule' do
|
83
83
|
let(:rules) { define_parser do
|
@@ -85,31 +85,31 @@ describe Rattler::BackEnd::Compiler do
|
|
85
85
|
match(/[[:alpha:]]+/) & match('=') & match(/[[:digit:]]+/)
|
86
86
|
end
|
87
87
|
end }
|
88
|
-
|
88
|
+
|
89
89
|
it { should compile(rules).test_parsing 'val=42 ' }
|
90
90
|
it { should compile(rules).test_parsing 'val=x' }
|
91
|
-
|
91
|
+
|
92
92
|
context 'with non-capturing parsers' do
|
93
93
|
it { should compile { rule :foo do
|
94
94
|
match(/[[:alpha:]]+/) & skip(/\s+/) & match(/[[:digit:]]+/)
|
95
95
|
end }.
|
96
96
|
test_parsing 'foo 42' }
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
context 'with only one capturing parser' do
|
100
100
|
it { should compile { rule :foo do
|
101
101
|
skip(/\s+/) & match(/\w+/)
|
102
102
|
end }.
|
103
103
|
test_parsing ' abc123' }
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
context 'with no capturing parsers' do
|
107
107
|
it { should compile { rule :foo do
|
108
108
|
skip(/\s*/) & skip(/#[^\n]+/)
|
109
109
|
end }.
|
110
110
|
test_parsing ' # foo' }
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
context 'with an apply referencing a non-capturing rule' do
|
114
114
|
it { should compile {
|
115
115
|
rule :ws do
|
@@ -121,7 +121,7 @@ describe Rattler::BackEnd::Compiler do
|
|
121
121
|
test_parsing('foo 42').as :foo }
|
122
122
|
end
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
########## optional ##########
|
126
126
|
context 'given an optional rule' do
|
127
127
|
let(:rules) { define_parser do
|
@@ -131,7 +131,7 @@ describe Rattler::BackEnd::Compiler do
|
|
131
131
|
end }
|
132
132
|
it { should compile(rules).test_parsing 'foo ' }
|
133
133
|
it { should compile(rules).test_parsing ' ' }
|
134
|
-
|
134
|
+
|
135
135
|
context 'with a non-capturing parser' do
|
136
136
|
let(:rules) { define_parser do
|
137
137
|
rule :foo do
|
@@ -142,7 +142,7 @@ describe Rattler::BackEnd::Compiler do
|
|
142
142
|
it { should compile(rules).test_parsing ' ' }
|
143
143
|
end
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
########## zero-or-more ##########
|
147
147
|
context 'given a zero-or-more rule' do
|
148
148
|
let(:rules) { define_parser do
|
@@ -152,7 +152,7 @@ describe Rattler::BackEnd::Compiler do
|
|
152
152
|
end }
|
153
153
|
it { should compile(rules).test_parsing 'foo ' }
|
154
154
|
it { should compile(rules).test_parsing ' ' }
|
155
|
-
|
155
|
+
|
156
156
|
context 'with a non-capturing parser' do
|
157
157
|
let(:rules) { define_parser do
|
158
158
|
rule :foo do
|
@@ -163,7 +163,7 @@ describe Rattler::BackEnd::Compiler do
|
|
163
163
|
it { should compile(rules).test_parsing ' ' }
|
164
164
|
end
|
165
165
|
end
|
166
|
-
|
166
|
+
|
167
167
|
########## one-or-more ##########
|
168
168
|
context 'given a one-or-more rule' do
|
169
169
|
let(:rules) { define_parser do
|
@@ -173,7 +173,7 @@ describe Rattler::BackEnd::Compiler do
|
|
173
173
|
end }
|
174
174
|
it { should compile(rules).test_parsing 'foo ' }
|
175
175
|
it { should compile(rules).test_parsing ' ' }
|
176
|
-
|
176
|
+
|
177
177
|
context 'with a non-capturing parser' do
|
178
178
|
let(:rules) { define_parser do
|
179
179
|
rule :foo do
|
@@ -184,7 +184,57 @@ describe Rattler::BackEnd::Compiler do
|
|
184
184
|
it { should compile(rules).test_parsing ' ' }
|
185
185
|
end
|
186
186
|
end
|
187
|
-
|
187
|
+
|
188
|
+
########## list ##########
|
189
|
+
context 'given a list rule' do
|
190
|
+
let(:rules) { define_parser do
|
191
|
+
rule :foo do
|
192
|
+
list(/\w+/, /[,;]/)
|
193
|
+
end
|
194
|
+
end }
|
195
|
+
it { should compile(rules).test_parsing ' ' }
|
196
|
+
it { should compile(rules).test_parsing 'foo ' }
|
197
|
+
it { should compile(rules).test_parsing 'foo,bar;baz ' }
|
198
|
+
it { should compile(rules).test_parsing 'foo,bar, ' }
|
199
|
+
|
200
|
+
context 'with a non-capturing parser' do
|
201
|
+
let(:rules) { define_parser do
|
202
|
+
rule :foo do
|
203
|
+
list(skip(/\w+/), /[,;]/)
|
204
|
+
end
|
205
|
+
end }
|
206
|
+
it { should compile(rules).test_parsing ' ' }
|
207
|
+
it { should compile(rules).test_parsing 'foo ' }
|
208
|
+
it { should compile(rules).test_parsing 'foo,bar;baz ' }
|
209
|
+
it { should compile(rules).test_parsing 'foo,bar, ' }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
########## list1 ##########
|
214
|
+
context 'given a list1 rule' do
|
215
|
+
let(:rules) { define_parser do
|
216
|
+
rule :foo do
|
217
|
+
list1(/\w+/, /[,;]/)
|
218
|
+
end
|
219
|
+
end }
|
220
|
+
it { should compile(rules).test_parsing ' ' }
|
221
|
+
it { should compile(rules).test_parsing 'foo ' }
|
222
|
+
it { should compile(rules).test_parsing 'foo,bar;baz ' }
|
223
|
+
it { should compile(rules).test_parsing 'foo,bar, ' }
|
224
|
+
|
225
|
+
context 'with a non-capturing parser' do
|
226
|
+
let(:rules) { define_parser do
|
227
|
+
rule :foo do
|
228
|
+
list(skip(/\w+/), /[,;]/)
|
229
|
+
end
|
230
|
+
end }
|
231
|
+
it { should compile(rules).test_parsing ' ' }
|
232
|
+
it { should compile(rules).test_parsing 'foo ' }
|
233
|
+
it { should compile(rules).test_parsing 'foo,bar;baz ' }
|
234
|
+
it { should compile(rules).test_parsing 'foo,bar, ' }
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
188
238
|
########## apply ##########
|
189
239
|
context 'given an apply rule' do
|
190
240
|
let(:rules) { define_parser do
|
@@ -194,10 +244,10 @@ describe Rattler::BackEnd::Compiler do
|
|
194
244
|
it { should compile(rules).test_parsing('451 ').twice.as :foo }
|
195
245
|
it { should compile(rules).test_parsing 'hi' }
|
196
246
|
end
|
197
|
-
|
247
|
+
|
198
248
|
########## assert ##########
|
199
249
|
context 'given an assert rule' do
|
200
|
-
|
250
|
+
|
201
251
|
context 'with a nested match rule' do
|
202
252
|
let(:rules) { define_parser do
|
203
253
|
rule(:word) { assert /\w+/ }
|
@@ -205,7 +255,7 @@ describe Rattler::BackEnd::Compiler do
|
|
205
255
|
it { should compile(rules).test_parsing 'abc123 ' }
|
206
256
|
it { should compile(rules).test_parsing ' ' }
|
207
257
|
end
|
208
|
-
|
258
|
+
|
209
259
|
context 'with a nested choice rule' do
|
210
260
|
let(:rules) { define_parser do
|
211
261
|
rule(:word) { assert(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/)) }
|
@@ -213,7 +263,7 @@ describe Rattler::BackEnd::Compiler do
|
|
213
263
|
it { should compile(rules).test_parsing('abc123 ').twice }
|
214
264
|
it { should compile(rules).test_parsing ' ' }
|
215
265
|
end
|
216
|
-
|
266
|
+
|
217
267
|
context 'with a nested sequence rule' do
|
218
268
|
let(:rules) { define_parser do
|
219
269
|
rule(:word) { assert(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/)) }
|
@@ -221,7 +271,7 @@ describe Rattler::BackEnd::Compiler do
|
|
221
271
|
it { should compile(rules).test_parsing 'abc123 ' }
|
222
272
|
it { should compile(rules).test_parsing ' ' }
|
223
273
|
end
|
224
|
-
|
274
|
+
|
225
275
|
context 'with a nested optional rule' do
|
226
276
|
let(:rules) { define_parser do
|
227
277
|
rule(:word) { assert(optional(/\w+/)) }
|
@@ -229,7 +279,7 @@ describe Rattler::BackEnd::Compiler do
|
|
229
279
|
it { should compile(rules).test_parsing 'abc123 ' }
|
230
280
|
it { should compile(rules).test_parsing ' ' }
|
231
281
|
end
|
232
|
-
|
282
|
+
|
233
283
|
context 'with a nested zero_or_more rule' do
|
234
284
|
let(:rules) { define_parser do
|
235
285
|
rule(:word) { assert(zero_or_more(/\w/)) }
|
@@ -237,7 +287,7 @@ describe Rattler::BackEnd::Compiler do
|
|
237
287
|
it { should compile(rules).test_parsing 'abc123 ' }
|
238
288
|
it { should compile(rules).test_parsing ' ' }
|
239
289
|
end
|
240
|
-
|
290
|
+
|
241
291
|
context 'with a nested one_or_more rule' do
|
242
292
|
let(:rules) { define_parser do
|
243
293
|
rule(:word) { assert(one_or_more(/\w/)) }
|
@@ -245,7 +295,23 @@ describe Rattler::BackEnd::Compiler do
|
|
245
295
|
it { should compile(rules).test_parsing 'abc123 ' }
|
246
296
|
it { should compile(rules).test_parsing ' ' }
|
247
297
|
end
|
248
|
-
|
298
|
+
|
299
|
+
context 'with a nested list rule' do
|
300
|
+
let(:rules) { define_parser do
|
301
|
+
rule(:word) { assert(list(/\w+/, /,/)) }
|
302
|
+
end }
|
303
|
+
it { should compile(rules).test_parsing 'abc,123 ' }
|
304
|
+
it { should compile(rules).test_parsing ' ' }
|
305
|
+
end
|
306
|
+
|
307
|
+
context 'with a nested list1 rule' do
|
308
|
+
let(:rules) { define_parser do
|
309
|
+
rule(:word) { assert(list(/\w+/, /,/)) }
|
310
|
+
end }
|
311
|
+
it { should compile(rules).test_parsing 'abc,123 ' }
|
312
|
+
it { should compile(rules).test_parsing ' ' }
|
313
|
+
end
|
314
|
+
|
249
315
|
context 'with a nested apply rule' do
|
250
316
|
let(:rules) { define_parser do
|
251
317
|
rule(:word) { assert /\w+/ }
|
@@ -254,7 +320,7 @@ describe Rattler::BackEnd::Compiler do
|
|
254
320
|
it { should compile(rules).test_parsing('abc123 ').as :foo }
|
255
321
|
it { should compile(rules).test_parsing ' ' }
|
256
322
|
end
|
257
|
-
|
323
|
+
|
258
324
|
context 'with a nested dispatch-action rule' do
|
259
325
|
let(:rules) { define_parser do
|
260
326
|
rule(:word) { assert(dispatch_action(/\w+/)) }
|
@@ -262,7 +328,7 @@ describe Rattler::BackEnd::Compiler do
|
|
262
328
|
it { should compile(rules).test_parsing 'abc123 ' }
|
263
329
|
it { should compile(rules).test_parsing ' ' }
|
264
330
|
end
|
265
|
-
|
331
|
+
|
266
332
|
context 'with a nested token rule' do
|
267
333
|
let(:rules) { define_parser do
|
268
334
|
rule(:word) { assert(token(match(/\w+/))) }
|
@@ -270,7 +336,7 @@ describe Rattler::BackEnd::Compiler do
|
|
270
336
|
it { should compile(rules).test_parsing 'abc123 ' }
|
271
337
|
it { should compile(rules).test_parsing ' ' }
|
272
338
|
end
|
273
|
-
|
339
|
+
|
274
340
|
context 'with a nested skip rule' do
|
275
341
|
let(:rules) { define_parser do
|
276
342
|
rule(:word) { assert(skip(/\w+/)) }
|
@@ -279,10 +345,10 @@ describe Rattler::BackEnd::Compiler do
|
|
279
345
|
it { should compile(rules).test_parsing ' ' }
|
280
346
|
end
|
281
347
|
end
|
282
|
-
|
348
|
+
|
283
349
|
########## disallow ##########
|
284
350
|
context 'given a disallow rule' do
|
285
|
-
|
351
|
+
|
286
352
|
context 'with a nested match rule' do
|
287
353
|
let(:rules) { define_parser do
|
288
354
|
rule(:word) { disallow /\w+/ }
|
@@ -290,7 +356,7 @@ describe Rattler::BackEnd::Compiler do
|
|
290
356
|
it { should compile(rules).test_parsing ' ' }
|
291
357
|
it { should compile(rules).test_parsing 'abc123 ' }
|
292
358
|
end
|
293
|
-
|
359
|
+
|
294
360
|
context 'with a nested choice rule' do
|
295
361
|
let(:rules) { define_parser do
|
296
362
|
rule(:word) { disallow(match(/[[:alpha:]]/) | match(/[[:digit:]]/)) }
|
@@ -298,7 +364,7 @@ describe Rattler::BackEnd::Compiler do
|
|
298
364
|
it { should compile(rules).test_parsing('abc123 ').twice }
|
299
365
|
it { should compile(rules).test_parsing ' ' }
|
300
366
|
end
|
301
|
-
|
367
|
+
|
302
368
|
context 'with a nested sequence rule' do
|
303
369
|
let(:rules) { define_parser do
|
304
370
|
rule(:word) { disallow(match(/[[:alpha:]]/) & match(/[[:digit:]]/)) }
|
@@ -306,7 +372,7 @@ describe Rattler::BackEnd::Compiler do
|
|
306
372
|
it { should compile(rules).test_parsing 'abc123 ' }
|
307
373
|
it { should compile(rules).test_parsing ' ' }
|
308
374
|
end
|
309
|
-
|
375
|
+
|
310
376
|
context 'with a nested optional rule' do
|
311
377
|
let(:rules) { define_parser do
|
312
378
|
rule(:word) { disallow(optional(/\w+/)) }
|
@@ -314,7 +380,7 @@ describe Rattler::BackEnd::Compiler do
|
|
314
380
|
it { should compile(rules).test_parsing 'abc123 ' }
|
315
381
|
it { should compile(rules).test_parsing ' ' }
|
316
382
|
end
|
317
|
-
|
383
|
+
|
318
384
|
context 'with a nested zero_or_more rule' do
|
319
385
|
let(:rules) { define_parser do
|
320
386
|
rule(:word) { disallow(zero_or_more(/\w/)) }
|
@@ -322,7 +388,7 @@ describe Rattler::BackEnd::Compiler do
|
|
322
388
|
it { should compile(rules).test_parsing 'abc123 ' }
|
323
389
|
it { should compile(rules).test_parsing ' ' }
|
324
390
|
end
|
325
|
-
|
391
|
+
|
326
392
|
context 'with a nested one_or_more rule' do
|
327
393
|
let(:rules) { define_parser do
|
328
394
|
rule(:word) { disallow(one_or_more(/\w/)) }
|
@@ -330,7 +396,7 @@ describe Rattler::BackEnd::Compiler do
|
|
330
396
|
it { should compile(rules).test_parsing 'abc123 ' }
|
331
397
|
it { should compile(rules).test_parsing ' ' }
|
332
398
|
end
|
333
|
-
|
399
|
+
|
334
400
|
context 'with a nested apply rule' do
|
335
401
|
let(:rules) { define_parser do
|
336
402
|
rule(:word) { disallow /\w+/ }
|
@@ -339,7 +405,7 @@ describe Rattler::BackEnd::Compiler do
|
|
339
405
|
it { should compile(rules).test_parsing ' ' }
|
340
406
|
it { should compile(rules).test_parsing('abc123 ').as :foo }
|
341
407
|
end
|
342
|
-
|
408
|
+
|
343
409
|
context 'with a nested token rule' do
|
344
410
|
let(:rules) { define_parser do
|
345
411
|
rule(:word) { disallow(token(match(/\w+/))) }
|
@@ -347,7 +413,7 @@ describe Rattler::BackEnd::Compiler do
|
|
347
413
|
it { should compile(rules).test_parsing 'abc123 ' }
|
348
414
|
it { should compile(rules).test_parsing ' ' }
|
349
415
|
end
|
350
|
-
|
416
|
+
|
351
417
|
context 'with a nested skip rule' do
|
352
418
|
let(:rules) { define_parser do
|
353
419
|
rule(:word) { disallow(skip(/\w+/)) }
|
@@ -356,10 +422,10 @@ describe Rattler::BackEnd::Compiler do
|
|
356
422
|
it { should compile(rules).test_parsing ' ' }
|
357
423
|
end
|
358
424
|
end
|
359
|
-
|
425
|
+
|
360
426
|
########## dispatch_action ##########
|
361
427
|
context 'given a dispatch-action rule' do
|
362
|
-
|
428
|
+
|
363
429
|
context 'with a nested match rule' do
|
364
430
|
let(:rules) { define_parser do
|
365
431
|
rule(:digits) { dispatch_action(/\d+/) }
|
@@ -367,17 +433,17 @@ describe Rattler::BackEnd::Compiler do
|
|
367
433
|
it { should compile(rules).test_parsing '451a' }
|
368
434
|
it { should compile(rules).test_parsing ' ' }
|
369
435
|
end
|
370
|
-
|
436
|
+
|
371
437
|
context 'with a nested choice rule' do
|
372
438
|
let(:rules) { define_parser do
|
373
439
|
rule :atom do
|
374
440
|
dispatch_action(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/))
|
375
441
|
end
|
376
442
|
end }
|
377
|
-
|
443
|
+
|
378
444
|
it { should compile(rules).test_parsing '451a' }
|
379
445
|
it { should compile(rules).test_parsing ' ' }
|
380
|
-
|
446
|
+
|
381
447
|
context 'with labels' do
|
382
448
|
let(:rules) { define_parser do
|
383
449
|
rule :assignment do
|
@@ -391,7 +457,7 @@ describe Rattler::BackEnd::Compiler do
|
|
391
457
|
it { should compile(rules).test_parsing '42 ' }
|
392
458
|
end
|
393
459
|
end
|
394
|
-
|
460
|
+
|
395
461
|
context 'with a nested sequence rule' do
|
396
462
|
let(:rules) { define_parser do
|
397
463
|
rule :assignment do
|
@@ -402,10 +468,10 @@ describe Rattler::BackEnd::Compiler do
|
|
402
468
|
)
|
403
469
|
end
|
404
470
|
end }
|
405
|
-
|
471
|
+
|
406
472
|
it { should compile(rules).test_parsing 'val=42 ' }
|
407
473
|
it { should compile(rules).test_parsing 'val=x' }
|
408
|
-
|
474
|
+
|
409
475
|
context 'with labels' do
|
410
476
|
let(:rules) { define_parser do
|
411
477
|
rule :assignment do
|
@@ -419,7 +485,7 @@ describe Rattler::BackEnd::Compiler do
|
|
419
485
|
it { should compile(rules).test_parsing 'val=42 ' }
|
420
486
|
end
|
421
487
|
end
|
422
|
-
|
488
|
+
|
423
489
|
context 'with a nested optional rule' do
|
424
490
|
let(:rules) { define_parser do
|
425
491
|
rule :foo do
|
@@ -429,7 +495,7 @@ describe Rattler::BackEnd::Compiler do
|
|
429
495
|
it { should compile(rules).test_parsing 'foo ' }
|
430
496
|
it { should compile(rules).test_parsing ' ' }
|
431
497
|
end
|
432
|
-
|
498
|
+
|
433
499
|
context 'with a nested zero-or-more rule' do
|
434
500
|
let(:rules) { define_parser do
|
435
501
|
rule :foo do
|
@@ -439,7 +505,7 @@ describe Rattler::BackEnd::Compiler do
|
|
439
505
|
it { should compile(rules).test_parsing 'foo ' }
|
440
506
|
it { should compile(rules).test_parsing ' ' }
|
441
507
|
end
|
442
|
-
|
508
|
+
|
443
509
|
context 'with a nested one-or-more rule' do
|
444
510
|
let(:rules) { define_parser do
|
445
511
|
rule :foo do
|
@@ -449,7 +515,7 @@ describe Rattler::BackEnd::Compiler do
|
|
449
515
|
it { should compile(rules).test_parsing 'foo ' }
|
450
516
|
it { should compile(rules).test_parsing ' ' }
|
451
517
|
end
|
452
|
-
|
518
|
+
|
453
519
|
context 'with a nested apply rule' do
|
454
520
|
let(:rules) { define_parser do
|
455
521
|
rule(:digit) { match /\d/ }
|
@@ -458,7 +524,7 @@ describe Rattler::BackEnd::Compiler do
|
|
458
524
|
it { should compile(rules).test_parsing('451a').twice.as :foo }
|
459
525
|
it { should compile(rules).test_parsing(' ').as :foo }
|
460
526
|
end
|
461
|
-
|
527
|
+
|
462
528
|
context 'with a nested token rule' do
|
463
529
|
let(:rules) { define_parser do
|
464
530
|
rule :foo do
|
@@ -468,7 +534,7 @@ describe Rattler::BackEnd::Compiler do
|
|
468
534
|
it { should compile(rules).test_parsing 'abc123' }
|
469
535
|
it { should compile(rules).test_parsing ' ' }
|
470
536
|
end
|
471
|
-
|
537
|
+
|
472
538
|
context 'with a nested skip rule' do
|
473
539
|
let(:rules) { define_parser do
|
474
540
|
rule :foo do
|
@@ -479,10 +545,10 @@ describe Rattler::BackEnd::Compiler do
|
|
479
545
|
it { should compile(rules).test_parsing ' ' }
|
480
546
|
end
|
481
547
|
end
|
482
|
-
|
548
|
+
|
483
549
|
########## direct_action ##########
|
484
550
|
context 'given a direct-action rule' do
|
485
|
-
|
551
|
+
|
486
552
|
context 'with a nested match rule' do
|
487
553
|
let(:rules) { define_parser do
|
488
554
|
rule(:num) { direct_action(/\d+/, '|_| _.to_i') }
|
@@ -490,7 +556,7 @@ describe Rattler::BackEnd::Compiler do
|
|
490
556
|
it { should compile(rules).test_parsing '451a' }
|
491
557
|
it { should compile(rules).test_parsing ' ' }
|
492
558
|
end
|
493
|
-
|
559
|
+
|
494
560
|
context 'with a nested choice rule' do
|
495
561
|
let(:rules) { define_parser do
|
496
562
|
rule :foo do
|
@@ -500,12 +566,12 @@ describe Rattler::BackEnd::Compiler do
|
|
500
566
|
)
|
501
567
|
end
|
502
568
|
end }
|
503
|
-
|
569
|
+
|
504
570
|
it { should compile(rules).test_parsing 'abc123' }
|
505
571
|
it { should compile(rules).test_parsing '451a' }
|
506
572
|
it { should compile(rules).test_parsing ' ' }
|
507
573
|
end
|
508
|
-
|
574
|
+
|
509
575
|
context 'with a nested sequence rule' do
|
510
576
|
let(:rules) { define_parser do
|
511
577
|
rule :assignment do
|
@@ -515,10 +581,10 @@ describe Rattler::BackEnd::Compiler do
|
|
515
581
|
)
|
516
582
|
end
|
517
583
|
end }
|
518
|
-
|
584
|
+
|
519
585
|
it { should compile(rules).test_parsing 'val=42 ' }
|
520
586
|
it { should compile(rules).test_parsing 'val=x' }
|
521
|
-
|
587
|
+
|
522
588
|
context 'with labels' do
|
523
589
|
let(:rules) { define_parser do
|
524
590
|
rule :assignment do
|
@@ -531,7 +597,7 @@ describe Rattler::BackEnd::Compiler do
|
|
531
597
|
it { should compile(rules).test_parsing 'val=42 ' }
|
532
598
|
end
|
533
599
|
end
|
534
|
-
|
600
|
+
|
535
601
|
context 'with a nested optional rule' do
|
536
602
|
let(:rules) { define_parser do
|
537
603
|
rule :foo do
|
@@ -541,7 +607,7 @@ describe Rattler::BackEnd::Compiler do
|
|
541
607
|
it { should compile(rules).test_parsing 'foo ' }
|
542
608
|
it { should compile(rules).test_parsing ' ' }
|
543
609
|
end
|
544
|
-
|
610
|
+
|
545
611
|
context 'with a nested zero-or-more rule' do
|
546
612
|
let(:rules) { define_parser do
|
547
613
|
rule :foo do
|
@@ -551,7 +617,7 @@ describe Rattler::BackEnd::Compiler do
|
|
551
617
|
it { should compile(rules).test_parsing 'foo ' }
|
552
618
|
it { should compile(rules).test_parsing ' ' }
|
553
619
|
end
|
554
|
-
|
620
|
+
|
555
621
|
context 'with a nested one-or-more rule' do
|
556
622
|
let(:rules) { define_parser do
|
557
623
|
rule :foo do
|
@@ -561,7 +627,7 @@ describe Rattler::BackEnd::Compiler do
|
|
561
627
|
it { should compile(rules).test_parsing 'foo ' }
|
562
628
|
it { should compile(rules).test_parsing ' ' }
|
563
629
|
end
|
564
|
-
|
630
|
+
|
565
631
|
context 'with a nested apply rule' do
|
566
632
|
let(:rules) { define_parser do
|
567
633
|
rule(:digit) { match /\d/ }
|
@@ -570,7 +636,7 @@ describe Rattler::BackEnd::Compiler do
|
|
570
636
|
it { should compile(rules).test_parsing('451a').twice.as :foo }
|
571
637
|
it { should compile(rules).test_parsing(' ').as :foo }
|
572
638
|
end
|
573
|
-
|
639
|
+
|
574
640
|
context 'with a nested token rule' do
|
575
641
|
let(:rules) { define_parser do
|
576
642
|
rule :foo do
|
@@ -580,7 +646,7 @@ describe Rattler::BackEnd::Compiler do
|
|
580
646
|
it { should compile(rules).test_parsing 'abc123' }
|
581
647
|
it { should compile(rules).test_parsing ' ' }
|
582
648
|
end
|
583
|
-
|
649
|
+
|
584
650
|
context 'with a nested skip rule' do
|
585
651
|
let(:rules) { define_parser do
|
586
652
|
rule :foo do
|
@@ -591,10 +657,10 @@ describe Rattler::BackEnd::Compiler do
|
|
591
657
|
it { should compile(rules).test_parsing ' ' }
|
592
658
|
end
|
593
659
|
end
|
594
|
-
|
660
|
+
|
595
661
|
########## token ##########
|
596
662
|
context 'given a token rule' do
|
597
|
-
|
663
|
+
|
598
664
|
context 'with a nested match rule' do
|
599
665
|
let(:rules) { define_parser do
|
600
666
|
rule(:digits) { token(match(/\d+/)) }
|
@@ -602,17 +668,17 @@ describe Rattler::BackEnd::Compiler do
|
|
602
668
|
it { should compile(rules).test_parsing '451a' }
|
603
669
|
it { should compile(rules).test_parsing 'hi' }
|
604
670
|
end
|
605
|
-
|
671
|
+
|
606
672
|
context 'with a nested choice rule' do
|
607
673
|
let(:rules) { define_parser do
|
608
674
|
rule(:atom) do
|
609
675
|
token(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/))
|
610
676
|
end
|
611
677
|
end }
|
612
|
-
|
678
|
+
|
613
679
|
it { should compile(rules).test_parsing 'abc123 ' }
|
614
680
|
it { should compile(rules).test_parsing '==' }
|
615
|
-
|
681
|
+
|
616
682
|
context 'with non-capturing choices' do
|
617
683
|
let(:rules) { define_parser do
|
618
684
|
rule(:atom) do
|
@@ -623,17 +689,17 @@ describe Rattler::BackEnd::Compiler do
|
|
623
689
|
it { should compile(rules).test_parsing '==' }
|
624
690
|
end
|
625
691
|
end
|
626
|
-
|
692
|
+
|
627
693
|
context 'with a nested sequence rule' do
|
628
694
|
let(:rules) { define_parser do
|
629
695
|
rule(:atom) do
|
630
696
|
token(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/))
|
631
697
|
end
|
632
698
|
end }
|
633
|
-
|
699
|
+
|
634
700
|
it { should compile(rules).test_parsing 'foo42!' }
|
635
701
|
it { should compile(rules).test_parsing 'val=x' }
|
636
|
-
|
702
|
+
|
637
703
|
context 'with non-capturing parsers' do
|
638
704
|
let(:rules) { define_parser do
|
639
705
|
rule :foo do
|
@@ -644,17 +710,17 @@ describe Rattler::BackEnd::Compiler do
|
|
644
710
|
it { should compile(rules).test_parsing 'foo bar' }
|
645
711
|
end
|
646
712
|
end
|
647
|
-
|
713
|
+
|
648
714
|
context 'with a nested optional rule' do
|
649
715
|
let(:rules) { define_parser do
|
650
716
|
rule :foo do
|
651
717
|
token(optional(/\w+/))
|
652
718
|
end
|
653
719
|
end }
|
654
|
-
|
720
|
+
|
655
721
|
it { should compile(rules).test_parsing 'foo ' }
|
656
722
|
it { should compile(rules).test_parsing ' ' }
|
657
|
-
|
723
|
+
|
658
724
|
context 'with a non-capturing rule' do
|
659
725
|
let(:rules) { define_parser do
|
660
726
|
rule :foo do
|
@@ -665,17 +731,17 @@ describe Rattler::BackEnd::Compiler do
|
|
665
731
|
it { should compile(rules).test_parsing ' ' }
|
666
732
|
end
|
667
733
|
end
|
668
|
-
|
734
|
+
|
669
735
|
context 'with a nested zero-or-more rule' do
|
670
736
|
let(:rules) { define_parser do
|
671
737
|
rule :foo do
|
672
738
|
token(zero_or_more(/\w/))
|
673
739
|
end
|
674
740
|
end }
|
675
|
-
|
741
|
+
|
676
742
|
it { should compile(rules).test_parsing 'foo ' }
|
677
743
|
it { should compile(rules).test_parsing ' ' }
|
678
|
-
|
744
|
+
|
679
745
|
context 'with a non-capturing rule' do
|
680
746
|
let(:rules) { define_parser do
|
681
747
|
rule :foo do
|
@@ -686,17 +752,17 @@ describe Rattler::BackEnd::Compiler do
|
|
686
752
|
it { should compile(rules).test_parsing ' ' }
|
687
753
|
end
|
688
754
|
end
|
689
|
-
|
755
|
+
|
690
756
|
context 'with a nested one-or-more rule' do
|
691
757
|
let(:rules) { define_parser do
|
692
758
|
rule :foo do
|
693
759
|
token(one_or_more(/\w/))
|
694
760
|
end
|
695
761
|
end }
|
696
|
-
|
762
|
+
|
697
763
|
it { should compile(rules).test_parsing 'foo ' }
|
698
764
|
it { should compile(rules).test_parsing ' ' }
|
699
|
-
|
765
|
+
|
700
766
|
context 'with a non-capturing rule' do
|
701
767
|
let(:rules) { define_parser do
|
702
768
|
rule :foo do
|
@@ -707,16 +773,16 @@ describe Rattler::BackEnd::Compiler do
|
|
707
773
|
it { should compile(rules).test_parsing ' ' }
|
708
774
|
end
|
709
775
|
end
|
710
|
-
|
776
|
+
|
711
777
|
context 'with a nested apply rule' do
|
712
778
|
let(:rules) { define_parser do
|
713
779
|
rule(:digits) { match(/\d+/) }
|
714
780
|
rule(:foo) { token(match(:digits)) }
|
715
781
|
end }
|
716
|
-
|
782
|
+
|
717
783
|
it { should compile(rules).test_parsing('451a').as :foo }
|
718
784
|
it { should compile(rules).test_parsing 'hi' }
|
719
|
-
|
785
|
+
|
720
786
|
context 'applying a non-capturing rule' do
|
721
787
|
let(:rules) { define_parser do
|
722
788
|
rule(:digits) { skip(/\d+/) }
|
@@ -726,7 +792,7 @@ describe Rattler::BackEnd::Compiler do
|
|
726
792
|
it { should compile(rules).test_parsing 'hi' }
|
727
793
|
end
|
728
794
|
end
|
729
|
-
|
795
|
+
|
730
796
|
context 'with a nested dispatch-action rule' do
|
731
797
|
let(:rules) { define_parser do
|
732
798
|
rule(:foo) { token(dispatch_action(/\w+/)) }
|
@@ -734,7 +800,7 @@ describe Rattler::BackEnd::Compiler do
|
|
734
800
|
it { should compile(rules).test_parsing 'abc123' }
|
735
801
|
it { should compile(rules).test_parsing ' ' }
|
736
802
|
end
|
737
|
-
|
803
|
+
|
738
804
|
context 'with a nested skip rule' do
|
739
805
|
let(:rules) { define_parser do
|
740
806
|
rule(:foo) { token(skip(/\w+/)) }
|
@@ -743,10 +809,10 @@ describe Rattler::BackEnd::Compiler do
|
|
743
809
|
it { should compile(rules).test_parsing ' ' }
|
744
810
|
end
|
745
811
|
end
|
746
|
-
|
812
|
+
|
747
813
|
########## skip ##########
|
748
814
|
context 'given a skip rule' do
|
749
|
-
|
815
|
+
|
750
816
|
context 'with a nested match rule' do
|
751
817
|
let(:rules) { define_parser do
|
752
818
|
rule(:ws) { skip(/\s+/) }
|
@@ -754,7 +820,7 @@ describe Rattler::BackEnd::Compiler do
|
|
754
820
|
it { should compile(rules).test_parsing ' foo' }
|
755
821
|
it { should compile(rules).test_parsing 'hi' }
|
756
822
|
end
|
757
|
-
|
823
|
+
|
758
824
|
context 'with a nested choice rule' do
|
759
825
|
let(:rules) { define_parser do
|
760
826
|
rule(:ws) do
|
@@ -764,7 +830,7 @@ describe Rattler::BackEnd::Compiler do
|
|
764
830
|
it { should compile(rules).test_parsing(' # hi there ').twice }
|
765
831
|
it { should compile(rules).test_parsing 'hi' }
|
766
832
|
end
|
767
|
-
|
833
|
+
|
768
834
|
context 'with a nested sequence rule' do
|
769
835
|
let(:rules) { define_parser do
|
770
836
|
rule :foo do
|
@@ -774,7 +840,7 @@ describe Rattler::BackEnd::Compiler do
|
|
774
840
|
it { should compile(rules).test_parsing 'foo42!' }
|
775
841
|
it { should compile(rules).test_parsing 'val=x' }
|
776
842
|
end
|
777
|
-
|
843
|
+
|
778
844
|
context 'with a nested optional rule' do
|
779
845
|
let(:rules) { define_parser do
|
780
846
|
rule :foo do
|
@@ -784,7 +850,7 @@ describe Rattler::BackEnd::Compiler do
|
|
784
850
|
it { should compile(rules).test_parsing 'foo ' }
|
785
851
|
it { should compile(rules).test_parsing ' ' }
|
786
852
|
end
|
787
|
-
|
853
|
+
|
788
854
|
context 'with a nested zero-or-more rule' do
|
789
855
|
let(:rules) { define_parser do
|
790
856
|
rule :foo do
|
@@ -794,7 +860,7 @@ describe Rattler::BackEnd::Compiler do
|
|
794
860
|
it { should compile(rules).test_parsing 'foo ' }
|
795
861
|
it { should compile(rules).test_parsing ' ' }
|
796
862
|
end
|
797
|
-
|
863
|
+
|
798
864
|
context 'with a nested one-or-more rule' do
|
799
865
|
let(:rules) { define_parser do
|
800
866
|
rule :foo do
|
@@ -804,7 +870,7 @@ describe Rattler::BackEnd::Compiler do
|
|
804
870
|
it { should compile(rules).test_parsing 'foo ' }
|
805
871
|
it { should compile(rules).test_parsing ' ' }
|
806
872
|
end
|
807
|
-
|
873
|
+
|
808
874
|
context 'with a nested apply rule' do
|
809
875
|
let(:rules) { define_parser do
|
810
876
|
rule(:digits) { match(/\d+/) }
|
@@ -814,11 +880,11 @@ describe Rattler::BackEnd::Compiler do
|
|
814
880
|
it { should compile(rules).test_parsing('hi').as :foo }
|
815
881
|
end
|
816
882
|
end
|
817
|
-
|
883
|
+
|
818
884
|
end
|
819
|
-
|
885
|
+
|
820
886
|
def have_method(rule_name)
|
821
887
|
be_method_defined(rule_name)
|
822
888
|
end
|
823
|
-
|
889
|
+
|
824
890
|
end
|