soroban 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,19 +1,17 @@
1
+ [![Gem Version](https://badge.fury.io/rb/soroban.svg)](http://badge.fury.io/rb/soroban)
2
+ [![Dependency Status](https://gemnasium.com/agworld/soroban.png)](https://gemnasium.com/agworld/soroban)
3
+ [![Build Status](https://secure.travis-ci.org/agworld/soroban.png)](http://travis-ci.org/#!/agworld/soroban)
4
+ [![Code Climate](https://codeclimate.com/github/agworld/soroban.png)](https://codeclimate.com/github/agworld/soroban)
5
+
1
6
  Soroban
2
7
  =======
3
8
 
4
9
  Soroban is a calculating engine that understands Excel formulas.
5
10
 
6
- [![Code Climate](https://codeclimate.com/github/agworld/soroban.png)](https://codeclimate.com/github/agworld/soroban)
7
- [![Dependency Status](https://gemnasium.com/agworld/soroban.png)](https://gemnasium.com/agworld/soroban)
8
- [![Build Status](https://secure.travis-ci.org/agworld/soroban.png)](http://travis-ci.org/#!/agworld/soroban)
9
-
10
-
11
11
  Getting Started
12
12
  ---------------
13
13
 
14
- Simply `sudo gem install soroban` and then `require 'soroban'` in your code.
15
-
16
- Look at the examples on this page, the [tests](https://github.com/agworld/soroban/blob/master/spec/soroban_spec.rb) and the [API docs](http://rubydoc.info/github/agworld/soroban/master/frames) to get up to speed.
14
+ Apart from the examples on this page, look at the [tests](https://github.com/agworld/soroban/blob/master/spec/soroban_spec.rb) and the [API docs](http://rubydoc.info/github/agworld/soroban/master/frames) to get up to speed.
17
15
 
18
16
  Example Usage
19
17
  -------------
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "soroban"
8
- s.version = "0.9.1"
8
+ s.version = "0.10.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jason Hutchens"]
12
- s.date = "2014-10-22"
12
+ s.date = "2014-10-24"
13
13
  s.description = "Soroban makes it easy to extract and execute formulas from Excel spreadsheets. It rewrites Excel formulas as Ruby expressions, and allows you to bind named variables to spreadsheet cells to easily manipulate inputs and capture outputs."
14
14
  s.email = "jason.hutchens@agworld.com.au"
15
15
  s.extra_rdoc_files = [
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.1
1
+ 0.10.0
@@ -21,7 +21,7 @@ module Soroban
21
21
  if node_cache[:formula].has_key?(index)
22
22
  cached = node_cache[:formula][index]
23
23
  if cached
24
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
24
+ node_cache[:formula][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
25
25
  @index = cached.interval.end
26
26
  end
27
27
  return cached
@@ -29,9 +29,9 @@ module Soroban
29
29
 
30
30
  i0 = index
31
31
  i1, s1 = index, []
32
- if has_terminal?('=', false, index)
33
- r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
34
- @index += 1
32
+ if (match_len = has_terminal?('=', false, index))
33
+ r2 = true
34
+ @index += match_len
35
35
  else
36
36
  terminal_parse_failure('=')
37
37
  r2 = nil
@@ -58,18 +58,22 @@ module Soroban
58
58
  r1 = nil
59
59
  end
60
60
  if r1
61
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
61
62
  r0 = r1
62
63
  else
63
64
  r6 = _nt_string
64
65
  if r6
66
+ r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
65
67
  r0 = r6
66
68
  else
67
69
  r7 = _nt_number
68
70
  if r7
71
+ r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
69
72
  r0 = r7
70
73
  else
71
74
  r8 = _nt_boolean
72
75
  if r8
76
+ r8 = SyntaxNode.new(input, (index-1)...index) if r8 == true
73
77
  r0 = r8
74
78
  else
75
79
  @index = i0
@@ -102,7 +106,7 @@ module Soroban
102
106
  if node_cache[:logical].has_key?(index)
103
107
  cached = node_cache[:logical][index]
104
108
  if cached
105
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
109
+ node_cache[:logical][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
106
110
  @index = cached.interval.end
107
111
  end
108
112
  return cached
@@ -123,9 +127,9 @@ module Soroban
123
127
  end
124
128
  s3 << r4
125
129
  if r4
126
- if has_terminal?('or', false, index)
127
- r6 = instantiate_node(SyntaxNode,input, index...(index + 2))
128
- @index += 2
130
+ if (match_len = has_terminal?('or', false, index))
131
+ r6 = instantiate_node(SyntaxNode,input, index...(index + match_len))
132
+ @index += match_len
129
133
  else
130
134
  terminal_parse_failure('or')
131
135
  r6 = nil
@@ -192,7 +196,7 @@ module Soroban
192
196
  if node_cache[:and].has_key?(index)
193
197
  cached = node_cache[:and][index]
194
198
  if cached
195
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
199
+ node_cache[:and][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
196
200
  @index = cached.interval.end
197
201
  end
198
202
  return cached
@@ -213,9 +217,9 @@ module Soroban
213
217
  end
214
218
  s3 << r4
215
219
  if r4
216
- if has_terminal?('and', false, index)
217
- r6 = instantiate_node(SyntaxNode,input, index...(index + 3))
218
- @index += 3
220
+ if (match_len = has_terminal?('and', false, index))
221
+ r6 = instantiate_node(SyntaxNode,input, index...(index + match_len))
222
+ @index += match_len
219
223
  else
220
224
  terminal_parse_failure('and')
221
225
  r6 = nil
@@ -276,7 +280,7 @@ module Soroban
276
280
  if node_cache[:truthval].has_key?(index)
277
281
  cached = node_cache[:truthval][index]
278
282
  if cached
279
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
283
+ node_cache[:truthval][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
280
284
  @index = cached.interval.end
281
285
  end
282
286
  return cached
@@ -285,12 +289,13 @@ module Soroban
285
289
  i0 = index
286
290
  r1 = _nt_comparison
287
291
  if r1
292
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
288
293
  r0 = r1
289
294
  else
290
295
  i2, s2 = index, []
291
- if has_terminal?('(', false, index)
292
- r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
293
- @index += 1
296
+ if (match_len = has_terminal?('(', false, index))
297
+ r3 = true
298
+ @index += match_len
294
299
  else
295
300
  terminal_parse_failure('(')
296
301
  r3 = nil
@@ -316,9 +321,9 @@ module Soroban
316
321
  end
317
322
  s2 << r7
318
323
  if r7
319
- if has_terminal?(')', false, index)
320
- r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
321
- @index += 1
324
+ if (match_len = has_terminal?(')', false, index))
325
+ r9 = true
326
+ @index += match_len
322
327
  else
323
328
  terminal_parse_failure(')')
324
329
  r9 = nil
@@ -336,10 +341,12 @@ module Soroban
336
341
  r2 = nil
337
342
  end
338
343
  if r2
344
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
339
345
  r0 = r2
340
346
  else
341
347
  r10 = _nt_boolean
342
348
  if r10
349
+ r10 = SyntaxNode.new(input, (index-1)...index) if r10 == true
343
350
  r0 = r10
344
351
  else
345
352
  @index = i0
@@ -358,51 +365,55 @@ module Soroban
358
365
  if node_cache[:boolean].has_key?(index)
359
366
  cached = node_cache[:boolean][index]
360
367
  if cached
361
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
368
+ node_cache[:boolean][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
362
369
  @index = cached.interval.end
363
370
  end
364
371
  return cached
365
372
  end
366
373
 
367
374
  i0 = index
368
- if has_terminal?('true', false, index)
369
- r1 = instantiate_node(SyntaxNode,input, index...(index + 4))
370
- @index += 4
375
+ if (match_len = has_terminal?('true', false, index))
376
+ r1 = instantiate_node(SyntaxNode,input, index...(index + match_len))
377
+ @index += match_len
371
378
  else
372
379
  terminal_parse_failure('true')
373
380
  r1 = nil
374
381
  end
375
382
  if r1
383
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
376
384
  r0 = r1
377
385
  else
378
- if has_terminal?('false', false, index)
379
- r2 = instantiate_node(SyntaxNode,input, index...(index + 5))
380
- @index += 5
386
+ if (match_len = has_terminal?('false', false, index))
387
+ r2 = instantiate_node(SyntaxNode,input, index...(index + match_len))
388
+ @index += match_len
381
389
  else
382
390
  terminal_parse_failure('false')
383
391
  r2 = nil
384
392
  end
385
393
  if r2
394
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
386
395
  r0 = r2
387
396
  else
388
- if has_terminal?('TRUE', false, index)
389
- r3 = instantiate_node(SyntaxNode,input, index...(index + 4))
390
- @index += 4
397
+ if (match_len = has_terminal?('TRUE', false, index))
398
+ r3 = instantiate_node(SyntaxNode,input, index...(index + match_len))
399
+ @index += match_len
391
400
  else
392
401
  terminal_parse_failure('TRUE')
393
402
  r3 = nil
394
403
  end
395
404
  if r3
405
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
396
406
  r0 = r3
397
407
  else
398
- if has_terminal?('FALSE', false, index)
399
- r4 = instantiate_node(SyntaxNode,input, index...(index + 5))
400
- @index += 5
408
+ if (match_len = has_terminal?('FALSE', false, index))
409
+ r4 = instantiate_node(SyntaxNode,input, index...(index + match_len))
410
+ @index += match_len
401
411
  else
402
412
  terminal_parse_failure('FALSE')
403
413
  r4 = nil
404
414
  end
405
415
  if r4
416
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
406
417
  r0 = r4
407
418
  else
408
419
  @index = i0
@@ -439,7 +450,7 @@ module Soroban
439
450
  if node_cache[:comparison].has_key?(index)
440
451
  cached = node_cache[:comparison][index]
441
452
  if cached
442
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
453
+ node_cache[:comparison][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
443
454
  @index = cached.interval.end
444
455
  end
445
456
  return cached
@@ -510,71 +521,77 @@ module Soroban
510
521
  if node_cache[:comparator].has_key?(index)
511
522
  cached = node_cache[:comparator][index]
512
523
  if cached
513
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
524
+ node_cache[:comparator][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
514
525
  @index = cached.interval.end
515
526
  end
516
527
  return cached
517
528
  end
518
529
 
519
530
  i0 = index
520
- if has_terminal?('=', false, index)
521
- r1 = instantiate_node(Equal,input, index...(index + 1))
522
- @index += 1
531
+ if (match_len = has_terminal?('=', false, index))
532
+ r1 = instantiate_node(Equal,input, index...(index + match_len))
533
+ @index += match_len
523
534
  else
524
535
  terminal_parse_failure('=')
525
536
  r1 = nil
526
537
  end
527
538
  if r1
539
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
528
540
  r0 = r1
529
541
  else
530
- if has_terminal?('<>', false, index)
531
- r2 = instantiate_node(NotEqual,input, index...(index + 2))
532
- @index += 2
542
+ if (match_len = has_terminal?('<>', false, index))
543
+ r2 = instantiate_node(NotEqual,input, index...(index + match_len))
544
+ @index += match_len
533
545
  else
534
546
  terminal_parse_failure('<>')
535
547
  r2 = nil
536
548
  end
537
549
  if r2
550
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
538
551
  r0 = r2
539
552
  else
540
- if has_terminal?('>=', false, index)
541
- r3 = instantiate_node(SyntaxNode,input, index...(index + 2))
542
- @index += 2
553
+ if (match_len = has_terminal?('>=', false, index))
554
+ r3 = instantiate_node(SyntaxNode,input, index...(index + match_len))
555
+ @index += match_len
543
556
  else
544
557
  terminal_parse_failure('>=')
545
558
  r3 = nil
546
559
  end
547
560
  if r3
561
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
548
562
  r0 = r3
549
563
  else
550
- if has_terminal?('<=', false, index)
551
- r4 = instantiate_node(SyntaxNode,input, index...(index + 2))
552
- @index += 2
564
+ if (match_len = has_terminal?('<=', false, index))
565
+ r4 = instantiate_node(SyntaxNode,input, index...(index + match_len))
566
+ @index += match_len
553
567
  else
554
568
  terminal_parse_failure('<=')
555
569
  r4 = nil
556
570
  end
557
571
  if r4
572
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
558
573
  r0 = r4
559
574
  else
560
- if has_terminal?('>', false, index)
561
- r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
562
- @index += 1
575
+ if (match_len = has_terminal?('>', false, index))
576
+ r5 = true
577
+ @index += match_len
563
578
  else
564
579
  terminal_parse_failure('>')
565
580
  r5 = nil
566
581
  end
567
582
  if r5
583
+ r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
568
584
  r0 = r5
569
585
  else
570
- if has_terminal?('<', false, index)
571
- r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
572
- @index += 1
586
+ if (match_len = has_terminal?('<', false, index))
587
+ r6 = true
588
+ @index += match_len
573
589
  else
574
590
  terminal_parse_failure('<')
575
591
  r6 = nil
576
592
  end
577
593
  if r6
594
+ r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
578
595
  r0 = r6
579
596
  else
580
597
  @index = i0
@@ -613,7 +630,7 @@ module Soroban
613
630
  if node_cache[:expression].has_key?(index)
614
631
  cached = node_cache[:expression][index]
615
632
  if cached
616
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
633
+ node_cache[:expression][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
617
634
  @index = cached.interval.end
618
635
  end
619
636
  return cached
@@ -684,31 +701,33 @@ module Soroban
684
701
  if node_cache[:additive_operator].has_key?(index)
685
702
  cached = node_cache[:additive_operator][index]
686
703
  if cached
687
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
704
+ node_cache[:additive_operator][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
688
705
  @index = cached.interval.end
689
706
  end
690
707
  return cached
691
708
  end
692
709
 
693
710
  i0 = index
694
- if has_terminal?('+', false, index)
695
- r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
696
- @index += 1
711
+ if (match_len = has_terminal?('+', false, index))
712
+ r1 = true
713
+ @index += match_len
697
714
  else
698
715
  terminal_parse_failure('+')
699
716
  r1 = nil
700
717
  end
701
718
  if r1
719
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
702
720
  r0 = r1
703
721
  else
704
- if has_terminal?('-', false, index)
705
- r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
706
- @index += 1
722
+ if (match_len = has_terminal?('-', false, index))
723
+ r2 = true
724
+ @index += match_len
707
725
  else
708
726
  terminal_parse_failure('-')
709
727
  r2 = nil
710
728
  end
711
729
  if r2
730
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
712
731
  r0 = r2
713
732
  else
714
733
  @index = i0
@@ -743,7 +762,7 @@ module Soroban
743
762
  if node_cache[:multiplicative].has_key?(index)
744
763
  cached = node_cache[:multiplicative][index]
745
764
  if cached
746
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
765
+ node_cache[:multiplicative][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
747
766
  @index = cached.interval.end
748
767
  end
749
768
  return cached
@@ -814,41 +833,44 @@ module Soroban
814
833
  if node_cache[:multiplicative_operator].has_key?(index)
815
834
  cached = node_cache[:multiplicative_operator][index]
816
835
  if cached
817
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
836
+ node_cache[:multiplicative_operator][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
818
837
  @index = cached.interval.end
819
838
  end
820
839
  return cached
821
840
  end
822
841
 
823
842
  i0 = index
824
- if has_terminal?('^', false, index)
825
- r1 = instantiate_node(Pow,input, index...(index + 1))
826
- @index += 1
843
+ if (match_len = has_terminal?('^', false, index))
844
+ r1 = instantiate_node(Pow,input, index...(index + match_len))
845
+ @index += match_len
827
846
  else
828
847
  terminal_parse_failure('^')
829
848
  r1 = nil
830
849
  end
831
850
  if r1
851
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
832
852
  r0 = r1
833
853
  else
834
- if has_terminal?('*', false, index)
835
- r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
836
- @index += 1
854
+ if (match_len = has_terminal?('*', false, index))
855
+ r2 = true
856
+ @index += match_len
837
857
  else
838
858
  terminal_parse_failure('*')
839
859
  r2 = nil
840
860
  end
841
861
  if r2
862
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
842
863
  r0 = r2
843
864
  else
844
- if has_terminal?('/', false, index)
845
- r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
846
- @index += 1
865
+ if (match_len = has_terminal?('/', false, index))
866
+ r3 = true
867
+ @index += match_len
847
868
  else
848
869
  terminal_parse_failure('/')
849
870
  r3 = nil
850
871
  end
851
872
  if r3
873
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
852
874
  r0 = r3
853
875
  else
854
876
  @index = i0
@@ -880,7 +902,7 @@ module Soroban
880
902
  if node_cache[:value].has_key?(index)
881
903
  cached = node_cache[:value][index]
882
904
  if cached
883
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
905
+ node_cache[:value][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
884
906
  @index = cached.interval.end
885
907
  end
886
908
  return cached
@@ -889,12 +911,13 @@ module Soroban
889
911
  i0 = index
890
912
  r1 = _nt_function
891
913
  if r1
914
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
892
915
  r0 = r1
893
916
  else
894
917
  i2, s2 = index, []
895
- if has_terminal?('(', false, index)
896
- r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
897
- @index += 1
918
+ if (match_len = has_terminal?('(', false, index))
919
+ r3 = true
920
+ @index += match_len
898
921
  else
899
922
  terminal_parse_failure('(')
900
923
  r3 = nil
@@ -920,9 +943,9 @@ module Soroban
920
943
  end
921
944
  s2 << r7
922
945
  if r7
923
- if has_terminal?(')', false, index)
924
- r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
925
- @index += 1
946
+ if (match_len = has_terminal?(')', false, index))
947
+ r9 = true
948
+ @index += match_len
926
949
  else
927
950
  terminal_parse_failure(')')
928
951
  r9 = nil
@@ -940,32 +963,38 @@ module Soroban
940
963
  r2 = nil
941
964
  end
942
965
  if r2
966
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
943
967
  r0 = r2
944
968
  else
945
969
  r10 = _nt_range
946
970
  if r10
971
+ r10 = SyntaxNode.new(input, (index-1)...index) if r10 == true
947
972
  r0 = r10
948
973
  else
949
974
  r11 = _nt_number
950
975
  if r11
976
+ r11 = SyntaxNode.new(input, (index-1)...index) if r11 == true
951
977
  r0 = r11
952
978
  else
953
979
  r12 = _nt_boolean
954
980
  if r12
981
+ r12 = SyntaxNode.new(input, (index-1)...index) if r12 == true
955
982
  r0 = r12
956
983
  else
957
984
  r13 = _nt_identifier
958
985
  if r13
986
+ r13 = SyntaxNode.new(input, (index-1)...index) if r13 == true
959
987
  r0 = r13
960
988
  else
961
989
  r14 = _nt_string
962
990
  if r14
991
+ r14 = SyntaxNode.new(input, (index-1)...index) if r14 == true
963
992
  r0 = r14
964
993
  else
965
994
  i15, s15 = index, []
966
- if has_terminal?('-', false, index)
967
- r16 = instantiate_node(SyntaxNode,input, index...(index + 1))
968
- @index += 1
995
+ if (match_len = has_terminal?('-', false, index))
996
+ r16 = true
997
+ @index += match_len
969
998
  else
970
999
  terminal_parse_failure('-')
971
1000
  r16 = nil
@@ -983,6 +1012,7 @@ module Soroban
983
1012
  r15 = nil
984
1013
  end
985
1014
  if r15
1015
+ r15 = SyntaxNode.new(input, (index-1)...index) if r15 == true
986
1016
  r0 = r15
987
1017
  else
988
1018
  @index = i0
@@ -1009,7 +1039,7 @@ module Soroban
1009
1039
  if node_cache[:function].has_key?(index)
1010
1040
  cached = node_cache[:function][index]
1011
1041
  if cached
1012
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1042
+ node_cache[:function][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1013
1043
  @index = cached.interval.end
1014
1044
  end
1015
1045
  return cached
@@ -1018,10 +1048,11 @@ module Soroban
1018
1048
  i0, s0 = index, []
1019
1049
  s1, i1 = [], index
1020
1050
  loop do
1021
- if has_terminal?('\G[a-zA-Z]', true, index)
1051
+ if has_terminal?(@regexps[gr = '\A[a-zA-Z]'] ||= Regexp.new(gr), :regexp, index)
1022
1052
  r2 = true
1023
1053
  @index += 1
1024
1054
  else
1055
+ terminal_parse_failure('[a-zA-Z]')
1025
1056
  r2 = nil
1026
1057
  end
1027
1058
  if r2
@@ -1038,9 +1069,9 @@ module Soroban
1038
1069
  end
1039
1070
  s0 << r1
1040
1071
  if r1
1041
- if has_terminal?('(', false, index)
1042
- r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
1043
- @index += 1
1072
+ if (match_len = has_terminal?('(', false, index))
1073
+ r3 = true
1074
+ @index += match_len
1044
1075
  else
1045
1076
  terminal_parse_failure('(')
1046
1077
  r3 = nil
@@ -1071,9 +1102,9 @@ module Soroban
1071
1102
  end
1072
1103
  s0 << r8
1073
1104
  if r8
1074
- if has_terminal?(')', false, index)
1075
- r10 = instantiate_node(SyntaxNode,input, index...(index + 1))
1076
- @index += 1
1105
+ if (match_len = has_terminal?(')', false, index))
1106
+ r10 = true
1107
+ @index += match_len
1077
1108
  else
1078
1109
  terminal_parse_failure(')')
1079
1110
  r10 = nil
@@ -1115,7 +1146,7 @@ module Soroban
1115
1146
  if node_cache[:arguments].has_key?(index)
1116
1147
  cached = node_cache[:arguments][index]
1117
1148
  if cached
1118
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1149
+ node_cache[:arguments][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1119
1150
  @index = cached.interval.end
1120
1151
  end
1121
1152
  return cached
@@ -1136,9 +1167,9 @@ module Soroban
1136
1167
  end
1137
1168
  s3 << r4
1138
1169
  if r4
1139
- if has_terminal?(',', false, index)
1140
- r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
1141
- @index += 1
1170
+ if (match_len = has_terminal?(',', false, index))
1171
+ r6 = true
1172
+ @index += match_len
1142
1173
  else
1143
1174
  terminal_parse_failure(',')
1144
1175
  r6 = nil
@@ -1188,12 +1219,18 @@ module Soroban
1188
1219
  end
1189
1220
 
1190
1221
  module Number0
1191
- def float
1222
+ def percentage
1192
1223
  elements[1]
1193
1224
  end
1194
1225
  end
1195
1226
 
1196
1227
  module Number1
1228
+ def float
1229
+ elements[1]
1230
+ end
1231
+ end
1232
+
1233
+ module Number2
1197
1234
  def integer
1198
1235
  elements[1]
1199
1236
  end
@@ -1204,69 +1241,104 @@ module Soroban
1204
1241
  if node_cache[:number].has_key?(index)
1205
1242
  cached = node_cache[:number][index]
1206
1243
  if cached
1207
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1244
+ node_cache[:number][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1208
1245
  @index = cached.interval.end
1209
1246
  end
1210
1247
  return cached
1211
1248
  end
1212
1249
 
1213
1250
  i0 = index
1214
- r1 = _nt_float
1251
+ r1 = _nt_percentage
1215
1252
  if r1
1253
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
1216
1254
  r0 = r1
1217
1255
  else
1218
- r2 = _nt_integer
1256
+ r2 = _nt_float
1219
1257
  if r2
1258
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
1220
1259
  r0 = r2
1221
1260
  else
1222
- i3, s3 = index, []
1223
- if has_terminal?('-', false, index)
1224
- r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
1225
- @index += 1
1226
- else
1227
- terminal_parse_failure('-')
1228
- r4 = nil
1229
- end
1230
- s3 << r4
1231
- if r4
1232
- r5 = _nt_float
1233
- s3 << r5
1234
- end
1235
- if s3.last
1236
- r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
1237
- r3.extend(Number0)
1238
- else
1239
- @index = i3
1240
- r3 = nil
1241
- end
1261
+ r3 = _nt_integer
1242
1262
  if r3
1263
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
1243
1264
  r0 = r3
1244
1265
  else
1245
- i6, s6 = index, []
1246
- if has_terminal?('-', false, index)
1247
- r7 = instantiate_node(SyntaxNode,input, index...(index + 1))
1248
- @index += 1
1266
+ i4, s4 = index, []
1267
+ if (match_len = has_terminal?('-', false, index))
1268
+ r5 = true
1269
+ @index += match_len
1249
1270
  else
1250
1271
  terminal_parse_failure('-')
1251
- r7 = nil
1272
+ r5 = nil
1252
1273
  end
1253
- s6 << r7
1254
- if r7
1255
- r8 = _nt_integer
1256
- s6 << r8
1274
+ s4 << r5
1275
+ if r5
1276
+ r6 = _nt_percentage
1277
+ s4 << r6
1257
1278
  end
1258
- if s6.last
1259
- r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
1260
- r6.extend(Number1)
1279
+ if s4.last
1280
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
1281
+ r4.extend(Number0)
1261
1282
  else
1262
- @index = i6
1263
- r6 = nil
1283
+ @index = i4
1284
+ r4 = nil
1264
1285
  end
1265
- if r6
1266
- r0 = r6
1286
+ if r4
1287
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
1288
+ r0 = r4
1267
1289
  else
1268
- @index = i0
1269
- r0 = nil
1290
+ i7, s7 = index, []
1291
+ if (match_len = has_terminal?('-', false, index))
1292
+ r8 = true
1293
+ @index += match_len
1294
+ else
1295
+ terminal_parse_failure('-')
1296
+ r8 = nil
1297
+ end
1298
+ s7 << r8
1299
+ if r8
1300
+ r9 = _nt_float
1301
+ s7 << r9
1302
+ end
1303
+ if s7.last
1304
+ r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
1305
+ r7.extend(Number1)
1306
+ else
1307
+ @index = i7
1308
+ r7 = nil
1309
+ end
1310
+ if r7
1311
+ r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
1312
+ r0 = r7
1313
+ else
1314
+ i10, s10 = index, []
1315
+ if (match_len = has_terminal?('-', false, index))
1316
+ r11 = true
1317
+ @index += match_len
1318
+ else
1319
+ terminal_parse_failure('-')
1320
+ r11 = nil
1321
+ end
1322
+ s10 << r11
1323
+ if r11
1324
+ r12 = _nt_integer
1325
+ s10 << r12
1326
+ end
1327
+ if s10.last
1328
+ r10 = instantiate_node(SyntaxNode,input, i10...index, s10)
1329
+ r10.extend(Number2)
1330
+ else
1331
+ @index = i10
1332
+ r10 = nil
1333
+ end
1334
+ if r10
1335
+ r10 = SyntaxNode.new(input, (index-1)...index) if r10 == true
1336
+ r0 = r10
1337
+ else
1338
+ @index = i0
1339
+ r0 = nil
1340
+ end
1341
+ end
1270
1342
  end
1271
1343
  end
1272
1344
  end
@@ -1277,6 +1349,108 @@ module Soroban
1277
1349
  r0
1278
1350
  end
1279
1351
 
1352
+ module Percentage0
1353
+ def float
1354
+ elements[0]
1355
+ end
1356
+
1357
+ end
1358
+
1359
+ module Percentage1
1360
+ def integer
1361
+ elements[0]
1362
+ end
1363
+
1364
+ end
1365
+
1366
+ def _nt_percentage
1367
+ start_index = index
1368
+ if node_cache[:percentage].has_key?(index)
1369
+ cached = node_cache[:percentage][index]
1370
+ if cached
1371
+ node_cache[:percentage][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1372
+ @index = cached.interval.end
1373
+ end
1374
+ return cached
1375
+ end
1376
+
1377
+ i0 = index
1378
+ i1, s1 = index, []
1379
+ r2 = _nt_float
1380
+ s1 << r2
1381
+ if r2
1382
+ r4 = _nt_space
1383
+ if r4
1384
+ r3 = r4
1385
+ else
1386
+ r3 = instantiate_node(SyntaxNode,input, index...index)
1387
+ end
1388
+ s1 << r3
1389
+ if r3
1390
+ if (match_len = has_terminal?('%', false, index))
1391
+ r5 = true
1392
+ @index += match_len
1393
+ else
1394
+ terminal_parse_failure('%')
1395
+ r5 = nil
1396
+ end
1397
+ s1 << r5
1398
+ end
1399
+ end
1400
+ if s1.last
1401
+ r1 = instantiate_node(PercentValue,input, i1...index, s1)
1402
+ r1.extend(Percentage0)
1403
+ else
1404
+ @index = i1
1405
+ r1 = nil
1406
+ end
1407
+ if r1
1408
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
1409
+ r0 = r1
1410
+ else
1411
+ i6, s6 = index, []
1412
+ r7 = _nt_integer
1413
+ s6 << r7
1414
+ if r7
1415
+ r9 = _nt_space
1416
+ if r9
1417
+ r8 = r9
1418
+ else
1419
+ r8 = instantiate_node(SyntaxNode,input, index...index)
1420
+ end
1421
+ s6 << r8
1422
+ if r8
1423
+ if (match_len = has_terminal?('%', false, index))
1424
+ r10 = true
1425
+ @index += match_len
1426
+ else
1427
+ terminal_parse_failure('%')
1428
+ r10 = nil
1429
+ end
1430
+ s6 << r10
1431
+ end
1432
+ end
1433
+ if s6.last
1434
+ r6 = instantiate_node(PercentValue,input, i6...index, s6)
1435
+ r6.extend(Percentage1)
1436
+ else
1437
+ @index = i6
1438
+ r6 = nil
1439
+ end
1440
+ if r6
1441
+ r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
1442
+ r0 = r6
1443
+ else
1444
+ @index = i0
1445
+ r0 = nil
1446
+ end
1447
+ end
1448
+
1449
+ node_cache[:percentage][start_index] = r0
1450
+
1451
+ r0
1452
+ end
1453
+
1280
1454
  module Float0
1281
1455
  end
1282
1456
 
@@ -1285,7 +1459,7 @@ module Soroban
1285
1459
  if node_cache[:float].has_key?(index)
1286
1460
  cached = node_cache[:float][index]
1287
1461
  if cached
1288
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1462
+ node_cache[:float][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1289
1463
  @index = cached.interval.end
1290
1464
  end
1291
1465
  return cached
@@ -1294,10 +1468,11 @@ module Soroban
1294
1468
  i0, s0 = index, []
1295
1469
  s1, i1 = [], index
1296
1470
  loop do
1297
- if has_terminal?('\G[0-9]', true, index)
1471
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
1298
1472
  r2 = true
1299
1473
  @index += 1
1300
1474
  else
1475
+ terminal_parse_failure('[0-9]')
1301
1476
  r2 = nil
1302
1477
  end
1303
1478
  if r2
@@ -1309,9 +1484,9 @@ module Soroban
1309
1484
  r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
1310
1485
  s0 << r1
1311
1486
  if r1
1312
- if has_terminal?('.', false, index)
1313
- r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
1314
- @index += 1
1487
+ if (match_len = has_terminal?('.', false, index))
1488
+ r3 = true
1489
+ @index += match_len
1315
1490
  else
1316
1491
  terminal_parse_failure('.')
1317
1492
  r3 = nil
@@ -1320,10 +1495,11 @@ module Soroban
1320
1495
  if r3
1321
1496
  s4, i4 = [], index
1322
1497
  loop do
1323
- if has_terminal?('\G[0-9]', true, index)
1498
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
1324
1499
  r5 = true
1325
1500
  @index += 1
1326
1501
  else
1502
+ terminal_parse_failure('[0-9]')
1327
1503
  r5 = nil
1328
1504
  end
1329
1505
  if r5
@@ -1359,7 +1535,7 @@ module Soroban
1359
1535
  if node_cache[:integer].has_key?(index)
1360
1536
  cached = node_cache[:integer][index]
1361
1537
  if cached
1362
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1538
+ node_cache[:integer][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1363
1539
  @index = cached.interval.end
1364
1540
  end
1365
1541
  return cached
@@ -1367,10 +1543,11 @@ module Soroban
1367
1543
 
1368
1544
  s0, i0 = [], index
1369
1545
  loop do
1370
- if has_terminal?('\G[0-9]', true, index)
1546
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
1371
1547
  r1 = true
1372
1548
  @index += 1
1373
1549
  else
1550
+ terminal_parse_failure('[0-9]')
1374
1551
  r1 = nil
1375
1552
  end
1376
1553
  if r1
@@ -1402,7 +1579,7 @@ module Soroban
1402
1579
  if node_cache[:identifier].has_key?(index)
1403
1580
  cached = node_cache[:identifier][index]
1404
1581
  if cached
1405
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1582
+ node_cache[:identifier][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1406
1583
  @index = cached.interval.end
1407
1584
  end
1408
1585
  return cached
@@ -1410,20 +1587,22 @@ module Soroban
1410
1587
 
1411
1588
  i0 = index
1412
1589
  i1, s1 = index, []
1413
- if has_terminal?('\G[a-zA-Z]', true, index)
1590
+ if has_terminal?(@regexps[gr = '\A[a-zA-Z]'] ||= Regexp.new(gr), :regexp, index)
1414
1591
  r2 = true
1415
1592
  @index += 1
1416
1593
  else
1594
+ terminal_parse_failure('[a-zA-Z]')
1417
1595
  r2 = nil
1418
1596
  end
1419
1597
  s1 << r2
1420
1598
  if r2
1421
1599
  s3, i3 = [], index
1422
1600
  loop do
1423
- if has_terminal?('\G[a-zA-Z0-9]', true, index)
1601
+ if has_terminal?(@regexps[gr = '\A[a-zA-Z0-9]'] ||= Regexp.new(gr), :regexp, index)
1424
1602
  r4 = true
1425
1603
  @index += 1
1426
1604
  else
1605
+ terminal_parse_failure('[a-zA-Z0-9]')
1427
1606
  r4 = nil
1428
1607
  end
1429
1608
  if r4
@@ -1443,12 +1622,13 @@ module Soroban
1443
1622
  r1 = nil
1444
1623
  end
1445
1624
  if r1
1625
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
1446
1626
  r0 = r1
1447
1627
  else
1448
1628
  i5, s5 = index, []
1449
- if has_terminal?('$', false, index)
1450
- r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
1451
- @index += 1
1629
+ if (match_len = has_terminal?('$', false, index))
1630
+ r6 = true
1631
+ @index += match_len
1452
1632
  else
1453
1633
  terminal_parse_failure('$')
1454
1634
  r6 = nil
@@ -1457,10 +1637,11 @@ module Soroban
1457
1637
  if r6
1458
1638
  s7, i7 = [], index
1459
1639
  loop do
1460
- if has_terminal?('\G[A-Za-z]', true, index)
1640
+ if has_terminal?(@regexps[gr = '\A[A-Za-z]'] ||= Regexp.new(gr), :regexp, index)
1461
1641
  r8 = true
1462
1642
  @index += 1
1463
1643
  else
1644
+ terminal_parse_failure('[A-Za-z]')
1464
1645
  r8 = nil
1465
1646
  end
1466
1647
  if r8
@@ -1477,29 +1658,31 @@ module Soroban
1477
1658
  end
1478
1659
  s5 << r7
1479
1660
  if r7
1480
- if has_terminal?('$', false, index)
1481
- r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
1482
- @index += 1
1661
+ if (match_len = has_terminal?('$', false, index))
1662
+ r9 = true
1663
+ @index += match_len
1483
1664
  else
1484
1665
  terminal_parse_failure('$')
1485
1666
  r9 = nil
1486
1667
  end
1487
1668
  s5 << r9
1488
1669
  if r9
1489
- if has_terminal?('\G[1-9]', true, index)
1670
+ if has_terminal?(@regexps[gr = '\A[1-9]'] ||= Regexp.new(gr), :regexp, index)
1490
1671
  r10 = true
1491
1672
  @index += 1
1492
1673
  else
1674
+ terminal_parse_failure('[1-9]')
1493
1675
  r10 = nil
1494
1676
  end
1495
1677
  s5 << r10
1496
1678
  if r10
1497
1679
  s11, i11 = [], index
1498
1680
  loop do
1499
- if has_terminal?('\G[0-9]', true, index)
1681
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
1500
1682
  r12 = true
1501
1683
  @index += 1
1502
1684
  else
1685
+ terminal_parse_failure('[0-9]')
1503
1686
  r12 = nil
1504
1687
  end
1505
1688
  if r12
@@ -1522,6 +1705,7 @@ module Soroban
1522
1705
  r5 = nil
1523
1706
  end
1524
1707
  if r5
1708
+ r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
1525
1709
  r0 = r5
1526
1710
  else
1527
1711
  @index = i0
@@ -1545,7 +1729,7 @@ module Soroban
1545
1729
  if node_cache[:label].has_key?(index)
1546
1730
  cached = node_cache[:label][index]
1547
1731
  if cached
1548
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1732
+ node_cache[:label][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1549
1733
  @index = cached.interval.end
1550
1734
  end
1551
1735
  return cached
@@ -1555,10 +1739,11 @@ module Soroban
1555
1739
  i1, s1 = index, []
1556
1740
  s2, i2 = [], index
1557
1741
  loop do
1558
- if has_terminal?('\G[A-Za-z]', true, index)
1742
+ if has_terminal?(@regexps[gr = '\A[A-Za-z]'] ||= Regexp.new(gr), :regexp, index)
1559
1743
  r3 = true
1560
1744
  @index += 1
1561
1745
  else
1746
+ terminal_parse_failure('[A-Za-z]')
1562
1747
  r3 = nil
1563
1748
  end
1564
1749
  if r3
@@ -1575,20 +1760,22 @@ module Soroban
1575
1760
  end
1576
1761
  s1 << r2
1577
1762
  if r2
1578
- if has_terminal?('\G[1-9]', true, index)
1763
+ if has_terminal?(@regexps[gr = '\A[1-9]'] ||= Regexp.new(gr), :regexp, index)
1579
1764
  r4 = true
1580
1765
  @index += 1
1581
1766
  else
1767
+ terminal_parse_failure('[1-9]')
1582
1768
  r4 = nil
1583
1769
  end
1584
1770
  s1 << r4
1585
1771
  if r4
1586
1772
  s5, i5 = [], index
1587
1773
  loop do
1588
- if has_terminal?('\G[0-9]', true, index)
1774
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
1589
1775
  r6 = true
1590
1776
  @index += 1
1591
1777
  else
1778
+ terminal_parse_failure('[0-9]')
1592
1779
  r6 = nil
1593
1780
  end
1594
1781
  if r6
@@ -1609,12 +1796,13 @@ module Soroban
1609
1796
  r1 = nil
1610
1797
  end
1611
1798
  if r1
1799
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
1612
1800
  r0 = r1
1613
1801
  else
1614
1802
  i7, s7 = index, []
1615
- if has_terminal?('$', false, index)
1616
- r8 = instantiate_node(SyntaxNode,input, index...(index + 1))
1617
- @index += 1
1803
+ if (match_len = has_terminal?('$', false, index))
1804
+ r8 = true
1805
+ @index += match_len
1618
1806
  else
1619
1807
  terminal_parse_failure('$')
1620
1808
  r8 = nil
@@ -1623,10 +1811,11 @@ module Soroban
1623
1811
  if r8
1624
1812
  s9, i9 = [], index
1625
1813
  loop do
1626
- if has_terminal?('\G[A-Za-z]', true, index)
1814
+ if has_terminal?(@regexps[gr = '\A[A-Za-z]'] ||= Regexp.new(gr), :regexp, index)
1627
1815
  r10 = true
1628
1816
  @index += 1
1629
1817
  else
1818
+ terminal_parse_failure('[A-Za-z]')
1630
1819
  r10 = nil
1631
1820
  end
1632
1821
  if r10
@@ -1643,29 +1832,31 @@ module Soroban
1643
1832
  end
1644
1833
  s7 << r9
1645
1834
  if r9
1646
- if has_terminal?('$', false, index)
1647
- r11 = instantiate_node(SyntaxNode,input, index...(index + 1))
1648
- @index += 1
1835
+ if (match_len = has_terminal?('$', false, index))
1836
+ r11 = true
1837
+ @index += match_len
1649
1838
  else
1650
1839
  terminal_parse_failure('$')
1651
1840
  r11 = nil
1652
1841
  end
1653
1842
  s7 << r11
1654
1843
  if r11
1655
- if has_terminal?('\G[1-9]', true, index)
1844
+ if has_terminal?(@regexps[gr = '\A[1-9]'] ||= Regexp.new(gr), :regexp, index)
1656
1845
  r12 = true
1657
1846
  @index += 1
1658
1847
  else
1848
+ terminal_parse_failure('[1-9]')
1659
1849
  r12 = nil
1660
1850
  end
1661
1851
  s7 << r12
1662
1852
  if r12
1663
1853
  s13, i13 = [], index
1664
1854
  loop do
1665
- if has_terminal?('\G[0-9]', true, index)
1855
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
1666
1856
  r14 = true
1667
1857
  @index += 1
1668
1858
  else
1859
+ terminal_parse_failure('[0-9]')
1669
1860
  r14 = nil
1670
1861
  end
1671
1862
  if r14
@@ -1688,6 +1879,7 @@ module Soroban
1688
1879
  r7 = nil
1689
1880
  end
1690
1881
  if r7
1882
+ r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
1691
1883
  r0 = r7
1692
1884
  else
1693
1885
  @index = i0
@@ -1714,7 +1906,7 @@ module Soroban
1714
1906
  if node_cache[:string].has_key?(index)
1715
1907
  cached = node_cache[:string][index]
1716
1908
  if cached
1717
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1909
+ node_cache[:string][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1718
1910
  @index = cached.interval.end
1719
1911
  end
1720
1912
  return cached
@@ -1722,9 +1914,9 @@ module Soroban
1722
1914
 
1723
1915
  i0 = index
1724
1916
  i1, s1 = index, []
1725
- if has_terminal?('"', false, index)
1726
- r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
1727
- @index += 1
1917
+ if (match_len = has_terminal?('"', false, index))
1918
+ r2 = true
1919
+ @index += match_len
1728
1920
  else
1729
1921
  terminal_parse_failure('"')
1730
1922
  r2 = nil
@@ -1734,21 +1926,22 @@ module Soroban
1734
1926
  s3, i3 = [], index
1735
1927
  loop do
1736
1928
  i4 = index
1737
- if has_terminal?('\"', false, index)
1738
- r5 = instantiate_node(SyntaxNode,input, index...(index + 2))
1739
- @index += 2
1929
+ if (match_len = has_terminal?('\"', false, index))
1930
+ r5 = instantiate_node(SyntaxNode,input, index...(index + match_len))
1931
+ @index += match_len
1740
1932
  else
1741
1933
  terminal_parse_failure('\"')
1742
1934
  r5 = nil
1743
1935
  end
1744
1936
  if r5
1937
+ r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
1745
1938
  r4 = r5
1746
1939
  else
1747
1940
  i6, s6 = index, []
1748
1941
  i7 = index
1749
- if has_terminal?('"', false, index)
1750
- r8 = instantiate_node(SyntaxNode,input, index...(index + 1))
1751
- @index += 1
1942
+ if (match_len = has_terminal?('"', false, index))
1943
+ r8 = true
1944
+ @index += match_len
1752
1945
  else
1753
1946
  terminal_parse_failure('"')
1754
1947
  r8 = nil
@@ -1762,7 +1955,7 @@ module Soroban
1762
1955
  s6 << r7
1763
1956
  if r7
1764
1957
  if index < input_length
1765
- r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
1958
+ r9 = true
1766
1959
  @index += 1
1767
1960
  else
1768
1961
  terminal_parse_failure("any character")
@@ -1778,6 +1971,7 @@ module Soroban
1778
1971
  r6 = nil
1779
1972
  end
1780
1973
  if r6
1974
+ r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
1781
1975
  r4 = r6
1782
1976
  else
1783
1977
  @index = i4
@@ -1793,9 +1987,9 @@ module Soroban
1793
1987
  r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
1794
1988
  s1 << r3
1795
1989
  if r3
1796
- if has_terminal?('"', false, index)
1797
- r10 = instantiate_node(SyntaxNode,input, index...(index + 1))
1798
- @index += 1
1990
+ if (match_len = has_terminal?('"', false, index))
1991
+ r10 = true
1992
+ @index += match_len
1799
1993
  else
1800
1994
  terminal_parse_failure('"')
1801
1995
  r10 = nil
@@ -1811,12 +2005,13 @@ module Soroban
1811
2005
  r1 = nil
1812
2006
  end
1813
2007
  if r1
2008
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
1814
2009
  r0 = r1
1815
2010
  else
1816
2011
  i11, s11 = index, []
1817
- if has_terminal?("'", false, index)
1818
- r12 = instantiate_node(SyntaxNode,input, index...(index + 1))
1819
- @index += 1
2012
+ if (match_len = has_terminal?("'", false, index))
2013
+ r12 = true
2014
+ @index += match_len
1820
2015
  else
1821
2016
  terminal_parse_failure("'")
1822
2017
  r12 = nil
@@ -1825,10 +2020,11 @@ module Soroban
1825
2020
  if r12
1826
2021
  s13, i13 = [], index
1827
2022
  loop do
1828
- if has_terminal?('\G[^\']', true, index)
2023
+ if has_terminal?(@regexps[gr = '\A[^\']'] ||= Regexp.new(gr), :regexp, index)
1829
2024
  r14 = true
1830
2025
  @index += 1
1831
2026
  else
2027
+ terminal_parse_failure('[^\']')
1832
2028
  r14 = nil
1833
2029
  end
1834
2030
  if r14
@@ -1840,9 +2036,9 @@ module Soroban
1840
2036
  r13 = instantiate_node(SyntaxNode,input, i13...index, s13)
1841
2037
  s11 << r13
1842
2038
  if r13
1843
- if has_terminal?("'", false, index)
1844
- r15 = instantiate_node(SyntaxNode,input, index...(index + 1))
1845
- @index += 1
2039
+ if (match_len = has_terminal?("'", false, index))
2040
+ r15 = true
2041
+ @index += match_len
1846
2042
  else
1847
2043
  terminal_parse_failure("'")
1848
2044
  r15 = nil
@@ -1858,6 +2054,7 @@ module Soroban
1858
2054
  r11 = nil
1859
2055
  end
1860
2056
  if r11
2057
+ r11 = SyntaxNode.new(input, (index-1)...index) if r11 == true
1861
2058
  r0 = r11
1862
2059
  else
1863
2060
  @index = i0
@@ -1885,7 +2082,7 @@ module Soroban
1885
2082
  if node_cache[:range].has_key?(index)
1886
2083
  cached = node_cache[:range][index]
1887
2084
  if cached
1888
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
2085
+ node_cache[:range][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1889
2086
  @index = cached.interval.end
1890
2087
  end
1891
2088
  return cached
@@ -1895,9 +2092,9 @@ module Soroban
1895
2092
  r1 = _nt_label
1896
2093
  s0 << r1
1897
2094
  if r1
1898
- if has_terminal?(':', false, index)
1899
- r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
1900
- @index += 1
2095
+ if (match_len = has_terminal?(':', false, index))
2096
+ r2 = true
2097
+ @index += match_len
1901
2098
  else
1902
2099
  terminal_parse_failure(':')
1903
2100
  r2 = nil
@@ -1926,7 +2123,7 @@ module Soroban
1926
2123
  if node_cache[:space].has_key?(index)
1927
2124
  cached = node_cache[:space][index]
1928
2125
  if cached
1929
- cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
2126
+ node_cache[:space][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
1930
2127
  @index = cached.interval.end
1931
2128
  end
1932
2129
  return cached
@@ -1934,10 +2131,11 @@ module Soroban
1934
2131
 
1935
2132
  s0, i0 = [], index
1936
2133
  loop do
1937
- if has_terminal?('\G[\\s]', true, index)
2134
+ if has_terminal?(@regexps[gr = '\A[\\s]'] ||= Regexp.new(gr), :regexp, index)
1938
2135
  r1 = true
1939
2136
  @index += 1
1940
2137
  else
2138
+ terminal_parse_failure('[\\s]')
1941
2139
  r1 = nil
1942
2140
  end
1943
2141
  if r1