citrus 2.1.2 → 2.2.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.
@@ -1,7 +1,6 @@
1
1
  require File.expand_path('../helper', __FILE__)
2
2
 
3
- class RuleTest < Test::Unit::TestCase
4
-
3
+ class ExtensionTest < Test::Unit::TestCase
5
4
  module MatchModule
6
5
  def a_test
7
6
  :test
@@ -16,37 +15,39 @@ class RuleTest < Test::Unit::TestCase
16
15
 
17
16
  NumericModule = Module.new(&NumericProc)
18
17
 
19
- def test_create
20
- rule = Rule.eval('"a"')
21
- assert(rule)
22
- match = rule.match(input('a'))
23
- assert(match)
24
- end
18
+ NumericProcBare = Proc.new {
19
+ to_i + 1
20
+ }
25
21
 
26
22
  def test_match_module
27
- rule = EqualRule.new('a')
23
+ rule = StringTerminal.new('abc')
28
24
  rule.extension = MatchModule
29
- match = rule.match(input('a'))
25
+ match = rule.parse('abc')
30
26
  assert(match)
31
27
  assert_equal(:test, match.a_test)
32
28
  end
33
29
 
34
30
  def test_numeric_proc
35
- rule = EqualRule.new(1)
31
+ rule = StringTerminal.new('1')
36
32
  rule.extension = NumericProc
37
- match = rule.match(input('1'))
33
+ match = rule.parse('1')
38
34
  assert(match)
39
35
  assert_equal(2, match.add_one)
40
- assert_instance_of(Float, match.to_f)
41
36
  end
42
37
 
43
38
  def test_numeric_module
44
- rule = EqualRule.new(1)
39
+ rule = StringTerminal.new('1')
45
40
  rule.extension = NumericModule
46
- match = rule.match(input('1'))
41
+ match = rule.parse('1')
47
42
  assert(match)
48
43
  assert_equal(2, match.add_one)
49
- assert_instance_of(Float, match.to_f)
50
44
  end
51
45
 
46
+ def test_numeric_proc_bare
47
+ rule = StringTerminal.new('1')
48
+ rule.extension = NumericProcBare
49
+ match = rule.parse('1')
50
+ assert(match)
51
+ assert_equal(2, match.value)
52
+ end
52
53
  end
data/test/file_test.rb CHANGED
@@ -1,324 +1,335 @@
1
1
  require File.expand_path('../helper', __FILE__)
2
- require 'citrus/file'
3
2
 
4
3
  class CitrusFileTest < Test::Unit::TestCase
5
4
 
6
- # A shortcut for creating a grammar that includes Citrus::File but uses a
7
- # different root.
8
- def file(root_rule)
9
- Grammar.new do
10
- include Citrus::File
11
- root root_rule
12
- end
13
- end
14
-
15
5
  ## File tests
16
6
 
17
7
  def run_file_test(file, root)
18
- grammar = file(root)
19
- code = F.read(file)
20
- match = grammar.parse(code)
8
+ match = File.parse(F.read(file), :root => root)
21
9
  assert(match)
22
10
  end
23
11
 
24
- %w< rule grammar >.each do |type|
12
+ %w<rule grammar>.each do |type|
25
13
  Dir[F.dirname(__FILE__) + "/_files/#{type}*.citrus"].each do |path|
26
- module_eval(<<-RUBY.gsub(/^ /, ''), __FILE__, __LINE__ + 1)
14
+ module_eval(<<-CODE.gsub(/^ /, ''), __FILE__, __LINE__ + 1)
27
15
  def test_#{F.basename(path, '.citrus')}
