rparsec 0.4.1 → 0.4.2

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,17 +1,20 @@
1
- # require 'rparsec/parser_impls'
2
- class ParserMonad
3
- def fail msg
4
- FailureParser.new(msg)
5
- end
6
- def value v
7
- return Nil if v.nil?
8
- ValueParser.new(v);
9
- end
10
- def bind(v, &proc)
11
- return v unless proc
12
- BoundParser.new(v, proc);
13
- end
14
- def mplus(p1, p2)
15
- PlusParser.new([p1,p2]);
16
- end
1
+ # require 'rparsec/parser_impls'
2
+ class ParserMonad
3
+ def fail msg
4
+ FailureParser.new(msg)
5
+ end
6
+
7
+ def value v
8
+ return Nil if v.nil?
9
+ ValueParser.new(v);
10
+ end
11
+
12
+ def bind(v, &proc)
13
+ return v unless proc
14
+ BoundParser.new(v, proc);
15
+ end
16
+
17
+ def mplus(p1, p2)
18
+ PlusParser.new([p1,p2]);
19
+ end
17
20
  end
@@ -1,604 +1,615 @@
1
- require 'rparsec/parser'
2
-
3
- class FailureParser < Parser
4
- init :msg
5
- def _parse ctxt
6
- return ctxt.failure(@msg)
7
- end
8
- end
9
-
10
- class ValueParser < Parser
11
- init :value
12
- def _parse ctxt
13
- ctxt.retn @value
14
- end
15
- end
16
-
17
- class LazyParser < Parser
18
- init :block
19
- def _parse ctxt
20
- @block.call._parse ctxt
21
- end
22
- end
23
-
24
- def add_error(err, e)
25
- return e if err.nil?
26
- return err if e.nil?
27
- cmp = compare_error(err, e)
28
- return err if cmp > 0
29
- return e if cmp < 0
30
- err
31
- # merge_error(err, e)
32
- end
33
- def get_first_element(err)
34
- while err.kind_of?(Array)
35
- err = err[0]
36
- end
37
- err
38
- end
39
-
40
- def compare_error(e1, e2)
41
- e1, e2 = get_first_element(e1), get_first_element(e2)
42
- return -1 if e1.index < e2.index
43
- return 1 if e1.index > e2.index
44
- 0
45
- end
46
- ###############################################
47
- #def merge_error(e1, e2)
48
- # return e1 << e2 if e1.kind_of?(Array)
49
- # [e1,e2]
50
- #end
51
- ###############################################
52
- class ThrowParser < Parser
53
- init :symbol
54
- def _parse ctxt
55
- throw @symbol
56
- end
57
- end
58
- class CatchParser < Parser
59
- init :symbol, :parser
60
- def _parse ctxt
61
- interrupted = true
62
- ok = false
63
- catch @symbol do
64
- ok = @parser._parse(ctxt)
65
- interrupted = false
66
- end
67
- return ctxt.retn(@symbol) if interrupted
68
- ok
69
- end
70
- end
71
-
72
- class PeekParser < Parser
73
- init :parser
74
- def _parse ctxt
75
- ind = ctxt.index
76
- return false unless @parser._parse ctxt
77
- ctxt.index = ind
78
- return true
79
- end
80
- def peek
81
- self
82
- end
83
- end
84
-
85
- class AtomParser < Parser
86
- init :parser
87
- def _parse ctxt
88
- ind = ctxt.index
89
- return true if @parser._parse ctxt
90
- ctxt.index = ind
91
- return false
92
- end
93
- def atomize
94
- self
95
- end
96
- end
97
-
98
- class LookAheadSensitiveParser < Parser
99
- def initialize(la=1)
100
- super()
101
- @lookahead = la
102
- end
103
- def visible(ctxt, n)
104
- ctxt.index - n < @lookahead
105
- end
106
- def lookahead(n)
107
- raise ArgumentError, "lookahead number #{n} should be positive" unless n>0
108
- return self if n == @lookahead
109
- withLookahead(n)
110
- end
111
- def not(msg="#{self} unexpected")
112
- NotParser.new(self, msg, @lookahead)
113
- end
114
- end
115
-
116
-
117
- class NotParser < LookAheadSensitiveParser
118
- def initialize(parser, msg, la=1)
119
- super(la)
120
- @parser, @msg, @name = parser, msg, "~#{parser.name}"
121
- end
122
- def _parse ctxt
123
- ind = ctxt.index
124
- if @parser._parse ctxt
125
- ctxt.index = ind
126
- return ctxt.expecting(@msg)
127
- end
128
- return ctxt.retn(nil) if visible(ctxt, ind)
129
- return false
130
- end
131
- def withLookahead(n)
132
- NotParser.new(@parser, @msg, n)
133
- end
134
- def not()
135
- @parser
136
- end
137
- end
138
-
139
- class ExpectParser < Parser
140
- def initialize(parser, msg)
141
- super()
142
- @parser, @msg, @name = parser, msg, msg
143
- end
144
- def _parse ctxt
145
- ind = ctxt.index
146
- return true if @parser._parse ctxt
147
- return false unless ind == ctxt.index
148
- ctxt.expecting(@msg)
149
- end
150
- end
151
-
152
- class PlusParser < LookAheadSensitiveParser
153
- def initialize(alts, la=1)
154
- super(la)
155
- @alts = alts
156
- end
157
- def _parse ctxt
158
- ind, result, err = ctxt.index, ctxt.result, ctxt.error
159
- for p in @alts
160
- ctxt.reset_error
161
- ctxt.index, ctxt.result = ind, result
162
- return true if p._parse(ctxt)
163
- return false unless visible(ctxt, ind)
164
- err = add_error(err, ctxt.error)
165
- end
166
- ctxt.error = err
167
- return false
168
- end
169
- def withLookahead(n)
170
- PlusParser.new(@alts, n)
171
- end
172
- def plus other
173
- PlusParser.new(@alts.dup << other, @lookahead).setName(name)
174
- end
175
- def_sig :plus, Parser
176
- end
177
-
178
-
179
- class AltParser < LookAheadSensitiveParser
180
- def initialize(alts, la = 1)
181
- super(la)
182
- @alts, @lookahead = alts, la
183
- end
184
- def _parse ctxt
185
- ind, result, err = ctxt.index, ctxt.result, ctxt.error
186
- err_ind, err_pos = -1, -1
187
- for p in @alts
188
- ctxt.reset_error
189
- ctxt.index, ctxt.result = ind, result
190
- return true if p._parse(ctxt)
191
- if ctxt.error.index > err_pos
192
- err, err_ind, err_pos = ctxt.error, ctxt.index, ctxt.error.index
193
- end
194
- end
195
- ctxt.index, ctxt.error = err_ind, err
196
- return false
197
- end
198
- def withLookahead(n)
199
- AltParser.new(@alts, n)
200
- end
201
- def | other
202
- AltParser.new(@alts.dup << autobox_parser(other)).setName(name)
203
- end
204
- end
205
-
206
-
207
- class BestParser < Parser
208
- init :alts, :longer
209
- def _parse ctxt
210
- best_result, best_ind = nil, -1
211
- err_ind, err_pos = -1, -1
212
- ind, result, err = ctxt.index, ctxt.result, ctxt.error
213
- for p in @alts
214
- ctxt.reset_error
215
- ctxt.index, ctxt.result = ind, result
216
- if p._parse(ctxt)
217
- err, now_ind = nil, ctxt.index
218
- if best_ind==-1 || now_ind != best_ind && @longer == (now_ind>best_ind)
219
- best_result, best_ind = ctxt.result, now_ind
220
- end
221
- elsif best_ind < 0 # no good match found yet.
222
- if ctxt.error.index > err_pos
223
- err_ind, err_pos = ctxt.index, ctxt.error.index
224
- end
225
- err = add_error(err, ctxt.error)
226
- end
227
- end
228
- if best_ind >= 0
229
- ctxt.index = best_ind
230
- return ctxt.retn(best_result)
231
- else
232
- ctxt.error, ctxt.index = err, err_ind
233
- return false
234
- end
235
- end
236
- end
237
-
238
- class BoundParser < Parser
239
- init :parser, :proc
240
- def _parse ctxt
241
- return false unless @parser._parse(ctxt)
242
- @proc.call(ctxt.result)._parse ctxt
243
- end
244
- end
245
- class BoundnParser < Parser
246
- init :parser, :proc
247
- def _parse ctxt
248
- return false unless @parser._parse(ctxt)
249
- @proc.call(*ctxt.result)._parse ctxt
250
- end
251
- end
252
- class MapParser < Parser
253
- init :parser, :proc
254
- def _parse ctxt
255
- return false unless @parser._parse(ctxt)
256
- ctxt.result = @proc.call(ctxt.result)
257
- true
258
- end
259
- end
260
-
261
- class MapnParser < Parser
262
- init :parser, :proc
263
- def _parse ctxt
264
- return false unless @parser._parse(ctxt)
265
- ctxt.result = @proc.call(*ctxt.result)
266
- true
267
- end
268
- end
269
-
270
- class SequenceParser < Parser
271
- init :parsers, :proc
272
- def _parse ctxt
273
- if @proc.nil?
274
- for p in @parsers
275
- return false unless p._parse(ctxt)
276
- end
277
- else
278
- results = []
279
- for p in @parsers
280
- return false unless p._parse(ctxt)
281
- results << ctxt.result
282
- end
283
- ctxt.retn(@proc.call(*results))
284
- end
285
- return true
286
- end
287
- def seq(other, &block)
288
- # TypeChecker.check_arg_type Parser, other, :seq
289
- SequenceParser.new(@parsers.dup << other, &block)
290
- end
291
- def_sig :seq, Parser
292
- end
293
-
294
- class FollowedParser < Parser
295
- init :p1, :p2
296
- def _parse ctxt
297
- return false unless @p1._parse ctxt
298
- result = ctxt.result
299
- return false unless @p2._parse ctxt
300
- ctxt.retn(result)
301
- end
302
- end
303
-
304
- class SatisfiesParser < Parser
305
- init :pred, :expected
306
- def _parse ctxt
307
- elem = nil
308
- if ctxt.eof || !@pred.call(elem=ctxt.current)
309
- return ctxt.expecting(@expected)
310
- end
311
- ctxt.next
312
- ctxt.retn elem
313
- end
314
- end
315
- class AnyParser < Parser
316
- def _parse ctxt
317
- return ctxt.expecting if ctxt.eof
318
- result = ctxt.current
319
- ctxt.next
320
- ctxt.retn result
321
- end
322
- end
323
-
324
- class EofParser < Parser
325
- init :msg
326
- def _parse ctxt
327
- return true if ctxt.eof
328
- return ctxt.expecting(@msg)
329
- end
330
- end
331
- class RegexpParser < Parser
332
- init :ptn, :msg
333
- def _parse ctxt
334
- scanner = ctxt.scanner
335
- result = scanner.check @ptn
336
- if result.nil?
337
- ctxt.expecting(@msg)
338
- else
339
- ctxt.advance(scanner.matched_size)
340
- ctxt.retn(result)
341
- end
342
- end
343
- end
344
- class AreParser < Parser
345
- init :vals, :msg
346
- def _parse ctxt
347
- if @vals.length > ctxt.available
348
- return ctxt.expecting(@msg)
349
- end
350
- cur = 0
351
- for cur in (0...@vals.length)
352
- if @vals[cur] != ctxt.peek(cur)
353
- return ctxt.expecting(@msg)
354
- end
355
- end
356
- ctxt.advance(@vals.length)
357
- ctxt.retn @vals
358
- end
359
- end
360
-
361
- def downcase c
362
- case when c >= ?A && c <=?Z : c + (?a - ?A) else c end
363
- end
364
-
365
- class StringCaseInsensitiveParser < Parser
366
- init :str, :msg
367
- def _parse ctxt
368
- if @str.length > ctxt.available
369
- return ctxt.expecting(@msg)
370
- end
371
- cur = 0
372
- for cur in (0...@str.length)
373
- if downcase(@str[cur]) != downcase(ctxt.peek(cur))
374
- return ctxt.expecting(@msg)
375
- end
376
- end
377
- result = ctxt.src[ctxt.index, @str.length]
378
- ctxt.advance(@str.length)
379
- ctxt.retn result
380
- end
381
- end
382
- class FragmentParser < Parser
383
- init :parser
384
- def _parse ctxt
385
- ind = ctxt.index
386
- return false unless @parser._parse ctxt
387
- ctxt.retn(ctxt.src[ind, ctxt.index-ind])
388
- end
389
- end
390
-
391
- class TokenParser < Parser
392
- init :symbol, :parser
393
- def _parse ctxt
394
- ind = ctxt.index
395
- return false unless @parser._parse ctxt
396
- raw = ctxt.result
397
- raw = ctxt.src[ind, ctxt.index-ind] unless raw.kind_of? String
398
- ctxt.retn(Token.new(@symbol, raw, ind))
399
- end
400
- end
401
-
402
- class NestedParser < Parser
403
- init :parser1, :parser2
404
- def _parse ctxt
405
- ind = ctxt.index
406
- return false unless @parser1._parse ctxt
407
- _run_nested(ind, ctxt, ctxt.result, @parser2)
408
- end
409
- private
410
- def _run_nested(start, ctxt, src, parser)
411
- ctxt.error = nil
412
- new_ctxt = nil
413
- if src.kind_of? String
414
- new_ctxt = ParseContext.new(src)
415
- return true if _run_parser parser, ctxt, new_ctxt
416
- ctxt.index = start + new_ctxt.index
417
- elsif src.kind_of? Array
418
- new_ctxt = ParseContext.new(src)
419
- return true if _run_parser parser, ctxt, new_ctxt
420
- ctxt.index = start + _get_index(new_ctxt) unless new_ctxt.eof
421
- else
422
- new_ctxt = ParseContext.new([src])
423
- return true if _run_parser parser, ctxt, new_ctxt
424
- ctxt.index = ind unless new_ctxt.eof
425
- end
426
- ctxt.error.index = ctxt.index
427
- false
428
- end
429
- def _get_index ctxt
430
- cur = ctxt.current
431
- return cur.index if cur.respond_to? :index
432
- ctxt.index
433
- end
434
- def _run_parser parser, old_ctxt, new_ctxt
435
- if parser._parse new_ctxt
436
- old_ctxt.result = new_ctxt.result
437
- true
438
- else
439
- old_ctxt.error = new_ctxt.error
440
- false
441
- end
442
- end
443
- end
444
-
445
- class WatchParser < Parser
446
- init :proc
447
- def _parse ctxt
448
- @proc.call(ctxt.result)
449
- true
450
- end
451
- end
452
- class WatchnParser < Parser
453
- init :proc
454
- def _parse ctxt
455
- @proc.call(*ctxt.result)
456
- true
457
- end
458
- end
459
- class MapCurrentParser < Parser
460
- init :proc
461
- def _parse ctxt
462
- ctxt.result = @proc.call(ctxt.result)
463
- true
464
- end
465
- end
466
- class MapnCurrentParser < Parser
467
- init :proc
468
- def _parse ctxt
469
- ctxt.result = @proc.call(*ctxt.result)
470
- true
471
- end
472
- end
473
- class Repeat_Parser < Parser
474
- init :parser, :times
475
- def _parse ctxt
476
- for i in (0...@times)
477
- return false unless @parser._parse ctxt
478
- end
479
- return true
480
- end
481
- end
482
-
483
- class RepeatParser < Parser
484
- init :parser, :times
485
- def _parse ctxt
486
- result = []
487
- for i in (0...@times)
488
- return false unless @parser._parse ctxt
489
- result << ctxt.result
490
- end
491
- return ctxt.retn(result)
492
- end
493
- end
494
-
495
- class Many_Parser < Parser
496
- init :parser, :least
497
- def _parse ctxt
498
- for i in (0...@least)
499
- return false unless @parser._parse ctxt
500
- end
501
- while(true)
502
- ind = ctxt.index
503
- if @parser._parse ctxt
504
- return true if ind==ctxt.index # infinite loop
505
- next
506
- end
507
- return ind==ctxt.index
508
- end
509
- end
510
- end
511
-
512
-
513
- class ManyParser < Parser
514
- init :parser, :least
515
- def _parse ctxt
516
- result = []
517
- for i in (0...@least)
518
- return false unless @parser._parse ctxt
519
- result << ctxt.result
520
- end
521
- while(true)
522
- ind = ctxt.index
523
- if @parser._parse ctxt
524
- result << ctxt.result
525
- return ctxt.retn(result) if ind==ctxt.index # infinite loop
526
- next
527
- end
528
- if ind==ctxt.index
529
- return ctxt.retn(result)
530
- else
531
- return false
532
- end
533
- end
534
- end
535
- end
536
-
537
- class Some_Parser < Parser
538
- init :parser, :least, :max
539
- def _parse ctxt
540
- for i in (0...@least)
541
- return false unless @parser._parse ctxt
542
- end
543
- for i in (@least...@max)
544
- ind = ctxt.index
545
- if @parser._parse ctxt
546
- return true if ind==ctxt.index # infinite loop
547
- next
548
- end
549
- return ind==ctxt.index
550
- end
551
- return true
552
- end
553
- end
554
-
555
- class SomeParser < Parser
556
- init :parser, :least, :max
557
- def _parse ctxt
558
- result = []
559
- for i in (0...@least)
560
- return false unless @parser._parse ctxt
561
- result << ctxt.result
562
- end
563
- for i in (@least...@max)
564
- ind = ctxt.index
565
- if @parser._parse ctxt
566
- result << ctxt.result
567
- return ctxt.retn(result) if ind==ctxt.index # infinite loop
568
- next
569
- end
570
- if ind==ctxt.index
571
- return ctxt.retn(result)
572
- else
573
- return false
574
- end
575
- end
576
- return ctxt.retn(result)
577
- end
578
- end
579
-
580
- class OneParser < Parser
581
- def _parse ctxt
582
- true
583
- end
584
- end
585
-
586
- class ZeroParser < Parser
587
- def _parse ctxt
588
- return ctxt.failure
589
- end
590
- end
591
-
592
- class GetIndexParser < Parser
593
- def _parse ctxt
594
- ctxt.retn(ctxt.index)
595
- end
596
- end
597
- class SetIndexParser < Parser
598
- init :index
599
- def _parse ctxt
600
- ctxt.index = @index
601
- end
602
- end
603
-
1
+ require 'rparsec/parser'
2
+
3
+ class FailureParser < Parser
4
+ init :msg
5
+ def _parse ctxt
6
+ return ctxt.failure(@msg)
7
+ end
8
+ end
9
+
10
+ class ValueParser < Parser
11
+ init :value
12
+ def _parse ctxt
13
+ ctxt.retn @value
14
+ end
15
+ end
16
+
17
+ class LazyParser < Parser
18
+ init :block
19
+ def _parse ctxt
20
+ @block.call._parse ctxt
21
+ end
22
+ end
23
+
24
+ def add_error(err, e)
25
+ return e if err.nil?
26
+ return err if e.nil?
27
+ cmp = compare_error(err, e)
28
+ return err if cmp > 0
29
+ return e if cmp < 0
30
+ err
31
+ # merge_error(err, e)
32
+ end
33
+
34
+ def get_first_element(err)
35
+ while err.kind_of?(Array)
36
+ err = err[0]
37
+ end
38
+ err
39
+ end
40
+
41
+ def compare_error(e1, e2)
42
+ e1, e2 = get_first_element(e1), get_first_element(e2)
43
+ return -1 if e1.index < e2.index
44
+ return 1 if e1.index > e2.index
45
+ 0
46
+ end
47
+
48
+ ###############################################
49
+ #def merge_error(e1, e2)
50
+ # return e1 << e2 if e1.kind_of?(Array)
51
+ # [e1,e2]
52
+ #end
53
+ ###############################################
54
+ class ThrowParser < Parser
55
+ init :symbol
56
+ def _parse ctxt
57
+ throw @symbol
58
+ end
59
+ end
60
+
61
+ class CatchParser < Parser
62
+ init :symbol, :parser
63
+ def _parse ctxt
64
+ interrupted = true
65
+ ok = false
66
+ catch @symbol do
67
+ ok = @parser._parse(ctxt)
68
+ interrupted = false
69
+ end
70
+ return ctxt.retn(@symbol) if interrupted
71
+ ok
72
+ end
73
+ end
74
+
75
+ class PeekParser < Parser
76
+ init :parser
77
+ def _parse ctxt
78
+ ind = ctxt.index
79
+ return false unless @parser._parse ctxt
80
+ ctxt.index = ind
81
+ return true
82
+ end
83
+ def peek
84
+ self
85
+ end
86
+ end
87
+
88
+ class AtomParser < Parser
89
+ init :parser
90
+ def _parse ctxt
91
+ ind = ctxt.index
92
+ return true if @parser._parse ctxt
93
+ ctxt.index = ind
94
+ return false
95
+ end
96
+ def atomize
97
+ self
98
+ end
99
+ end
100
+
101
+ class LookAheadSensitiveParser < Parser
102
+ def initialize(la=1)
103
+ super()
104
+ @lookahead = la
105
+ end
106
+ def visible(ctxt, n)
107
+ ctxt.index - n < @lookahead
108
+ end
109
+ def lookahead(n)
110
+ raise ArgumentError, "lookahead number #{n} should be positive" unless n>0
111
+ return self if n == @lookahead
112
+ withLookahead(n)
113
+ end
114
+ def not(msg="#{self} unexpected")
115
+ NotParser.new(self, msg, @lookahead)
116
+ end
117
+ end
118
+
119
+ class NotParser < LookAheadSensitiveParser
120
+ def initialize(parser, msg, la=1)
121
+ super(la)
122
+ @parser, @msg, @name = parser, msg, "~#{parser.name}"
123
+ end
124
+ def _parse ctxt
125
+ ind = ctxt.index
126
+ if @parser._parse ctxt
127
+ ctxt.index = ind
128
+ return ctxt.expecting(@msg)
129
+ end
130
+ return ctxt.retn(nil) if visible(ctxt, ind)
131
+ return false
132
+ end
133
+ def withLookahead(n)
134
+ NotParser.new(@parser, @msg, n)
135
+ end
136
+ def not()
137
+ @parser
138
+ end
139
+ end
140
+
141
+ class ExpectParser < Parser
142
+ def initialize(parser, msg)
143
+ super()
144
+ @parser, @msg, @name = parser, msg, msg
145
+ end
146
+ def _parse ctxt
147
+ ind = ctxt.index
148
+ return true if @parser._parse ctxt
149
+ return false unless ind == ctxt.index
150
+ ctxt.expecting(@msg)
151
+ end
152
+ end
153
+
154
+ class PlusParser < LookAheadSensitiveParser
155
+ def initialize(alts, la=1)
156
+ super(la)
157
+ @alts = alts
158
+ end
159
+ def _parse ctxt
160
+ ind, result, err = ctxt.index, ctxt.result, ctxt.error
161
+ for p in @alts
162
+ ctxt.reset_error
163
+ ctxt.index, ctxt.result = ind, result
164
+ return true if p._parse(ctxt)
165
+ return false unless visible(ctxt, ind)
166
+ err = add_error(err, ctxt.error)
167
+ end
168
+ ctxt.error = err
169
+ return false
170
+ end
171
+ def withLookahead(n)
172
+ PlusParser.new(@alts, n)
173
+ end
174
+ def plus other
175
+ PlusParser.new(@alts.dup << other, @lookahead).setName(name)
176
+ end
177
+ def_sig :plus, Parser
178
+ end
179
+
180
+
181
+ class AltParser < LookAheadSensitiveParser
182
+ def initialize(alts, la = 1)
183
+ super(la)
184
+ @alts, @lookahead = alts, la
185
+ end
186
+ def _parse ctxt
187
+ ind, result, err = ctxt.index, ctxt.result, ctxt.error
188
+ err_ind, err_pos = -1, -1
189
+ for p in @alts
190
+ ctxt.reset_error
191
+ ctxt.index, ctxt.result = ind, result
192
+ return true if p._parse(ctxt)
193
+ if ctxt.error.index > err_pos
194
+ err, err_ind, err_pos = ctxt.error, ctxt.index, ctxt.error.index
195
+ end
196
+ end
197
+ ctxt.index, ctxt.error = err_ind, err
198
+ return false
199
+ end
200
+ def withLookahead(n)
201
+ AltParser.new(@alts, n)
202
+ end
203
+ def | other
204
+ AltParser.new(@alts.dup << autobox_parser(other)).setName(name)
205
+ end
206
+ end
207
+
208
+
209
+ class BestParser < Parser
210
+ init :alts, :longer
211
+ def _parse ctxt
212
+ best_result, best_ind = nil, -1
213
+ err_ind, err_pos = -1, -1
214
+ ind, result, err = ctxt.index, ctxt.result, ctxt.error
215
+ for p in @alts
216
+ ctxt.reset_error
217
+ ctxt.index, ctxt.result = ind, result
218
+ if p._parse(ctxt)
219
+ err, now_ind = nil, ctxt.index
220
+ if best_ind==-1 || now_ind != best_ind && @longer == (now_ind>best_ind)
221
+ best_result, best_ind = ctxt.result, now_ind
222
+ end
223
+ elsif best_ind < 0 # no good match found yet.
224
+ if ctxt.error.index > err_pos
225
+ err_ind, err_pos = ctxt.index, ctxt.error.index
226
+ end
227
+ err = add_error(err, ctxt.error)
228
+ end
229
+ end
230
+ if best_ind >= 0
231
+ ctxt.index = best_ind
232
+ return ctxt.retn(best_result)
233
+ else
234
+ ctxt.error, ctxt.index = err, err_ind
235
+ return false
236
+ end
237
+ end
238
+ end
239
+
240
+ class BoundParser < Parser
241
+ init :parser, :proc
242
+ def _parse ctxt
243
+ return false unless @parser._parse(ctxt)
244
+ @proc.call(ctxt.result)._parse ctxt
245
+ end
246
+ end
247
+
248
+ class BoundnParser < Parser
249
+ init :parser, :proc
250
+ def _parse ctxt
251
+ return false unless @parser._parse(ctxt)
252
+ @proc.call(*ctxt.result)._parse ctxt
253
+ end
254
+ end
255
+
256
+ class MapParser < Parser
257
+ init :parser, :proc
258
+ def _parse ctxt
259
+ return false unless @parser._parse(ctxt)
260
+ ctxt.result = @proc.call(ctxt.result)
261
+ true
262
+ end
263
+ end
264
+
265
+ class MapnParser < Parser
266
+ init :parser, :proc
267
+ def _parse ctxt
268
+ return false unless @parser._parse(ctxt)
269
+ ctxt.result = @proc.call(*ctxt.result)
270
+ true
271
+ end
272
+ end
273
+
274
+ class SequenceParser < Parser
275
+ init :parsers, :proc
276
+ def _parse ctxt
277
+ if @proc.nil?
278
+ for p in @parsers
279
+ return false unless p._parse(ctxt)
280
+ end
281
+ else
282
+ results = []
283
+ for p in @parsers
284
+ return false unless p._parse(ctxt)
285
+ results << ctxt.result
286
+ end
287
+ ctxt.retn(@proc.call(*results))
288
+ end
289
+ return true
290
+ end
291
+ def seq(other, &block)
292
+ # TypeChecker.check_arg_type Parser, other, :seq
293
+ SequenceParser.new(@parsers.dup << other, &block)
294
+ end
295
+ def_sig :seq, Parser
296
+ end
297
+
298
+ class FollowedParser < Parser
299
+ init :p1, :p2
300
+ def _parse ctxt
301
+ return false unless @p1._parse ctxt
302
+ result = ctxt.result
303
+ return false unless @p2._parse ctxt
304
+ ctxt.retn(result)
305
+ end
306
+ end
307
+
308
+ class SatisfiesParser < Parser
309
+ init :pred, :expected
310
+ def _parse ctxt
311
+ elem = nil
312
+ if ctxt.eof || !@pred.call(elem=ctxt.current)
313
+ return ctxt.expecting(@expected)
314
+ end
315
+ ctxt.next
316
+ ctxt.retn elem
317
+ end
318
+ end
319
+
320
+ class AnyParser < Parser
321
+ def _parse ctxt
322
+ return ctxt.expecting if ctxt.eof
323
+ result = ctxt.current
324
+ ctxt.next
325
+ ctxt.retn result
326
+ end
327
+ end
328
+
329
+ class EofParser < Parser
330
+ init :msg
331
+ def _parse ctxt
332
+ return true if ctxt.eof
333
+ return ctxt.expecting(@msg)
334
+ end
335
+ end
336
+
337
+ class RegexpParser < Parser
338
+ init :ptn, :msg
339
+ def _parse ctxt
340
+ scanner = ctxt.scanner
341
+ result = scanner.check @ptn
342
+ if result.nil?
343
+ ctxt.expecting(@msg)
344
+ else
345
+ ctxt.advance(scanner.matched_size)
346
+ ctxt.retn(result)
347
+ end
348
+ end
349
+ end
350
+
351
+ class AreParser < Parser
352
+ init :vals, :msg
353
+ def _parse ctxt
354
+ if @vals.length > ctxt.available
355
+ return ctxt.expecting(@msg)
356
+ end
357
+ cur = 0
358
+ for cur in (0...@vals.length)
359
+ if @vals[cur] != ctxt.peek(cur)
360
+ return ctxt.expecting(@msg)
361
+ end
362
+ end
363
+ ctxt.advance(@vals.length)
364
+ ctxt.retn @vals
365
+ end
366
+ end
367
+
368
+ def downcase c
369
+ case when c >= ?A && c <=?Z then c + (?a - ?A) else c end
370
+ end
371
+
372
+ class StringCaseInsensitiveParser < Parser
373
+ init :str, :msg
374
+ def _parse ctxt
375
+ if @str.length > ctxt.available
376
+ return ctxt.expecting(@msg)
377
+ end
378
+ cur = 0
379
+ for cur in (0...@str.length)
380
+ if downcase(@str[cur]) != downcase(ctxt.peek(cur))
381
+ return ctxt.expecting(@msg)
382
+ end
383
+ end
384
+ result = ctxt.src[ctxt.index, @str.length]
385
+ ctxt.advance(@str.length)
386
+ ctxt.retn result
387
+ end
388
+ end
389
+
390
+ class FragmentParser < Parser
391
+ init :parser
392
+ def _parse ctxt
393
+ ind = ctxt.index
394
+ return false unless @parser._parse ctxt
395
+ ctxt.retn(ctxt.src[ind, ctxt.index-ind])
396
+ end
397
+ end
398
+
399
+ class TokenParser < Parser
400
+ init :symbol, :parser
401
+ def _parse ctxt
402
+ ind = ctxt.index
403
+ return false unless @parser._parse ctxt
404
+ raw = ctxt.result
405
+ raw = ctxt.src[ind, ctxt.index-ind] unless raw.kind_of? String
406
+ ctxt.retn(Token.new(@symbol, raw, ind))
407
+ end
408
+ end
409
+
410
+ class NestedParser < Parser
411
+ init :parser1, :parser2
412
+ def _parse ctxt
413
+ ind = ctxt.index
414
+ return false unless @parser1._parse ctxt
415
+ _run_nested(ind, ctxt, ctxt.result, @parser2)
416
+ end
417
+ private
418
+ def _run_nested(start, ctxt, src, parser)
419
+ ctxt.error = nil
420
+ new_ctxt = nil
421
+ if src.kind_of? String
422
+ new_ctxt = ParseContext.new(src)
423
+ return true if _run_parser parser, ctxt, new_ctxt
424
+ ctxt.index = start + new_ctxt.index
425
+ elsif src.kind_of? Array
426
+ new_ctxt = ParseContext.new(src)
427
+ return true if _run_parser parser, ctxt, new_ctxt
428
+ ctxt.index = start + _get_index(new_ctxt) unless new_ctxt.eof
429
+ else
430
+ new_ctxt = ParseContext.new([src])
431
+ return true if _run_parser parser, ctxt, new_ctxt
432
+ ctxt.index = ind unless new_ctxt.eof
433
+ end
434
+ ctxt.error.index = ctxt.index
435
+ false
436
+ end
437
+ def _get_index ctxt
438
+ cur = ctxt.current
439
+ return cur.index if cur.respond_to? :index
440
+ ctxt.index
441
+ end
442
+ def _run_parser parser, old_ctxt, new_ctxt
443
+ if parser._parse new_ctxt
444
+ old_ctxt.result = new_ctxt.result
445
+ true
446
+ else
447
+ old_ctxt.error = new_ctxt.error
448
+ false
449
+ end
450
+ end
451
+ end
452
+
453
+ class WatchParser < Parser
454
+ init :proc
455
+ def _parse ctxt
456
+ @proc.call(ctxt.result)
457
+ true
458
+ end
459
+ end
460
+
461
+ class WatchnParser < Parser
462
+ init :proc
463
+ def _parse ctxt
464
+ @proc.call(*ctxt.result)
465
+ true
466
+ end
467
+ end
468
+
469
+ class MapCurrentParser < Parser
470
+ init :proc
471
+ def _parse ctxt
472
+ ctxt.result = @proc.call(ctxt.result)
473
+ true
474
+ end
475
+ end
476
+
477
+ class MapnCurrentParser < Parser
478
+ init :proc
479
+ def _parse ctxt
480
+ ctxt.result = @proc.call(*ctxt.result)
481
+ true
482
+ end
483
+ end
484
+
485
+ class Repeat_Parser < Parser
486
+ init :parser, :times
487
+ def _parse ctxt
488
+ for i in (0...@times)
489
+ return false unless @parser._parse ctxt
490
+ end
491
+ return true
492
+ end
493
+ end
494
+
495
+ class RepeatParser < Parser
496
+ init :parser, :times
497
+ def _parse ctxt
498
+ result = []
499
+ for i in (0...@times)
500
+ return false unless @parser._parse ctxt
501
+ result << ctxt.result
502
+ end
503
+ return ctxt.retn(result)
504
+ end
505
+ end
506
+
507
+ class Many_Parser < Parser
508
+ init :parser, :least
509
+ def _parse ctxt
510
+ for i in (0...@least)
511
+ return false unless @parser._parse ctxt
512
+ end
513
+ while(true)
514
+ ind = ctxt.index
515
+ if @parser._parse ctxt
516
+ return true if ind==ctxt.index # infinite loop
517
+ next
518
+ end
519
+ return ind==ctxt.index
520
+ end
521
+ end
522
+ end
523
+
524
+ class ManyParser < Parser
525
+ init :parser, :least
526
+ def _parse ctxt
527
+ result = []
528
+ for i in (0...@least)
529
+ return false unless @parser._parse ctxt
530
+ result << ctxt.result
531
+ end
532
+ while(true)
533
+ ind = ctxt.index
534
+ if @parser._parse ctxt
535
+ result << ctxt.result
536
+ return ctxt.retn(result) if ind==ctxt.index # infinite loop
537
+ next
538
+ end
539
+ if ind==ctxt.index
540
+ return ctxt.retn(result)
541
+ else
542
+ return false
543
+ end
544
+ end
545
+ end
546
+ end
547
+
548
+ class Some_Parser < Parser
549
+ init :parser, :least, :max
550
+ def _parse ctxt
551
+ for i in (0...@least)
552
+ return false unless @parser._parse ctxt
553
+ end
554
+ for i in (@least...@max)
555
+ ind = ctxt.index
556
+ if @parser._parse ctxt
557
+ return true if ind==ctxt.index # infinite loop
558
+ next
559
+ end
560
+ return ind==ctxt.index
561
+ end
562
+ return true
563
+ end
564
+ end
565
+
566
+ class SomeParser < Parser
567
+ init :parser, :least, :max
568
+ def _parse ctxt
569
+ result = []
570
+ for i in (0...@least)
571
+ return false unless @parser._parse ctxt
572
+ result << ctxt.result
573
+ end
574
+ for i in (@least...@max)
575
+ ind = ctxt.index
576
+ if @parser._parse ctxt
577
+ result << ctxt.result
578
+ return ctxt.retn(result) if ind==ctxt.index # infinite loop
579
+ next
580
+ end
581
+ if ind==ctxt.index
582
+ return ctxt.retn(result)
583
+ else
584
+ return false
585
+ end
586
+ end
587
+ return ctxt.retn(result)
588
+ end
589
+ end
590
+
591
+ class OneParser < Parser
592
+ def _parse ctxt
593
+ true
594
+ end
595
+ end
596
+
597
+ class ZeroParser < Parser
598
+ def _parse ctxt
599
+ return ctxt.failure
600
+ end
601
+ end
602
+
603
+ class GetIndexParser < Parser
604
+ def _parse ctxt
605
+ ctxt.retn(ctxt.index)
606
+ end
607
+ end
608
+ class SetIndexParser < Parser
609
+ init :index
610
+ def _parse ctxt
611
+ ctxt.index = @index
612
+ end
613
+ end
614
+
604
615
  Nil = ValueParser.new(nil)