citrus 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/citrus.gemspec +2 -2
- data/lib/citrus.rb +1 -1
- data/lib/citrus/file.rb +1 -1
- data/test/file_test.rb +56 -42
- data/test/multibyte_test.rb +34 -0
- metadata +6 -4
data/citrus.gemspec
CHANGED
data/lib/citrus.rb
CHANGED
data/lib/citrus/file.rb
CHANGED
data/test/file_test.rb
CHANGED
@@ -3,21 +3,19 @@ require 'citrus/file'
|
|
3
3
|
|
4
4
|
class CitrusFileTest < Test::Unit::TestCase
|
5
5
|
|
6
|
-
# A shortcut for creating a grammar that includes Citrus::
|
6
|
+
# A shortcut for creating a grammar that includes Citrus::File but uses a
|
7
7
|
# different root.
|
8
|
-
def
|
9
|
-
Grammar.new
|
8
|
+
def file(root_rule)
|
9
|
+
Grammar.new do
|
10
10
|
include Citrus::File
|
11
11
|
root root_rule
|
12
|
-
|
12
|
+
end
|
13
13
|
end
|
14
14
|
|
15
15
|
## File tests
|
16
16
|
|
17
|
-
F = ::File
|
18
|
-
|
19
17
|
def run_file_test(file, root)
|
20
|
-
grammar =
|
18
|
+
grammar = file(root)
|
21
19
|
code = F.read(file)
|
22
20
|
match = grammar.parse(code)
|
23
21
|
assert(match)
|
@@ -36,7 +34,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
36
34
|
## Hierarchical syntax
|
37
35
|
|
38
36
|
def test_rule_body
|
39
|
-
grammar =
|
37
|
+
grammar = file(:rule_body)
|
40
38
|
|
41
39
|
match = grammar.parse('"a" | "b"')
|
42
40
|
assert(match)
|
@@ -137,12 +135,6 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
137
135
|
assert_kind_of(Rule, match.value)
|
138
136
|
assert_instance_of(Choice, match.value)
|
139
137
|
|
140
|
-
# Test precedence of Sequence over Choice.
|
141
|
-
match = grammar.parse('"a" "b" | "c"')
|
142
|
-
assert(match)
|
143
|
-
assert_kind_of(Rule, match.value)
|
144
|
-
assert_instance_of(Choice, match.value)
|
145
|
-
|
146
138
|
match = grammar.parse('"a" ("b" | /./)* {}')
|
147
139
|
assert(match)
|
148
140
|
assert_kind_of(Rule, match.value)
|
@@ -189,8 +181,30 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
189
181
|
assert_instance_of(Repeat, match.value)
|
190
182
|
end
|
191
183
|
|
184
|
+
def test_precedence
|
185
|
+
grammar = file(:rule_body)
|
186
|
+
|
187
|
+
# Sequence should bind more tightly than Choice.
|
188
|
+
match = grammar.parse('"a" "b" | "c"')
|
189
|
+
assert(match)
|
190
|
+
assert_kind_of(Rule, match.value)
|
191
|
+
assert_instance_of(Choice, match.value)
|
192
|
+
|
193
|
+
# Parentheses should change binding precedence.
|
194
|
+
match = grammar.parse('"a" ("b" | "c")')
|
195
|
+
assert(match)
|
196
|
+
assert_kind_of(Rule, match.value)
|
197
|
+
assert_instance_of(Sequence, match.value)
|
198
|
+
|
199
|
+
# Repeat should bind more tightly than AndPredicate.
|
200
|
+
match = grammar.parse("&'a'+")
|
201
|
+
assert(match)
|
202
|
+
assert_kind_of(Rule, match.value)
|
203
|
+
assert_instance_of(AndPredicate, match.value)
|
204
|
+
end
|
205
|
+
|
192
206
|
def test_sequence
|
193
|
-
grammar =
|
207
|
+
grammar = file(:sequence)
|
194
208
|
|
195
209
|
match = grammar.parse('"" ""')
|
196
210
|
assert(match)
|
@@ -204,7 +218,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
204
218
|
end
|
205
219
|
|
206
220
|
def test_prefix
|
207
|
-
grammar =
|
221
|
+
grammar = file(:prefix)
|
208
222
|
|
209
223
|
match = grammar.parse('&""')
|
210
224
|
assert(match)
|
@@ -228,7 +242,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
228
242
|
end
|
229
243
|
|
230
244
|
def test_appendix
|
231
|
-
grammar =
|
245
|
+
grammar = file(:appendix)
|
232
246
|
|
233
247
|
match = grammar.parse('"" <Module>')
|
234
248
|
assert(match)
|
@@ -247,7 +261,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
247
261
|
end
|
248
262
|
|
249
263
|
def test_suffix
|
250
|
-
grammar =
|
264
|
+
grammar = file(:suffix)
|
251
265
|
|
252
266
|
match = grammar.parse('""+')
|
253
267
|
assert(match)
|
@@ -266,7 +280,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
266
280
|
end
|
267
281
|
|
268
282
|
def test_primary
|
269
|
-
grammar =
|
283
|
+
grammar = file(:primary)
|
270
284
|
|
271
285
|
match = grammar.parse('rule_name')
|
272
286
|
assert(match)
|
@@ -284,7 +298,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
284
298
|
|
285
299
|
|
286
300
|
def test_require
|
287
|
-
grammar =
|
301
|
+
grammar = file(:require)
|
288
302
|
|
289
303
|
match = grammar.parse('require "some/file"')
|
290
304
|
assert(match)
|
@@ -300,7 +314,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
300
314
|
end
|
301
315
|
|
302
316
|
def test_include
|
303
|
-
grammar =
|
317
|
+
grammar = file(:include)
|
304
318
|
|
305
319
|
match = grammar.parse('include Module')
|
306
320
|
assert(match)
|
@@ -312,7 +326,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
312
326
|
end
|
313
327
|
|
314
328
|
def test_root
|
315
|
-
grammar =
|
329
|
+
grammar = file(:root)
|
316
330
|
|
317
331
|
match = grammar.parse('root some_rule')
|
318
332
|
assert(match)
|
@@ -324,7 +338,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
324
338
|
end
|
325
339
|
|
326
340
|
def test_rule_name
|
327
|
-
grammar =
|
341
|
+
grammar = file(:rule_name)
|
328
342
|
|
329
343
|
match = grammar.parse('some_rule')
|
330
344
|
assert(match)
|
@@ -340,7 +354,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
340
354
|
end
|
341
355
|
|
342
356
|
def test_terminal
|
343
|
-
grammar =
|
357
|
+
grammar = file(:terminal)
|
344
358
|
|
345
359
|
match = grammar.parse('"a"')
|
346
360
|
assert(match)
|
@@ -368,7 +382,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
368
382
|
end
|
369
383
|
|
370
384
|
def test_single_quoted_string
|
371
|
-
grammar =
|
385
|
+
grammar = file(:quoted_string)
|
372
386
|
|
373
387
|
match = grammar.parse("'test'")
|
374
388
|
assert(match)
|
@@ -384,7 +398,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
384
398
|
end
|
385
399
|
|
386
400
|
def test_double_quoted_string
|
387
|
-
grammar =
|
401
|
+
grammar = file(:quoted_string)
|
388
402
|
|
389
403
|
match = grammar.parse('"test"')
|
390
404
|
assert(match)
|
@@ -404,7 +418,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
404
418
|
end
|
405
419
|
|
406
420
|
def test_character_class
|
407
|
-
grammar =
|
421
|
+
grammar = file(:character_class)
|
408
422
|
|
409
423
|
match = grammar.parse('[_]')
|
410
424
|
assert(match)
|
@@ -428,7 +442,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
428
442
|
end
|
429
443
|
|
430
444
|
def test_anything_symbol
|
431
|
-
grammar =
|
445
|
+
grammar = file(:anything_symbol)
|
432
446
|
|
433
447
|
match = grammar.parse('.')
|
434
448
|
assert(match)
|
@@ -436,7 +450,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
436
450
|
end
|
437
451
|
|
438
452
|
def test_regular_expression
|
439
|
-
grammar =
|
453
|
+
grammar = file(:regular_expression)
|
440
454
|
|
441
455
|
match = grammar.parse('/./')
|
442
456
|
assert(match)
|
@@ -460,7 +474,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
460
474
|
end
|
461
475
|
|
462
476
|
def test_qualifier
|
463
|
-
grammar =
|
477
|
+
grammar = file(:qualifier)
|
464
478
|
|
465
479
|
match = grammar.parse('&')
|
466
480
|
assert(match)
|
@@ -472,7 +486,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
472
486
|
end
|
473
487
|
|
474
488
|
def test_and
|
475
|
-
grammar =
|
489
|
+
grammar = file(:and)
|
476
490
|
|
477
491
|
match = grammar.parse('&')
|
478
492
|
assert(match)
|
@@ -484,7 +498,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
484
498
|
end
|
485
499
|
|
486
500
|
def test_not
|
487
|
-
grammar =
|
501
|
+
grammar = file(:not)
|
488
502
|
|
489
503
|
match = grammar.parse('!')
|
490
504
|
assert(match)
|
@@ -496,7 +510,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
496
510
|
end
|
497
511
|
|
498
512
|
def test_label
|
499
|
-
grammar =
|
513
|
+
grammar = file(:label)
|
500
514
|
|
501
515
|
match = grammar.parse('label:')
|
502
516
|
assert(match)
|
@@ -510,7 +524,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
510
524
|
end
|
511
525
|
|
512
526
|
def test_tag
|
513
|
-
grammar =
|
527
|
+
grammar = file(:tag)
|
514
528
|
|
515
529
|
match = grammar.parse('<Module>')
|
516
530
|
assert(match)
|
@@ -526,7 +540,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
526
540
|
end
|
527
541
|
|
528
542
|
def test_block
|
529
|
-
grammar =
|
543
|
+
grammar = file(:block)
|
530
544
|
|
531
545
|
match = grammar.parse('{}')
|
532
546
|
assert(match)
|
@@ -561,7 +575,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
561
575
|
end
|
562
576
|
|
563
577
|
def test_quantifier
|
564
|
-
grammar =
|
578
|
+
grammar = file(:quantifier)
|
565
579
|
|
566
580
|
match = grammar.parse('?')
|
567
581
|
assert(match)
|
@@ -577,7 +591,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
577
591
|
end
|
578
592
|
|
579
593
|
def test_question
|
580
|
-
grammar =
|
594
|
+
grammar = file(:question)
|
581
595
|
|
582
596
|
match = grammar.parse('?')
|
583
597
|
assert(match)
|
@@ -591,7 +605,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
591
605
|
end
|
592
606
|
|
593
607
|
def test_plus
|
594
|
-
grammar =
|
608
|
+
grammar = file(:plus)
|
595
609
|
|
596
610
|
match = grammar.parse('+')
|
597
611
|
assert(match)
|
@@ -605,7 +619,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
605
619
|
end
|
606
620
|
|
607
621
|
def test_repeat
|
608
|
-
grammar =
|
622
|
+
grammar = file(:repeat)
|
609
623
|
|
610
624
|
match = grammar.parse('*')
|
611
625
|
assert(match)
|
@@ -634,7 +648,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
634
648
|
end
|
635
649
|
|
636
650
|
def test_module_name
|
637
|
-
grammar =
|
651
|
+
grammar = file(:module_name)
|
638
652
|
|
639
653
|
match = grammar.parse('Module')
|
640
654
|
assert(match)
|
@@ -644,7 +658,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
644
658
|
end
|
645
659
|
|
646
660
|
def test_constant
|
647
|
-
grammar =
|
661
|
+
grammar = file(:constant)
|
648
662
|
|
649
663
|
match = grammar.parse('Math')
|
650
664
|
assert(match)
|
@@ -655,7 +669,7 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
655
669
|
end
|
656
670
|
|
657
671
|
def test_comment
|
658
|
-
grammar =
|
672
|
+
grammar = file(:comment)
|
659
673
|
|
660
674
|
match = grammar.parse('# A comment.')
|
661
675
|
assert(match)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
class MultibyteTest < Test::Unit::TestCase
|
4
|
+
Citrus.eval(<<-'CODE')
|
5
|
+
grammar MultibyteTest::Grammar
|
6
|
+
rule string
|
7
|
+
"\xFF"
|
8
|
+
end
|
9
|
+
|
10
|
+
rule regexp
|
11
|
+
/\xFF/
|
12
|
+
end
|
13
|
+
|
14
|
+
rule character_class
|
15
|
+
[\xFF]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
CODE
|
19
|
+
|
20
|
+
def test_multibyte_string
|
21
|
+
m = Grammar.parse("\xFF", :root => :string)
|
22
|
+
assert(m)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_multibyte_regexp
|
26
|
+
m = Grammar.parse("\xFF", :root => :regexp)
|
27
|
+
assert(m)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_multibyte_character_class
|
31
|
+
m = Grammar.parse("\xFF", :root => :character_class)
|
32
|
+
assert(m)
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: citrus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 1.5.
|
9
|
+
- 1
|
10
|
+
version: 1.5.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Jackson
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-08-17 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- test/helper.rb
|
91
91
|
- test/label_test.rb
|
92
92
|
- test/match_test.rb
|
93
|
+
- test/multibyte_test.rb
|
93
94
|
- test/not_predicate_test.rb
|
94
95
|
- test/repeat_test.rb
|
95
96
|
- test/rule_test.rb
|
@@ -149,6 +150,7 @@ test_files:
|
|
149
150
|
- test/grammar_test.rb
|
150
151
|
- test/label_test.rb
|
151
152
|
- test/match_test.rb
|
153
|
+
- test/multibyte_test.rb
|
152
154
|
- test/not_predicate_test.rb
|
153
155
|
- test/repeat_test.rb
|
154
156
|
- test/rule_test.rb
|