28
16
  run_file_test("#{path}", :#{type})
29
17
  end
30
- RUBY
18
+ CODE
31
19
  end
32
20
  end
33
21
 
34
22
  ## Hierarchical syntax
35
23
 
36
- def test_rule_body
37
- grammar = file(:rule_body)
38
-
39
- match = grammar.parse('"a" | "b"')
40
- assert(match)
41
- assert_kind_of(Rule, match.value)
42
- assert_instance_of(Choice, match.value)
43
-
44
- match = grammar.parse('rule_name')
24
+ def test_rule_body_alias
25
+ match = File.parse('rule_name', :root => :rule_body)
45
26
  assert(match)
46
27
  assert_kind_of(Rule, match.value)
47
28
  assert_instance_of(Alias, match.value)
29
+ end
48
30
 
49
- match = grammar.parse('""')
31
+ def test_rule_body_terminal
32
+ match = File.parse('.', :root => :rule_body)
50
33
  assert(match)
51
34
  assert_kind_of(Rule, match.value)
52
35
  assert_instance_of(Terminal, match.value)
53
36
 
54
- match = grammar.parse('"a"')
37
+ match = File.parse('[a-z]', :root => :rule_body)
55
38
  assert(match)
56
39
  assert_kind_of(Rule, match.value)
57
40
  assert_instance_of(Terminal, match.value)
58
41
 
59
- match = grammar.parse('"a" "b"')
42
+ match = File.parse('/./', :root => :rule_body)
60
43
  assert(match)
61
44
  assert_kind_of(Rule, match.value)
62
- assert_instance_of(Sequence, match.value)
45
+ assert_instance_of(Terminal, match.value)
63
46
 
64
- match = grammar.parse('"a" | "b"')
47
+ match = File.parse("[0-9] {\n def value\n text.to_i\n end\n}\n", :root => :rule_body)
65
48
  assert(match)
66
49
  assert_kind_of(Rule, match.value)
67
- assert_instance_of(Choice, match.value)
50
+ assert_instance_of(Terminal, match.value)
51
+ end
68
52
 
69
- match = grammar.parse('.')
53
+ def test_rule_body_string_terminal
54
+ match = File.parse('""', :root => :rule_body)
70
55
  assert(match)
71
56
  assert_kind_of(Rule, match.value)
72
- assert_instance_of(Terminal, match.value)
57
+ assert_instance_of(StringTerminal, match.value)
73
58
 
74
- match = grammar.parse('[a-z]')
59
+ match = File.parse('"a"', :root => :rule_body)
75
60
  assert(match)
76
61
  assert_kind_of(Rule, match.value)
77
- assert_instance_of(Terminal, match.value)
62
+ assert_instance_of(StringTerminal, match.value)
78
63
 
79
- match = grammar.parse('/./')
64
+ match = File.parse('"" {}', :root => :rule_body)
80
65
  assert(match)
81
66
  assert_kind_of(Rule, match.value)
82
- assert_instance_of(Terminal, match.value)
67
+ assert_instance_of(StringTerminal, match.value)
68
+ end
83
69
 
84
- match = grammar.parse('/./ /./')
70
+ def test_rule_body_repeat
71
+ match = File.parse('"a"*', :root => :rule_body)
85
72
  assert(match)
86
73
  assert_kind_of(Rule, match.value)
87
- assert_instance_of(Sequence, match.value)
88
- assert_equal(2, match.find(:regular_expression).length)
74
+ assert_instance_of(Repeat, match.value)
75
+ assert_equal(0, match.value.min)
76
+ assert_equal(Infinity, match.value.max)
89
77
 
90
- match = grammar.parse('/./ | /./')
78
+ match = File.parse('""* {}', :root => :rule_body)
91
79
  assert(match)
92
80
  assert_kind_of(Rule, match.value)
93
- assert_instance_of(Choice, match.value)
94
- assert_equal(1, match.find(:bar).length)
95
- assert_equal(2, match.find(:regular_expression).length)
96
- assert_equal(0, match.find(:dot).length)
81
+ assert_instance_of(Repeat, match.value)
97
82
 
98
- match = grammar.parse('"" {}')
83
+ match = File.parse('("a" "b")*', :root => :rule_body)
99
84
  assert(match)
100
85
  assert_kind_of(Rule, match.value)
101
- assert_instance_of(Terminal, match.value)
86
+ assert_instance_of(Repeat, match.value)
102
87
 
103
- match = grammar.parse('""* {}')
88
+ match = File.parse('("a" | "b")*', :root => :rule_body)
104
89
  assert(match)
105
90
  assert_kind_of(Rule, match.value)
106
91
  assert_instance_of(Repeat, match.value)
107
92
 
108
- match = grammar.parse('"a"*')
93
+ match = File.parse('("a" "b")* {}', :root => :rule_body)
109
94
  assert(match)
110
95
  assert_kind_of(Rule, match.value)
111
96
  assert_instance_of(Repeat, match.value)
112
- assert_equal(0, match.value.min)
113
- assert_equal(Infinity, match.value.max)
114
97
 
115
- match = grammar.parse('("a" "b")*')
98
+ match = File.parse('("a" | "b")* {}', :root => :rule_body)
116
99
  assert(match)
117
100
  assert_kind_of(Rule, match.value)
118
101
  assert_instance_of(Repeat, match.value)
119
102
 
120
- match = grammar.parse('"a" | "b"')
103
+ match = File.parse('("a" "b")* <Module>', :root => :rule_body)
121
104
  assert(match)
122
105
  assert_kind_of(Rule, match.value)
123
- assert_instance_of(Choice, match.value)
106
+ assert_instance_of(Repeat, match.value)
124
107
 
125
- match = grammar.parse('("a" | "b")*')
108
+ match = File.parse('( "a" "b" )* <Module>', :root => :rule_body)
126
109
  assert(match)
127
110
  assert_kind_of(Rule, match.value)
128
111
  assert_instance_of(Repeat, match.value)
129
112
 
130
- match = grammar.parse('("a" "b")* {}')
113
+ match = File.parse('("a" | "b")* <Module>', :root => :rule_body)
131
114
  assert(match)
132
115
  assert_kind_of(Rule, match.value)
133
116
  assert_instance_of(Repeat, match.value)
134
117
 
135
- match = grammar.parse('("a" | "b")* {}')
118
+ match = File.parse("[0-9]+ {\n def value\n text.to_i\n end\n}\n", :root => :rule_body)
136
119
  assert(match)
137
120
  assert_kind_of(Rule, match.value)
138
121
  assert_instance_of(Repeat, match.value)
122
+ end
139
123
 
140
- match = grammar.parse('("a" | /./)')
124
+ def test_rule_body_choice
125
+ match = File.parse('"a" | "b"', :root => :rule_body)
141
126
  assert(match)
142
127
  assert_kind_of(Rule, match.value)
143
128
  assert_instance_of(Choice, match.value)
144
129
 
145
- match = grammar.parse('"a" ("b" | /./)* {}')
130
+ match = File.parse('/./ | /./', :root => :rule_body)
146
131
  assert(match)
147
132
  assert_kind_of(Rule, match.value)
148
- assert_instance_of(Sequence, match.value)
133
+ assert_instance_of(Choice, match.value)
134
+ assert_equal(1, match.find(:bar).length)
135
+ assert_equal(2, match.find(:regular_expression).length)
136
+ assert_equal(0, match.find(:dot).length)
149
137
 
150
- match = grammar.parse('("a" "b")* <Module>')
138
+ match = File.parse('("a" | /./)', :root => :rule_body)
151
139
  assert(match)
152
140
  assert_kind_of(Rule, match.value)
153
- assert_instance_of(Repeat, match.value)
141
+ assert_instance_of(Choice, match.value)
154
142
 
155
- match = grammar.parse('( "a" "b" )* <Module>')
143
+ match = File.parse('("a" | "b") <Module>', :root => :rule_body)
156
144
  assert(match)
157
145
  assert_kind_of(Rule, match.value)
158
- assert_instance_of(Repeat, match.value)
146
+ assert_instance_of(Choice, match.value)
147
+ end
159
148
 
160
- match = grammar.parse('( "a" "b" ) <Module>')
149
+ def test_rule_body_sequence
150
+ match = File.parse('"a" "b"', :root => :rule_body)
161
151
  assert(match)
162
152
  assert_kind_of(Rule, match.value)
163
153
  assert_instance_of(Sequence, match.value)
164
154
 
165
- match = grammar.parse('("a" | "b")* <Module>')
166
- assert(match)
167
- assert_kind_of(Rule, match.value)
168
- assert_instance_of(Repeat, match.value)
169
-
170
- match = grammar.parse('("a" | "b") <Module>')
155
+ match = File.parse('/./ /./', :root => :rule_body)
171
156
  assert(match)
172
157
  assert_kind_of(Rule, match.value)
173
- assert_instance_of(Choice, match.value)
158
+ assert_instance_of(Sequence, match.value)
159
+ assert_equal(2, match.find(:regular_expression).length)
174
160
 
175
- match = grammar.parse('"a" ("b" | /./)* <Module>')
161
+ match = File.parse('( "a" "b" ) <Module>', :root => :rule_body)
176
162
  assert(match)
177
163
  assert_kind_of(Rule, match.value)
178
164
  assert_instance_of(Sequence, match.value)
179
165
 
180
- match = grammar.parse("[0-9] {\n def value\n text.to_i\n end\n}\n")
166
+ match = File.parse('"a" ("b" | /./)* <Module>', :root => :rule_body)
181
167
  assert(match)
182
168
  assert_kind_of(Rule, match.value)
183
- assert_instance_of(Terminal, match.value)
169
+ assert_instance_of(Sequence, match.value)
184
170
 
185
- match = grammar.parse("[0-9]+ {\n def value\n text.to_i\n end\n}\n")
171
+ match = File.parse('"a" ("b" | /./)* {}', :root => :rule_body)
186
172
  assert(match)
187
173
  assert_kind_of(Rule, match.value)
188
- assert_instance_of(Repeat, match.value)
174
+ assert_instance_of(Sequence, match.value)
189
175
  end
190
176
 
191
177
  def test_precedence
192
- grammar = file(:rule_body)
193
-
194
178
  # Sequence should bind more tightly than Choice.
195
- match = grammar.parse('"a" "b" | "c"')
179
+ match = File.parse('"a" "b" | "c"', :root => :rule_body)
196
180
  assert(match)
197
181
  assert_kind_of(Rule, match.value)
198
182
  assert_instance_of(Choice, match.value)
199
183
 
200
184
  # Parentheses should change binding precedence.
201
- match = grammar.parse('"a" ("b" | "c")')
185
+ match = File.parse('"a" ("b" | "c")', :root => :rule_body)
202
186
  assert(match)
203
187
  assert_kind_of(Rule, match.value)
204
188
  assert_instance_of(Sequence, match.value)
205
189
 
206
190
  # Repeat should bind more tightly than AndPredicate.
207
- match = grammar.parse("&'a'+")
191
+ match = File.parse("&'a'+", :root => :rule_body)
208
192
  assert(match)
209
193
  assert_kind_of(Rule, match.value)
210
194
  assert_instance_of(AndPredicate, match.value)
211
195
  end
212
196
 
213
- def test_empty
214
- grammar = file(:rule_body)
215
-
216
- match = grammar.parse('')
197
+ def test_rule_body_empty
198
+ match = File.parse('', :root => :rule_body)
217
199
  assert(match)
218
200
  end
219
201
 
220
202
  def test_choice
221
- grammar = file(:choice)
222
-
223
- match = grammar.parse('"a" | "b"')
203
+ match = File.parse('"a" | "b"', :root => :choice)
224
204
  assert(match)
225
205
  assert_equal(2, match.rules.length)
226
206
  assert_instance_of(Choice, match.value)
207
+ end
227
208
 
228
- match = grammar.parse('"a" | ("b" "c")')
209
+ def test_choice_embedded_sequence
210
+ match = File.parse('"a" | ("b" "c")', :root => :choice)
229
211
  assert(match)
230
212
  assert_equal(2, match.rules.length)
231
213
  assert_instance_of(Choice, match.value)
232
214
  end
233
215
 
234
216
  def test_sequence
235
- grammar = file(:sequence)
236
-
237
- match = grammar.parse('"" ""')
217
+ match = File.parse('"" ""', :root => :sequence)
238
218
  assert(match)
239
219
  assert_equal(2, match.rules.length)
240
220
  assert_instance_of(Sequence, match.value)
221
+ end
241
222
 
242
- match = grammar.parse('"a" "b" "c"')
223
+ def test_sequence_embedded_choice
224
+ match = File.parse('"a" ("b" | "c")', :root => :sequence)
243
225
  assert(match)
244
- assert_equal(3, match.rules.length)
226
+ assert_equal(2, match.rules.length)
245
227
  assert_instance_of(Sequence, match.value)
246
228
  end
247
229
 
248
- def test_expression
249
- grammar = file(:expression)
250
-
251
- match = grammar.parse('"" <Module>')
230
+ def test_expression_tag
231
+ match = File.parse('"" <Module>', :root => :expression)
252
232
  assert(match)
253
233
  assert_kind_of(Rule, match.value)
254
234
  assert_kind_of(Module, match.value.extension)
235
+ end
255
236
 
256
- match = grammar.parse('"" {}')
237
+ def test_expression_block
238
+ match = File.parse('"" {}', :root => :expression)
257
239
  assert(match)
258
240
  assert_kind_of(Rule, match.value)
259
241
  assert_kind_of(Module, match.value.extension)
242
+ end
260
243
 
261
- match = grammar.parse('"" {} ')
244
+ def test_expression_block_space
245
+ match = File.parse('"" {} ', :root => :expression)
262
246
  assert(match)
263
247
  assert_kind_of(Rule, match.value)
264
248
  assert_kind_of(Module, match.value.extension)
265
249
  end
266
250
 
267
- def test_prefix
268
- grammar = file(:prefix)
269
-
270
- match = grammar.parse('&""')
251
+ def test_prefix_and
252
+ match = File.parse('&""', :root => :prefix)
271
253
  assert(match)
272
254
  assert_kind_of(Rule, match.value)
273
255
  assert_instance_of(AndPredicate, match.value)
256
+ end
274
257
 
275
- match = grammar.parse('!""')
258
+ def test_prefix_not
259
+ match = File.parse('!""', :root => :prefix)
276
260
  assert(match)
277
261
  assert_kind_of(Rule, match.value)
278
262
  assert_instance_of(NotPredicate, match.value)
263
+ end
279
264
 
280
- match = grammar.parse('label:""')
265
+ def test_prefix_label
266
+ match = File.parse('label:""', :root => :prefix)
281
267
  assert(match)
282
268
  assert_kind_of(Rule, match.value)
283
269
  assert_instance_of(Label, match.value)
270
+ end
284
271
 
285
- match = grammar.parse('label :"" ')
272
+ def test_prefix_label_space
273
+ match = File.parse('label :"" ', :root => :prefix)
286
274
  assert(match)
287
275
  assert_kind_of(Rule, match.value)
288
276
  assert_instance_of(Label, match.value)
289
277
  end
290
278
 
291
- def test_suffix
292
- grammar = file(:suffix)
279
+ def test_suffix_plus
280
+ match = File.parse('""+', :root => :suffix)
281
+ assert(match)
282
+ assert_kind_of(Rule, match.value)
283
+ assert_instance_of(Repeat, match.value)
284
+ end
293
285
 
294
- match = grammar.parse('""+')
286
+ def test_suffix_question
287
+ match = File.parse('""? ', :root => :suffix)
295
288
  assert(match)
296
289
  assert_kind_of(Rule, match.value)
297
290
  assert_instance_of(Repeat, match.value)
291
+ end
298
292
 
299
- match = grammar.parse('""? ')
293
+ def test_suffix_star
294
+ match = File.parse('""*', :root => :suffix)
300
295
  assert(match)
301
296
  assert_kind_of(Rule, match.value)
302
297
  assert_instance_of(Repeat, match.value)
298
+ end
303
299
 
304
- match = grammar.parse('""1* ')
300
+ def test_suffix_n_star
301
+ match = File.parse('""1*', :root => :suffix)
305
302
  assert(match)
306
303
  assert_kind_of(Rule, match.value)
307
304
  assert_instance_of(Repeat, match.value)
308
305
  end
309
306
 
310
- def test_primary
311
- grammar = file(:primary)
307
+ def test_suffix_star_n
308
+ match = File.parse('""*2', :root => :suffix)
309
+ assert(match)
310
+ assert_kind_of(Rule, match.value)
311
+ assert_instance_of(Repeat, match.value)
312
+ end
312
313
 
313
- match = grammar.parse('rule_name')
314
+ def test_suffix_n_star_n
315
+ match = File.parse('""1*2', :root => :suffix)
316
+ assert(match)
317
+ assert_kind_of(Rule, match.value)
318
+ assert_instance_of(Repeat, match.value)
319
+ end
320
+
321
+ def test_primary_alias
322
+ match = File.parse('rule_name', :root => :primary)
314
323
  assert(match)
315
324
  assert_kind_of(Rule, match.value)
316
325
  assert_instance_of(Alias, match.value)
326
+ end
317
327
 
318
- match = grammar.parse('"a"')
328
+ def test_primary_string_terminal
329
+ match = File.parse('"a"', :root => :primary)
319
330
  assert(match)
320
331
  assert_kind_of(Rule, match.value)
321
- assert_instance_of(Terminal, match.value)
332
+ assert_instance_of(StringTerminal, match.value)
322
333
  end
323
334
 
324
335
 
@@ -326,223 +337,279 @@ class CitrusFileTest < Test::Unit::TestCase
326
337
 
327
338
 
328
339
  def test_require
329
- grammar = file(:require)
330
-
331
- match = grammar.parse('require "some/file"')
340
+ match = File.parse('require "some/file"', :root => :require)
332
341
  assert(match)
333
342
  assert_equal('some/file', match.value)
343
+ end
334
344
 
335
- match = grammar.parse('require"some/file"')
345
+ def test_require_no_space
346
+ match = File.parse('require"some/file"', :root => :require)
336
347
  assert(match)
337
348
  assert_equal('some/file', match.value)
349
+ end
338
350
 
339
- match = grammar.parse("require 'some/file'")
351
+ def test_require_single_quoted
352
+ match = File.parse("require 'some/file'", :root => :require)
340
353
  assert(match)
341
354
  assert_equal('some/file', match.value)
342
355
  end
343
356
 
344
357
  def test_include
345
- grammar = file(:include)
346
-
347
- match = grammar.parse('include Module')
358
+ match = File.parse('include Module', :root => :include)
348
359
  assert(match)
349
360
  assert_equal(Module, match.value)
361
+ end
350
362
 
351
- match = grammar.parse('include ::Module')
363
+ def test_include_colon_colon
364
+ match = File.parse('include ::Module', :root => :include)
352
365
  assert(match)
353
366
  assert_equal(Module, match.value)
354
367
  end
355
368
 
356
369
  def test_root
357
- grammar = file(:root)
358
-
359
- match = grammar.parse('root some_rule')
370
+ match = File.parse('root some_rule', :root => :root)
360
371
  assert(match)
361
372
  assert_equal('some_rule', match.value)
373
+ end
362
374
 
375
+ def test_root_invalid
363
376
  assert_raise ParseError do
364
- match = grammar.parse('root :a_root')
377
+ File.parse('root :a_root', :root => :root)
365
378
  end
366
379
  end
367
380
 
368
381
  def test_rule_name
369
- grammar = file(:rule_name)
370
-
371
- match = grammar.parse('some_rule')
382
+ match = File.parse('some_rule', :root => :rule_name)
372
383
  assert(match)
373
384
  assert('some_rule', match.value)
385
+ end
374
386
 
375
- match = grammar.parse('some_rule ')
387
+ def test_rule_name_space
388
+ match = File.parse('some_rule ', :root => :rule_name)
376
389
  assert(match)
377
390
  assert('some_rule', match.value)
378
391
  end
379
392
 
380
- def test_terminal
381
- grammar = file(:terminal)
382
-
383
- match = grammar.parse('"a"')
393
+ def test_terminal_character_class
394
+ match = File.parse('[a-z]', :root => :terminal)
384
395
  assert(match)
385
396
  assert_kind_of(Rule, match.value)
386
397
  assert_instance_of(Terminal, match.value)
387
- assert(match.value.terminal?)
398
+ end
388
399
 
389
- match = grammar.parse('[a-z]')
400
+ def test_terminal_dot
401
+ match = File.parse('.', :root => :terminal)
390
402
  assert(match)
391
403
  assert_kind_of(Rule, match.value)
392
404
  assert_instance_of(Terminal, match.value)
393
- assert(match.value.terminal?)
405
+ end
394
406
 
395
- match = grammar.parse('.')
407
+ def test_terminal_regular_expression
408
+ match = File.parse('/./', :root => :terminal)
396
409
  assert(match)
397
410
  assert_kind_of(Rule, match.value)
398
411
  assert_instance_of(Terminal, match.value)
399
- assert(match.value.terminal?)
412
+ end
400
413
 
401
- match = grammar.parse('/./')
414
+ def test_string_terminal_single_quoted
415
+ match = File.parse("'a'", :root => :string_terminal)
402
416
  assert(match)
403
417
  assert_kind_of(Rule, match.value)
404
- assert_instance_of(Terminal, match.value)
405
- assert(match.value.terminal?)
418
+ assert_instance_of(StringTerminal, match.value)
406
419
  end
407
420
 
408
- def test_single_quoted_string
409
- grammar = file(:quoted_string)
421
+ def test_string_terminal_double_quoted
422
+ match = File.parse('"a"', :root => :string_terminal)
423
+ assert(match)
424
+ assert_kind_of(Rule, match.value)
425
+ assert_instance_of(StringTerminal, match.value)
426
+ end
427
+
428
+ def test_string_terminal_case_insensitive
429
+ match = File.parse('`a`', :root => :string_terminal)
430
+ assert(match)
431
+ assert_kind_of(Rule, match.value)
432
+ assert_instance_of(StringTerminal, match.value)
433
+ end
410
434
 
411
- match = grammar.parse("'test'")
435
+ def test_single_quoted_string
436
+ match = File.parse("'test'", :root => :quoted_string)
412
437
  assert(match)
413
438
  assert_equal('test', match.value)
439
+ end
414
440
 
415
- match = grammar.parse("'te\\'st'")
441
+ def test_single_quoted_string_embedded_single_quote
442
+ match = File.parse("'te\\'st'", :root => :quoted_string)
416
443
  assert(match)
417
444
  assert_equal("te'st", match.value)
445
+ end
418
446
 
419
- match = grammar.parse("'te\"st'")
447
+ def test_single_quoted_string_embedded_double_quote
448
+ match = File.parse("'te\"st'", :root => :quoted_string)
420
449
  assert(match)
421
450
  assert_equal('te"st', match.value)
422
451
  end
423
452
 
424
453
  def test_double_quoted_string
425
- grammar = file(:quoted_string)
426
-
427
- match = grammar.parse('"test"')
454
+ match = File.parse('"test"', :root => :quoted_string)
428
455
  assert(match)
429
456
  assert_equal('test', match.value)
457
+ end
430
458
 
431
- match = grammar.parse('"te\\"st"')
459
+ def test_double_quoted_string_embedded_double_quote
460
+ match = File.parse('"te\\"st"', :root => :quoted_string)
432
461
  assert(match)
433
462
  assert_equal('te"st', match.value)
463
+ end
434
464
 
435
- match = grammar.parse('"te\'st"')
465
+ def test_double_quoted_string_embedded_single_quote
466
+ match = File.parse('"te\'st"', :root => :quoted_string)
436
467
  assert(match)
437
468
  assert_equal("te'st", match.value)
469
+ end
438
470
 
439
- match = grammar.parse('"\\x26"')
471
+ def test_double_quoted_string_hex
472
+ match = File.parse('"\\x26"', :root => :quoted_string)
440
473
  assert(match)
441
474
  assert_equal('&', match.value)
442
475
  end
443
476
 
444
- def test_character_class
445
- grammar = file(:character_class)
477
+ def test_case_insensitive_string
478
+ match = File.parse('`test`', :root => :case_insensitive_string)
479
+ assert(match)
480
+ assert_equal('test', match.value)
481
+ end
482
+
483
+ def test_case_insensitive_string_embedded_double_quote
484
+ match = File.parse('`te\\"st`', :root => :case_insensitive_string)
485
+ assert(match)
486
+ assert_equal('te"st', match.value)
487
+ end
446
488
 
447
- match = grammar.parse('[_]')
489
+ def test_case_insensitive_string_embedded_backtick
490
+ match = File.parse('`te\`st`', :root => :case_insensitive_string)
491
+ assert(match)
492
+ assert_equal("te`st", match.value)
493
+ end
494
+
495
+ def test_case_insensitive_string_hex
496
+ match = File.parse('`\\x26`', :root => :case_insensitive_string)
497
+ assert(match)
498
+ assert_equal('&', match.value)
499
+ end
500
+
501
+ def test_character_class
502
+ match = File.parse('[_]', :root => :character_class)
448
503
  assert(match)
449
504
  assert_equal(/\A[_]/, match.value)
505
+ end
450
506
 
451
- match = grammar.parse('[a-z]')
507
+ def test_character_class_a_z
508
+ match = File.parse('[a-z]', :root => :character_class)
452
509
  assert(match)
453
510
  assert_equal(/\A[a-z]/, match.value)
511
+ end
454
512
 
455
- match = grammar.parse('[a-z0-9]')
513
+ def test_character_class_a_z_0_9
514
+ match = File.parse('[a-z0-9]', :root => :character_class)
456
515
  assert(match)
457
516
  assert_equal(/\A[a-z0-9]/, match.value)
517
+ end
458
518
 
459
- match = grammar.parse('[\[-\]]')
519
+ def test_character_class_nested_square_brackets
520
+ match = File.parse('[\[-\]]', :root => :character_class)
460
521
  assert(match)
461
522
  assert_equal(/\A[\[-\]]/, match.value)
523
+ end
462
524
 
463
- match = grammar.parse('[\\x26-\\x29]')
525
+ def test_character_class_hex_range
526
+ match = File.parse('[\\x26-\\x29]', :root => :character_class)
464
527
  assert(match)
465
528
  assert_equal(/\A[\x26-\x29]/, match.value)
466
529
  end
467
530
 
468
531
  def test_dot
469
- grammar = file(:dot)
470
-
471
- match = grammar.parse('.')
532
+ match = File.parse('.', :root => :dot)
472
533
  assert(match)
473
534
  assert_equal(DOT, match.value)
474
535
  end
475
536
 
476
537
  def test_regular_expression
477
- grammar = file(:regular_expression)
478
-
479
- match = grammar.parse('/./')
538
+ match = File.parse('/./', :root => :regular_expression)
480
539
  assert(match)
481
540
  assert_equal(/./, match.value)
541
+ end
482
542
 
483
- match = grammar.parse('/\\//')
543
+ def test_regular_expression_escaped_forward_slash
544
+ match = File.parse('/\\//', :root => :regular_expression)
484
545
  assert(match)
485
546
  assert_equal(/\//, match.value)
547
+ end
486
548
 
487
- match = grammar.parse('/\\\\/')
549
+ def test_regular_expression_escaped_backslash
550
+ match = File.parse('/\\\\/', :root => :regular_expression)
488
551
  assert(match)
489
552
  assert_equal(/\\/, match.value)
553
+ end
490
554
 
491
- match = grammar.parse('/\\x26/')
555
+ def test_regular_expression_hex
556
+ match = File.parse('/\\x26/', :root => :regular_expression)
492
557
  assert(match)
493
558
  assert_equal(/\x26/, match.value)
559
+ end
494
560
 
495
- match = grammar.parse('/a/i')
561
+ def test_regular_expression_with_flag
562
+ match = File.parse('/a/i', :root => :regular_expression)
496
563
  assert(match)
497
564
  assert_equal(/a/i, match.value)
498
565
  end
499
566
 
500
- def test_predicate
501
- grammar = file(:predicate)
502
-
503
- match = grammar.parse('&')
567
+ def test_predicate_and
568
+ match = File.parse('&', :root => :predicate)
504
569
  assert(match)
505
570
  assert_kind_of(Rule, match.value(''))
571
+ end
506
572
 
507
- match = grammar.parse('!')
573
+ def test_predicate_not
574
+ match = File.parse('!', :root => :predicate)
508
575
  assert(match)
509
576
  assert_kind_of(Rule, match.value(''))
510
577
  end
511
578
 
512
579
  def test_and
513
- grammar = file(:and)
514
-
515
- match = grammar.parse('&')
580
+ match = File.parse('&', :root => :and)
516
581
  assert(match)
517
582
  assert_instance_of(AndPredicate, match.value(''))
583
+ end
518
584
 
519
- match = grammar.parse('& ')
585
+ def test_and_space
586
+ match = File.parse('& ', :root => :and)
520
587
  assert(match)
521
588
  assert_instance_of(AndPredicate, match.value(''))
522
589
  end
523
590
 
524
591
  def test_not
525
- grammar = file(:not)
526
-
527
- match = grammar.parse('!')
592
+ match = File.parse('!', :root => :not)
528
593
  assert(match)
529
594
  assert_instance_of(NotPredicate, match.value(''))
595
+ end
530
596
 
531
- match = grammar.parse('! ')
597
+ def test_not_space
598
+ match = File.parse('! ', :root => :not)
532
599
  assert(match)
533
600
  assert_instance_of(NotPredicate, match.value(''))
534
601
  end
535
602
 
536
603
  def test_label
537
- grammar = file(:label)
538
-
539
- match = grammar.parse('label:')
604
+ match = File.parse('label:', :root => :label)
540
605
  assert(match)
541
606
  v = match.value('')
542
607
  assert_instance_of(Label, v)
543
608
  assert_equal(:label, v.label)
609
+ end
544
610
 
545
- match = grammar.parse('a_label : ')
611
+ def test_label_spaced
612
+ match = File.parse('a_label : ', :root => :label)
546
613
  assert(match)
547
614
  v = match.value('')
548
615
  assert_instance_of(Label, v)
@@ -550,43 +617,51 @@ class CitrusFileTest < Test::Unit::TestCase
550
617
  end
551
618
 
552
619
  def test_tag
553
- grammar = file(:tag)
554
-
555
- match = grammar.parse('<Module>')
620
+ match = File.parse('<Module>', :root => :tag)
556
621
  assert(match)
557
622
  assert_equal(Module, match.value)
623
+ end
558
624
 
559
- match = grammar.parse('< Module >')
625
+ def test_tag_inner_space
626
+ match = File.parse('< Module >', :root => :tag)
560
627
  assert(match)
561
628
  assert_equal(Module, match.value)
629
+ end
562
630
 
563
- match = grammar.parse('<Module> ')
631
+ def test_tag_space
632
+ match = File.parse('<Module> ', :root => :tag)
564
633
  assert(match)
565
634
  assert_equal(Module, match.value)
566
635
  end
567
636
 
568
637
  def test_block
569
- grammar = file(:block)
570
-
571
- match = grammar.parse('{}')
638
+ match = File.parse('{}', :root => :block)
572
639
  assert(match)
573
640
  assert(match.value)
641
+ end
574
642
 
575
- match = grammar.parse("{} \n")
643
+ def test_block_space
644
+ match = File.parse("{} \n", :root => :block)
576
645
  assert(match)
577
646
  assert(match.value)
647
+ end
578
648
 
579
- match = grammar.parse('{ 2 }')
649
+ def test_block_n
650
+ match = File.parse('{ 2 }', :root => :block)
580
651
  assert(match)
581
652
  assert(match.value)
582
653
  assert_equal(2, match.value.call)
654
+ end
583
655
 
584
- match = grammar.parse("{ {:a => :b}\n}")
656
+ def test_block_with_hash
657
+ match = File.parse("{ {:a => :b}\n}", :root => :block)
585
658
  assert(match)
586
659
  assert(match.value)
587
660
  assert_equal({:a => :b}, match.value.call)
661
+ end
588
662
 
589
- match = grammar.parse("{|b|\n Proc.new(&b)\n}")
663
+ def test_block_proc
664
+ match = File.parse("{|b|\n Proc.new(&b)\n}", :root => :block)
590
665
  assert(match)
591
666
  assert(match.value)
592
667
 
@@ -594,121 +669,152 @@ class CitrusFileTest < Test::Unit::TestCase
594
669
 
595
670
  assert(b)
596
671
  assert_equal(:hi, b.call)
672
+ end
597
673
 
598
- match = grammar.parse("{\n def value\n 'a'\n end\n} ")
674
+ def test_block_def
675
+ match = File.parse("{\n def value\n 'a'\n end\n} ", :root => :block)
599
676
  assert(match)
600
677
  assert(match.value)
601
-
602
678
  end
603
679
 
604
680
  def test_block_with_interpolation
605
- grammar = file(:block)
606
-
607
- match = grammar.parse('{ "#{number}" }')
681
+ match = File.parse('{ "#{number}" }', :root => :block)
608
682
  assert(match)
609
683
  assert(match.value)
610
684
  end
611
685
 
612
- def test_repeat
613
- grammar = file(:repeat)
686
+ def test_repeat_question
687
+ match = File.parse('?', :root => :repeat)
688
+ assert(match)
689
+ assert_instance_of(Repeat, match.value(''))
690
+ end
691
+
692
+ def test_repeat_plus
693
+ match = File.parse('+', :root => :repeat)
694
+ assert(match)
695
+ assert_instance_of(Repeat, match.value(''))
696
+ end
614
697
 
615
- match = grammar.parse('?')
698
+ def test_repeat_star
699
+ match = File.parse('*', :root => :repeat)
616
700
  assert(match)
617
- assert_instance_of(Repeat, match.wrap(''))
701
+ assert_instance_of(Repeat, match.value(''))
702
+ end
618
703
 
619
- match = grammar.parse('+')
704
+ def test_repeat_n_star
705
+ match = File.parse('1*', :root => :repeat)
620
706
  assert(match)
621
- assert_instance_of(Repeat, match.wrap(''))
707
+ assert_instance_of(Repeat, match.value(''))
708
+ end
622
709
 
623
- match = grammar.parse('*')
710
+ def test_repeat_star_n
711
+ match = File.parse('*2', :root => :repeat)
624
712
  assert(match)
625
- assert_instance_of(Repeat, match.wrap(''))
713
+ assert_instance_of(Repeat, match.value(''))
626
714
  end
627
715
 
628
- def test_question
629
- grammar = file(:question)
716
+ def test_repeat_n_star_n
717
+ match = File.parse('1*2', :root => :repeat)
718
+ assert(match)
719
+ assert_instance_of(Repeat, match.value(''))
720
+ end
630
721
 
631
- match = grammar.parse('?')
722
+ def test_question
723
+ match = File.parse('?', :root => :question)
632
724
  assert(match)
633
725
  assert_equal(0, match.min)
634
726
  assert_equal(1, match.max)
727
+ end
635
728
 
636
- match = grammar.parse('? ')
729
+ def test_question_space
730
+ match = File.parse('? ', :root => :question)
637
731
  assert(match)
638
732
  assert_equal(0, match.min)
639
733
  assert_equal(1, match.max)
640
734
  end
641
735
 
642
736
  def test_plus
643
- grammar = file(:plus)
644
-
645
- match = grammar.parse('+')
737
+ match = File.parse('+', :root => :plus)
646
738
  assert(match)
647
739
  assert_equal(1, match.min)
648
740
  assert_equal(Infinity, match.max)
741
+ end
649
742
 
650
- match = grammar.parse('+ ')
743
+ def test_plus_space
744
+ match = File.parse('+ ', :root => :plus)
651
745
  assert(match)
652
746
  assert_equal(1, match.min)
653
747
  assert_equal(Infinity, match.max)
654
748
  end
655
749
 
656
- def test_repeat
657
- grammar = file(:repeat)
658
-
659
- match = grammar.parse('*')
750
+ def test_star
751
+ match = File.parse('*', :root => :star)
660
752
  assert(match)
661
753
  assert_equal(0, match.min)
662
754
  assert_equal(Infinity, match.max)
755
+ end
663
756
 
664
- match = grammar.parse('1*')
757
+ def test_n_star
758
+ match = File.parse('1*', :root => :star)
665
759
  assert(match)
666
760
  assert_equal(1, match.min)
667
761
  assert_equal(Infinity, match.max)
762
+ end
668
763
 
669
- match = grammar.parse('*2')
764
+ def test_star_n
765
+ match = File.parse('*2', :root => :star)
670
766
  assert(match)
671
767
  assert_equal(0, match.min)
672
768
  assert_equal(2, match.max)
769
+ end
673
770
 
674
- match = grammar.parse('1*2')
771
+ def test_n_star_n
772
+ match = File.parse('1*2', :root => :star)
675
773
  assert(match)
676
774
  assert_equal(1, match.min)
677
775
  assert_equal(2, match.max)
776
+ end
678
777
 
679
- match = grammar.parse('1*2 ')
778
+ def test_n_star_n_space
779
+ match = File.parse('1*2 ', :root => :star)
680
780
  assert(match)
681
781
  assert_equal(1, match.min)
682
782
  assert_equal(2, match.max)
683
783
  end
684
784
 
685
785
  def test_module_name
686
- grammar = file(:module_name)
786
+ match = File.parse('Module', :root => :module_name)
787
+ assert(match)
788
+ assert_equal('Module', match)
789
+ end
687
790
 
688
- match = grammar.parse('Module')
791
+ def test_module_name_space
792
+ match = File.parse('Module ', :root => :module_name)
689
793
  assert(match)
794
+ assert_equal('Module', match.first)
795
+ end
690
796
 
691
- match = grammar.parse('::Proc')
797
+ def test_module_name_colon_colon
798
+ match = File.parse('::Proc', :root => :module_name)
692
799
  assert(match)
800
+ assert_equal('::Proc', match)
693
801
  end
694
802
 
695
803
  def test_constant
696
- grammar = file(:constant)
697
-
698
- match = grammar.parse('Math')
804
+ match = File.parse('Math', :root => :constant)
699
805
  assert(match)
806
+ assert_equal('Math', match)
807
+ end
700
808
 
809
+ def test_constant_invalid
701
810
  assert_raise ParseError do
702
- match = grammar.parse('math')
811
+ File.parse('math', :root => :constant)
703
812
  end
704
813
  end
705
814
 
706
815
  def test_comment
707
- grammar = file(:comment)
708
-
709
- match = grammar.parse('# A comment.')
816
+ match = File.parse('# A comment.', :root => :comment)
710
817
  assert(match)
711
818
  assert_equal('# A comment.', match)
712
819
  end
713
-
714
820
  end