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 CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'citrus'
3
- s.version = '1.5.0'
4
- s.date = '2010-07-24'
3
+ s.version = '1.5.1'
4
+ s.date = '2010-08-17'
5
5
 
6
6
  s.summary = 'Parsing Expressions for Ruby'
7
7
  s.description = 'Parsing Expressions for Ruby'
data/lib/citrus.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # http://mjijackson.com/citrus
6
6
  module Citrus
7
- VERSION = [1, 5, 0]
7
+ VERSION = [1, 5, 1]
8
8
 
9
9
  Infinity = 1.0 / 0
10
10
 
data/lib/citrus/file.rb CHANGED
@@ -216,7 +216,7 @@ module Citrus
216
216
  rule :character_class do
217
217
  all(/\[(?:\\?.)*?\]/, :space) {
218
218
  def value
219
- Regexp.new('\A' + first.text)
219
+ Regexp.new('\A' + first.text, nil, 'n')
220
220
  end
221
221
  }
222
222
  end
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::PEG but uses a
6
+ # A shortcut for creating a grammar that includes Citrus::File but uses a
7
7
  # different root.
8
- def peg(root_rule)
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 = peg(root)
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 = peg(:rule_body)
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 = peg(:sequence)
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 = peg(:prefix)
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 = peg(:appendix)
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 = peg(:suffix)
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 = peg(:primary)
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 = peg(:require)
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 = peg(:include)
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 = peg(:root)
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 = peg(:rule_name)
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 = peg(:terminal)
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 = peg(:quoted_string)
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 = peg(:quoted_string)
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 = peg(:character_class)
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 = peg(:anything_symbol)
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 = peg(:regular_expression)
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 = peg(:qualifier)
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 = peg(:and)
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 = peg(:not)
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 = peg(:label)
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 = peg(:tag)
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 = peg(:block)
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 = peg(:quantifier)
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 = peg(:question)
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 = peg(:plus)
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 = peg(:repeat)
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 = peg(:module_name)
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 = peg(:constant)
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 = peg(:comment)
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: 3
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 5
9
- - 0
10
- version: 1.5.0
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-07-24 00:00:00 -06:00
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