OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-wire / expr / expr.go
1
2 package expr
3
4 import (
5         "bytes"
6   "encoding/hex"
7         "errors"
8         "fmt"
9         "io"
10         "io/ioutil"
11         "os"
12   "strconv"
13         "strings"
14         "unicode"
15         "unicode/utf8"
16 )
17
18 var g = &grammar {
19         rules: []*rule{
20 {
21         name: "Start",
22         pos: position{line: 19, col: 1, offset: 148},
23         expr: &actionExpr{
24         pos: position{line: 19, col: 9, offset: 158},
25         run: (*parser).callonStart1,
26         expr: &seqExpr{
27         pos: position{line: 19, col: 9, offset: 158},
28         exprs: []interface{}{
29 &labeledExpr{
30         pos: position{line: 19, col: 9, offset: 158},
31         label: "items_",
32         expr: &oneOrMoreExpr{
33         pos: position{line: 19, col: 16, offset: 165},
34         expr: &ruleRefExpr{
35         pos: position{line: 19, col: 16, offset: 165},
36         name: "Item",
37 },
38 },
39 },
40 &ruleRefExpr{
41         pos: position{line: 19, col: 22, offset: 171},
42         name: "_",
43 },
44 &ruleRefExpr{
45         pos: position{line: 19, col: 24, offset: 173},
46         name: "EOF",
47 },
48         },
49 },
50 },
51 },
52 {
53         name: "Item",
54         pos: position{line: 27, col: 1, offset: 307},
55         expr: &actionExpr{
56         pos: position{line: 27, col: 8, offset: 316},
57         run: (*parser).callonItem1,
58         expr: &seqExpr{
59         pos: position{line: 27, col: 8, offset: 316},
60         exprs: []interface{}{
61 &ruleRefExpr{
62         pos: position{line: 27, col: 8, offset: 316},
63         name: "_",
64 },
65 &labeledExpr{
66         pos: position{line: 27, col: 10, offset: 318},
67         label: "it",
68         expr: &choiceExpr{
69         pos: position{line: 27, col: 14, offset: 322},
70         alternatives: []interface{}{
71 &ruleRefExpr{
72         pos: position{line: 27, col: 14, offset: 322},
73         name: "Array",
74 },
75 &ruleRefExpr{
76         pos: position{line: 27, col: 22, offset: 330},
77         name: "Tuple",
78 },
79 &ruleRefExpr{
80         pos: position{line: 27, col: 30, offset: 338},
81         name: "Hex",
82 },
83 &ruleRefExpr{
84         pos: position{line: 27, col: 36, offset: 344},
85         name: "TypedNumeric",
86 },
87 &ruleRefExpr{
88         pos: position{line: 27, col: 51, offset: 359},
89         name: "UntypedNumeric",
90 },
91 &ruleRefExpr{
92         pos: position{line: 27, col: 68, offset: 376},
93         name: "Placeholder",
94 },
95 &ruleRefExpr{
96         pos: position{line: 27, col: 82, offset: 390},
97         name: "String",
98 },
99         },
100 },
101 },
102         },
103 },
104 },
105 },
106 {
107         name: "Array",
108         pos: position{line: 31, col: 1, offset: 422},
109         expr: &actionExpr{
110         pos: position{line: 31, col: 9, offset: 432},
111         run: (*parser).callonArray1,
112         expr: &seqExpr{
113         pos: position{line: 31, col: 9, offset: 432},
114         exprs: []interface{}{
115 &litMatcher{
116         pos: position{line: 31, col: 9, offset: 432},
117         val: "[",
118         ignoreCase: false,
119 },
120 &labeledExpr{
121         pos: position{line: 31, col: 13, offset: 436},
122         label: "items",
123         expr: &zeroOrMoreExpr{
124         pos: position{line: 31, col: 19, offset: 442},
125         expr: &ruleRefExpr{
126         pos: position{line: 31, col: 19, offset: 442},
127         name: "Item",
128 },
129 },
130 },
131 &ruleRefExpr{
132         pos: position{line: 31, col: 25, offset: 448},
133         name: "_",
134 },
135 &litMatcher{
136         pos: position{line: 31, col: 27, offset: 450},
137         val: "]",
138         ignoreCase: false,
139 },
140         },
141 },
142 },
143 },
144 {
145         name: "Tuple",
146         pos: position{line: 35, col: 1, offset: 504},
147         expr: &actionExpr{
148         pos: position{line: 35, col: 9, offset: 514},
149         run: (*parser).callonTuple1,
150         expr: &seqExpr{
151         pos: position{line: 35, col: 9, offset: 514},
152         exprs: []interface{}{
153 &litMatcher{
154         pos: position{line: 35, col: 9, offset: 514},
155         val: "(",
156         ignoreCase: false,
157 },
158 &labeledExpr{
159         pos: position{line: 35, col: 13, offset: 518},
160         label: "items",
161         expr: &oneOrMoreExpr{
162         pos: position{line: 35, col: 19, offset: 524},
163         expr: &ruleRefExpr{
164         pos: position{line: 35, col: 19, offset: 524},
165         name: "Item",
166 },
167 },
168 },
169 &ruleRefExpr{
170         pos: position{line: 35, col: 25, offset: 530},
171         name: "_",
172 },
173 &litMatcher{
174         pos: position{line: 35, col: 27, offset: 532},
175         val: ")",
176         ignoreCase: false,
177 },
178         },
179 },
180 },
181 },
182 {
183         name: "UntypedNumeric",
184         pos: position{line: 39, col: 1, offset: 586},
185         expr: &actionExpr{
186         pos: position{line: 39, col: 18, offset: 605},
187         run: (*parser).callonUntypedNumeric1,
188         expr: &labeledExpr{
189         pos: position{line: 39, col: 18, offset: 605},
190         label: "number",
191         expr: &ruleRefExpr{
192         pos: position{line: 39, col: 25, offset: 612},
193         name: "Integer",
194 },
195 },
196 },
197 },
198 {
199         name: "TypedNumeric",
200         pos: position{line: 46, col: 1, offset: 704},
201         expr: &actionExpr{
202         pos: position{line: 46, col: 16, offset: 721},
203         run: (*parser).callonTypedNumeric1,
204         expr: &seqExpr{
205         pos: position{line: 46, col: 16, offset: 721},
206         exprs: []interface{}{
207 &labeledExpr{
208         pos: position{line: 46, col: 16, offset: 721},
209         label: "t",
210         expr: &ruleRefExpr{
211         pos: position{line: 46, col: 18, offset: 723},
212         name: "Type",
213 },
214 },
215 &litMatcher{
216         pos: position{line: 46, col: 23, offset: 728},
217         val: ":",
218         ignoreCase: false,
219 },
220 &labeledExpr{
221         pos: position{line: 46, col: 27, offset: 732},
222         label: "number",
223         expr: &ruleRefExpr{
224         pos: position{line: 46, col: 34, offset: 739},
225         name: "Integer",
226 },
227 },
228         },
229 },
230 },
231 },
232 {
233         name: "Hex",
234         pos: position{line: 53, col: 1, offset: 838},
235         expr: &choiceExpr{
236         pos: position{line: 53, col: 7, offset: 846},
237         alternatives: []interface{}{
238 &ruleRefExpr{
239         pos: position{line: 53, col: 7, offset: 846},
240         name: "HexLengthPrefixed",
241 },
242 &ruleRefExpr{
243         pos: position{line: 53, col: 27, offset: 866},
244         name: "HexRaw",
245 },
246         },
247 },
248 },
249 {
250         name: "HexLengthPrefixed",
251         pos: position{line: 55, col: 1, offset: 874},
252         expr: &actionExpr{
253         pos: position{line: 55, col: 21, offset: 896},
254         run: (*parser).callonHexLengthPrefixed1,
255         expr: &seqExpr{
256         pos: position{line: 55, col: 21, offset: 896},
257         exprs: []interface{}{
258 &litMatcher{
259         pos: position{line: 55, col: 21, offset: 896},
260         val: "0x",
261         ignoreCase: false,
262 },
263 &labeledExpr{
264         pos: position{line: 55, col: 26, offset: 901},
265         label: "hexbytes",
266         expr: &ruleRefExpr{
267         pos: position{line: 55, col: 35, offset: 910},
268         name: "HexBytes",
269 },
270 },
271         },
272 },
273 },
274 },
275 {
276         name: "HexRaw",
277         pos: position{line: 59, col: 1, offset: 974},
278         expr: &actionExpr{
279         pos: position{line: 59, col: 10, offset: 985},
280         run: (*parser).callonHexRaw1,
281         expr: &seqExpr{
282         pos: position{line: 59, col: 10, offset: 985},
283         exprs: []interface{}{
284 &litMatcher{
285         pos: position{line: 59, col: 10, offset: 985},
286         val: "x",
287         ignoreCase: false,
288 },
289 &labeledExpr{
290         pos: position{line: 59, col: 14, offset: 989},
291         label: "hexbytes",
292         expr: &ruleRefExpr{
293         pos: position{line: 59, col: 23, offset: 998},
294         name: "HexBytes",
295 },
296 },
297         },
298 },
299 },
300 },
301 {
302         name: "HexBytes",
303         pos: position{line: 63, col: 1, offset: 1063},
304         expr: &actionExpr{
305         pos: position{line: 63, col: 12, offset: 1076},
306         run: (*parser).callonHexBytes1,
307         expr: &oneOrMoreExpr{
308         pos: position{line: 63, col: 12, offset: 1076},
309         expr: &charClassMatcher{
310         pos: position{line: 63, col: 12, offset: 1076},
311         val: "[0-9abcdefABCDEF]",
312         chars: []rune{'a','b','c','d','e','f','A','B','C','D','E','F',},
313         ranges: []rune{'0','9',},
314         ignoreCase: false,
315         inverted: false,
316 },
317 },
318 },
319 },
320 {
321         name: "Type",
322         pos: position{line: 71, col: 1, offset: 1223},
323         expr: &actionExpr{
324         pos: position{line: 71, col: 8, offset: 1232},
325         run: (*parser).callonType1,
326         expr: &choiceExpr{
327         pos: position{line: 71, col: 9, offset: 1233},
328         alternatives: []interface{}{
329 &litMatcher{
330         pos: position{line: 71, col: 9, offset: 1233},
331         val: "u64",
332         ignoreCase: false,
333 },
334 &litMatcher{
335         pos: position{line: 71, col: 17, offset: 1241},
336         val: "i64",
337         ignoreCase: false,
338 },
339         },
340 },
341 },
342 },
343 {
344         name: "Integer",
345         pos: position{line: 75, col: 1, offset: 1284},
346         expr: &actionExpr{
347         pos: position{line: 75, col: 11, offset: 1296},
348         run: (*parser).callonInteger1,
349         expr: &seqExpr{
350         pos: position{line: 75, col: 11, offset: 1296},
351         exprs: []interface{}{
352 &zeroOrOneExpr{
353         pos: position{line: 75, col: 11, offset: 1296},
354         expr: &litMatcher{
355         pos: position{line: 75, col: 11, offset: 1296},
356         val: "-",
357         ignoreCase: false,
358 },
359 },
360 &oneOrMoreExpr{
361         pos: position{line: 75, col: 16, offset: 1301},
362         expr: &charClassMatcher{
363         pos: position{line: 75, col: 16, offset: 1301},
364         val: "[0-9]",
365         ranges: []rune{'0','9',},
366         ignoreCase: false,
367         inverted: false,
368 },
369 },
370         },
371 },
372 },
373 },
374 {
375         name: "Label",
376         pos: position{line: 79, col: 1, offset: 1344},
377         expr: &actionExpr{
378         pos: position{line: 79, col: 9, offset: 1354},
379         run: (*parser).callonLabel1,
380         expr: &oneOrMoreExpr{
381         pos: position{line: 79, col: 9, offset: 1354},
382         expr: &charClassMatcher{
383         pos: position{line: 79, col: 9, offset: 1354},
384         val: "[0-9a-zA-Z:]",
385         chars: []rune{':',},
386         ranges: []rune{'0','9','a','z','A','Z',},
387         ignoreCase: false,
388         inverted: false,
389 },
390 },
391 },
392 },
393 {
394         name: "Placeholder",
395         pos: position{line: 83, col: 1, offset: 1404},
396         expr: &actionExpr{
397         pos: position{line: 83, col: 15, offset: 1420},
398         run: (*parser).callonPlaceholder1,
399         expr: &seqExpr{
400         pos: position{line: 83, col: 15, offset: 1420},
401         exprs: []interface{}{
402 &litMatcher{
403         pos: position{line: 83, col: 15, offset: 1420},
404         val: "<",
405         ignoreCase: false,
406 },
407 &labeledExpr{
408         pos: position{line: 83, col: 19, offset: 1424},
409         label: "label",
410         expr: &ruleRefExpr{
411         pos: position{line: 83, col: 25, offset: 1430},
412         name: "Label",
413 },
414 },
415 &litMatcher{
416         pos: position{line: 83, col: 31, offset: 1436},
417         val: ">",
418         ignoreCase: false,
419 },
420         },
421 },
422 },
423 },
424 {
425         name: "String",
426         pos: position{line: 89, col: 1, offset: 1509},
427         expr: &actionExpr{
428         pos: position{line: 89, col: 10, offset: 1520},
429         run: (*parser).callonString1,
430         expr: &seqExpr{
431         pos: position{line: 89, col: 10, offset: 1520},
432         exprs: []interface{}{
433 &litMatcher{
434         pos: position{line: 89, col: 10, offset: 1520},
435         val: "\"",
436         ignoreCase: false,
437 },
438 &zeroOrMoreExpr{
439         pos: position{line: 89, col: 14, offset: 1524},
440         expr: &choiceExpr{
441         pos: position{line: 89, col: 16, offset: 1526},
442         alternatives: []interface{}{
443 &seqExpr{
444         pos: position{line: 89, col: 16, offset: 1526},
445         exprs: []interface{}{
446 &notExpr{
447         pos: position{line: 89, col: 16, offset: 1526},
448         expr: &ruleRefExpr{
449         pos: position{line: 89, col: 17, offset: 1527},
450         name: "EscapedChar",
451 },
452 },
453 &anyMatcher{
454         line: 89, col: 29, offset: 1539,
455 },
456         },
457 },
458 &seqExpr{
459         pos: position{line: 89, col: 33, offset: 1543},
460         exprs: []interface{}{
461 &litMatcher{
462         pos: position{line: 89, col: 33, offset: 1543},
463         val: "\\",
464         ignoreCase: false,
465 },
466 &ruleRefExpr{
467         pos: position{line: 89, col: 38, offset: 1548},
468         name: "EscapeSequence",
469 },
470         },
471 },
472         },
473 },
474 },
475 &litMatcher{
476         pos: position{line: 89, col: 56, offset: 1566},
477         val: "\"",
478         ignoreCase: false,
479 },
480         },
481 },
482 },
483 },
484 {
485         name: "EscapedChar",
486         pos: position{line: 100, col: 1, offset: 1839},
487         expr: &charClassMatcher{
488         pos: position{line: 100, col: 15, offset: 1855},
489         val: "[\\x00-\\x1f\"\\\\]",
490         chars: []rune{'"','\\',},
491         ranges: []rune{'\x00','\x1f',},
492         ignoreCase: false,
493         inverted: false,
494 },
495 },
496 {
497         name: "EscapeSequence",
498         pos: position{line: 102, col: 1, offset: 1871},
499         expr: &choiceExpr{
500         pos: position{line: 102, col: 18, offset: 1890},
501         alternatives: []interface{}{
502 &ruleRefExpr{
503         pos: position{line: 102, col: 18, offset: 1890},
504         name: "SingleCharEscape",
505 },
506 &ruleRefExpr{
507         pos: position{line: 102, col: 37, offset: 1909},
508         name: "UnicodeEscape",
509 },
510         },
511 },
512 },
513 {
514         name: "SingleCharEscape",
515         pos: position{line: 104, col: 1, offset: 1924},
516         expr: &charClassMatcher{
517         pos: position{line: 104, col: 20, offset: 1945},
518         val: "[\"\\\\/bfnrt]",
519         chars: []rune{'"','\\','/','b','f','n','r','t',},
520         ignoreCase: false,
521         inverted: false,
522 },
523 },
524 {
525         name: "UnicodeEscape",
526         pos: position{line: 106, col: 1, offset: 1958},
527         expr: &seqExpr{
528         pos: position{line: 106, col: 17, offset: 1976},
529         exprs: []interface{}{
530 &litMatcher{
531         pos: position{line: 106, col: 17, offset: 1976},
532         val: "u",
533         ignoreCase: false,
534 },
535 &ruleRefExpr{
536         pos: position{line: 106, col: 21, offset: 1980},
537         name: "HexDigit",
538 },
539 &ruleRefExpr{
540         pos: position{line: 106, col: 30, offset: 1989},
541         name: "HexDigit",
542 },
543 &ruleRefExpr{
544         pos: position{line: 106, col: 39, offset: 1998},
545         name: "HexDigit",
546 },
547 &ruleRefExpr{
548         pos: position{line: 106, col: 48, offset: 2007},
549         name: "HexDigit",
550 },
551         },
552 },
553 },
554 {
555         name: "HexDigit",
556         pos: position{line: 108, col: 1, offset: 2017},
557         expr: &charClassMatcher{
558         pos: position{line: 108, col: 12, offset: 2030},
559         val: "[0-9a-f]i",
560         ranges: []rune{'0','9','a','f',},
561         ignoreCase: true,
562         inverted: false,
563 },
564 },
565 {
566         name: "_",
567         displayName: "\"whitespace\"",
568         pos: position{line: 110, col: 1, offset: 2041},
569         expr: &zeroOrMoreExpr{
570         pos: position{line: 110, col: 18, offset: 2060},
571         expr: &charClassMatcher{
572         pos: position{line: 110, col: 18, offset: 2060},
573         val: "[ \\n\\t\\r]",
574         chars: []rune{' ','\n','\t','\r',},
575         ignoreCase: false,
576         inverted: false,
577 },
578 },
579 },
580 {
581         name: "EOF",
582         pos: position{line: 112, col: 1, offset: 2072},
583         expr: &notExpr{
584         pos: position{line: 112, col: 7, offset: 2080},
585         expr: &anyMatcher{
586         line: 112, col: 8, offset: 2081,
587 },
588 },
589 },
590         },
591 }
592 func (c *current) onStart1(items_ interface{}) (interface{}, error) {
593     items := items_.([]interface{})
594     if len(items) == 1 {
595         return items[0], nil
596     }
597     return Tuple(items), nil
598 }
599
600 func (p *parser) callonStart1() (interface{}, error) {
601         stack := p.vstack[len(p.vstack)-1]
602         _ = stack
603         return p.cur.onStart1(stack["items_"])
604 }
605
606 func (c *current) onItem1(it interface{}) (interface{}, error) {
607     return it, nil
608 }
609
610 func (p *parser) callonItem1() (interface{}, error) {
611         stack := p.vstack[len(p.vstack)-1]
612         _ = stack
613         return p.cur.onItem1(stack["it"])
614 }
615
616 func (c *current) onArray1(items interface{}) (interface{}, error) {
617     return Array(items.([]interface{})), nil
618 }
619
620 func (p *parser) callonArray1() (interface{}, error) {
621         stack := p.vstack[len(p.vstack)-1]
622         _ = stack
623         return p.cur.onArray1(stack["items"])
624 }
625
626 func (c *current) onTuple1(items interface{}) (interface{}, error) {
627     return Tuple(items.([]interface{})), nil
628 }
629
630 func (p *parser) callonTuple1() (interface{}, error) {
631         stack := p.vstack[len(p.vstack)-1]
632         _ = stack
633         return p.cur.onTuple1(stack["items"])
634 }
635
636 func (c *current) onUntypedNumeric1(number interface{}) (interface{}, error) {
637     return Numeric{
638       Type: "i",
639       Number: number.(string),
640     }, nil
641 }
642
643 func (p *parser) callonUntypedNumeric1() (interface{}, error) {
644         stack := p.vstack[len(p.vstack)-1]
645         _ = stack
646         return p.cur.onUntypedNumeric1(stack["number"])
647 }
648
649 func (c *current) onTypedNumeric1(t, number interface{}) (interface{}, error) {
650     return Numeric{
651       Type: t.(string),
652       Number: number.(string),
653     }, nil
654 }
655
656 func (p *parser) callonTypedNumeric1() (interface{}, error) {
657         stack := p.vstack[len(p.vstack)-1]
658         _ = stack
659         return p.cur.onTypedNumeric1(stack["t"], stack["number"])
660 }
661
662 func (c *current) onHexLengthPrefixed1(hexbytes interface{}) (interface{}, error) {
663     return NewBytes(hexbytes.([]byte), true), nil
664 }
665
666 func (p *parser) callonHexLengthPrefixed1() (interface{}, error) {
667         stack := p.vstack[len(p.vstack)-1]
668         _ = stack
669         return p.cur.onHexLengthPrefixed1(stack["hexbytes"])
670 }
671
672 func (c *current) onHexRaw1(hexbytes interface{}) (interface{}, error) {
673     return NewBytes(hexbytes.([]byte), false), nil
674 }
675
676 func (p *parser) callonHexRaw1() (interface{}, error) {
677         stack := p.vstack[len(p.vstack)-1]
678         _ = stack
679         return p.cur.onHexRaw1(stack["hexbytes"])
680 }
681
682 func (c *current) onHexBytes1() (interface{}, error) {
683     bytez, err := hex.DecodeString(string(c.text))
684     if err != nil {
685         return nil, err
686     }
687     return bytez, nil
688 }
689
690 func (p *parser) callonHexBytes1() (interface{}, error) {
691         stack := p.vstack[len(p.vstack)-1]
692         _ = stack
693         return p.cur.onHexBytes1()
694 }
695
696 func (c *current) onType1() (interface{}, error) {
697     return string(c.text), nil
698 }
699
700 func (p *parser) callonType1() (interface{}, error) {
701         stack := p.vstack[len(p.vstack)-1]
702         _ = stack
703         return p.cur.onType1()
704 }
705
706 func (c *current) onInteger1() (interface{}, error) {
707     return string(c.text), nil
708 }
709
710 func (p *parser) callonInteger1() (interface{}, error) {
711         stack := p.vstack[len(p.vstack)-1]
712         _ = stack
713         return p.cur.onInteger1()
714 }
715
716 func (c *current) onLabel1() (interface{}, error) {
717     return string(c.text), nil
718 }
719
720 func (p *parser) callonLabel1() (interface{}, error) {
721         stack := p.vstack[len(p.vstack)-1]
722         _ = stack
723         return p.cur.onLabel1()
724 }
725
726 func (c *current) onPlaceholder1(label interface{}) (interface{}, error) {
727     return Placeholder{
728       Label: label.(string),
729     }, nil
730 }
731
732 func (p *parser) callonPlaceholder1() (interface{}, error) {
733         stack := p.vstack[len(p.vstack)-1]
734         _ = stack
735         return p.cur.onPlaceholder1(stack["label"])
736 }
737
738 func (c *current) onString1() (interface{}, error) {
739     // TODO : the forward slash (solidus) is not a valid escape in Go, it will
740     // fail if there's one in the string
741     text, err := strconv.Unquote(string(c.text))
742     if err != nil {
743       return nil, err
744     } else {
745       return NewString(text), nil
746     }
747 }
748
749 func (p *parser) callonString1() (interface{}, error) {
750         stack := p.vstack[len(p.vstack)-1]
751         _ = stack
752         return p.cur.onString1()
753 }
754
755
756 var (
757         // errNoRule is returned when the grammar to parse has no rule.
758         errNoRule          = errors.New("grammar has no rule")
759
760         // errInvalidEncoding is returned when the source is not properly
761         // utf8-encoded.
762         errInvalidEncoding = errors.New("invalid encoding")
763
764         // errNoMatch is returned if no match could be found.
765         errNoMatch         = errors.New("no match found")
766 )
767
768 // Option is a function that can set an option on the parser. It returns
769 // the previous setting as an Option.
770 type Option func(*parser) Option
771
772 // Debug creates an Option to set the debug flag to b. When set to true,
773 // debugging information is printed to stdout while parsing.
774 //
775 // The default is false.
776 func Debug(b bool) Option {
777         return func(p *parser) Option {
778                 old := p.debug
779                 p.debug = b
780                 return Debug(old)
781         }
782 }
783
784 // Memoize creates an Option to set the memoize flag to b. When set to true,
785 // the parser will cache all results so each expression is evaluated only
786 // once. This guarantees linear parsing time even for pathological cases,
787 // at the expense of more memory and slower times for typical cases.
788 //
789 // The default is false.
790 func Memoize(b bool) Option {
791         return func(p *parser) Option {
792                 old := p.memoize
793                 p.memoize = b
794                 return Memoize(old)
795         }
796 }
797
798 // Recover creates an Option to set the recover flag to b. When set to
799 // true, this causes the parser to recover from panics and convert it
800 // to an error. Setting it to false can be useful while debugging to
801 // access the full stack trace.
802 //
803 // The default is true.
804 func Recover(b bool) Option {
805         return func(p *parser) Option {
806                 old := p.recover
807                 p.recover = b
808                 return Recover(old)
809         }
810 }
811
812 // ParseFile parses the file identified by filename.
813 func ParseFile(filename string, opts ...Option) (interface{}, error) {
814         f, err := os.Open(filename)
815         if err != nil {
816                 return nil, err
817         }
818         defer f.Close()
819         return ParseReader(filename, f, opts...)
820 }
821
822 // ParseReader parses the data from r using filename as information in the
823 // error messages.
824 func ParseReader(filename string, r io.Reader, opts ...Option) (interface{}, error) {
825         b, err := ioutil.ReadAll(r)
826         if err != nil {
827                 return nil, err
828         }
829
830         return Parse(filename, b, opts...)
831 }
832
833 // Parse parses the data from b using filename as information in the
834 // error messages.
835 func Parse(filename string, b []byte, opts ...Option) (interface{}, error) {
836         return newParser(filename, b, opts...).parse(g)
837 }
838
839 // position records a position in the text.
840 type position struct {
841         line, col, offset int
842 }
843
844 func (p position) String() string {
845         return fmt.Sprintf("%d:%d [%d]", p.line, p.col, p.offset)
846 }
847
848 // savepoint stores all state required to go back to this point in the
849 // parser.
850 type savepoint struct {
851         position
852         rn rune
853         w  int
854 }
855
856 type current struct {
857         pos  position // start position of the match
858         text []byte   // raw text of the match
859 }
860
861 // the AST types...
862
863 type grammar struct {
864         pos   position
865         rules []*rule
866 }
867
868 type rule struct {
869         pos         position
870         name        string
871         displayName string
872         expr        interface{}
873 }
874
875 type choiceExpr struct {
876         pos          position
877         alternatives []interface{}
878 }
879
880 type actionExpr struct {
881         pos    position
882         expr   interface{}
883         run    func(*parser) (interface{}, error)
884 }
885
886 type seqExpr struct {
887         pos   position
888         exprs []interface{}
889 }
890
891 type labeledExpr struct {
892         pos   position
893         label string
894         expr  interface{}
895 }
896
897 type expr struct {
898         pos  position
899         expr interface{}
900 }
901
902 type andExpr expr
903 type notExpr expr
904 type zeroOrOneExpr expr
905 type zeroOrMoreExpr expr
906 type oneOrMoreExpr expr
907
908 type ruleRefExpr struct {
909         pos  position
910         name string
911 }
912
913 type andCodeExpr struct {
914         pos position
915         run func(*parser) (bool, error)
916 }
917
918 type notCodeExpr struct {
919         pos position
920         run func(*parser) (bool, error)
921 }
922
923 type litMatcher struct {
924         pos        position
925         val        string
926         ignoreCase bool
927 }
928
929 type charClassMatcher struct {
930         pos        position
931         val        string
932         chars      []rune
933         ranges     []rune
934         classes    []*unicode.RangeTable
935         ignoreCase bool
936         inverted   bool
937 }
938
939 type anyMatcher position
940
941 // errList cumulates the errors found by the parser.
942 type errList []error
943
944 func (e *errList) add(err error) {
945         *e = append(*e, err)
946 }
947
948 func (e errList) err() error {
949         if len(e) == 0 {
950                 return nil
951         }
952         e.dedupe()
953         return e
954 }
955
956 func (e *errList) dedupe() {
957         var cleaned []error
958         set := make(map[string]bool)
959         for _, err := range *e {
960                 if msg := err.Error(); !set[msg] {
961                         set[msg] = true
962                         cleaned = append(cleaned, err)
963                 }
964         }
965         *e = cleaned
966 }
967
968 func (e errList) Error() string {
969         switch len(e) {
970         case 0:
971                 return ""
972         case 1:
973                 return e[0].Error()
974         default:
975                 var buf bytes.Buffer
976
977                 for i, err := range e {
978                         if i > 0 {
979                                 buf.WriteRune('\n')
980                         }
981                         buf.WriteString(err.Error())
982                 }
983                 return buf.String()
984         }
985 }
986
987 // parserError wraps an error with a prefix indicating the rule in which
988 // the error occurred. The original error is stored in the Inner field.
989 type parserError struct {
990         Inner  error
991         pos    position
992         prefix string
993 }
994
995 // Error returns the error message.
996 func (p *parserError) Error() string {
997         return p.prefix + ": " + p.Inner.Error()
998 }
999
1000 // newParser creates a parser with the specified input source and options.
1001 func newParser(filename string, b []byte, opts ...Option) *parser {
1002         p := &parser{
1003                 filename: filename,
1004                 errs: new(errList),
1005                 data: b,
1006                 pt: savepoint{position: position{line: 1}},
1007                 recover: true,
1008         }
1009         p.setOptions(opts)
1010         return p
1011 }
1012
1013 // setOptions applies the options to the parser.
1014 func (p *parser) setOptions(opts []Option) {
1015         for _, opt := range opts {
1016                 opt(p)
1017         }
1018 }
1019
1020 type resultTuple struct {
1021         v interface{}
1022         b bool
1023         end savepoint
1024 }
1025
1026 type parser struct {
1027         filename string
1028         pt       savepoint
1029         cur      current
1030
1031         data []byte
1032         errs *errList
1033
1034         recover bool
1035         debug bool
1036         depth  int
1037
1038         memoize bool
1039         // memoization table for the packrat algorithm:
1040         // map[offset in source] map[expression or rule] {value, match}
1041         memo map[int]map[interface{}]resultTuple
1042
1043         // rules table, maps the rule identifier to the rule node
1044         rules  map[string]*rule
1045         // variables stack, map of label to value
1046         vstack []map[string]interface{}
1047         // rule stack, allows identification of the current rule in errors
1048         rstack []*rule
1049
1050         // stats
1051         exprCnt int
1052 }
1053
1054 // push a variable set on the vstack.
1055 func (p *parser) pushV() {
1056         if cap(p.vstack) == len(p.vstack) {
1057                 // create new empty slot in the stack
1058                 p.vstack = append(p.vstack, nil)
1059         } else {
1060                 // slice to 1 more
1061                 p.vstack = p.vstack[:len(p.vstack)+1]
1062         }
1063
1064         // get the last args set
1065         m := p.vstack[len(p.vstack)-1]
1066         if m != nil && len(m) == 0 {
1067                 // empty map, all good
1068                 return
1069         }
1070
1071         m = make(map[string]interface{})
1072         p.vstack[len(p.vstack)-1] = m
1073 }
1074
1075 // pop a variable set from the vstack.
1076 func (p *parser) popV() {
1077         // if the map is not empty, clear it
1078         m := p.vstack[len(p.vstack)-1]
1079         if len(m) > 0 {
1080                 // GC that map
1081                 p.vstack[len(p.vstack)-1] = nil
1082         }
1083         p.vstack = p.vstack[:len(p.vstack)-1]
1084 }
1085
1086 func (p *parser) print(prefix, s string) string {
1087         if !p.debug {
1088                 return s
1089         }
1090
1091         fmt.Printf("%s %d:%d:%d: %s [%#U]\n",
1092                 prefix, p.pt.line, p.pt.col, p.pt.offset, s, p.pt.rn)
1093         return s
1094 }
1095
1096 func (p *parser) in(s string) string {
1097         p.depth++
1098         return p.print(strings.Repeat(" ", p.depth) + ">", s)
1099 }
1100
1101 func (p *parser) out(s string) string {
1102         p.depth--
1103         return p.print(strings.Repeat(" ", p.depth) + "<", s)
1104 }
1105
1106 func (p *parser) addErr(err error) {
1107         p.addErrAt(err, p.pt.position)
1108 }
1109
1110 func (p *parser) addErrAt(err error, pos position) {
1111         var buf bytes.Buffer
1112         if p.filename != "" {
1113                 buf.WriteString(p.filename)
1114         }
1115         if buf.Len() > 0 {
1116                 buf.WriteString(":")
1117         }
1118         buf.WriteString(fmt.Sprintf("%d:%d (%d)", pos.line, pos.col, pos.offset))
1119         if len(p.rstack) > 0 {
1120                 if buf.Len() > 0 {
1121                         buf.WriteString(": ")
1122                 }
1123                 rule := p.rstack[len(p.rstack)-1]
1124                 if rule.displayName != "" {
1125                         buf.WriteString("rule " + rule.displayName)
1126                 } else {
1127                         buf.WriteString("rule " + rule.name)
1128                 }
1129         }
1130         pe := &parserError{Inner: err, prefix: buf.String()}
1131         p.errs.add(pe)
1132 }
1133
1134 // read advances the parser to the next rune.
1135 func (p *parser) read() {
1136         p.pt.offset += p.pt.w
1137         rn, n := utf8.DecodeRune(p.data[p.pt.offset:])
1138         p.pt.rn = rn
1139         p.pt.w = n
1140         p.pt.col++
1141         if rn == '\n' {
1142                 p.pt.line++
1143                 p.pt.col = 0
1144         }
1145
1146         if rn == utf8.RuneError {
1147                 if n > 0 {
1148                         p.addErr(errInvalidEncoding)
1149                 }
1150         }
1151 }
1152
1153 // restore parser position to the savepoint pt.
1154 func (p *parser) restore(pt savepoint) {
1155         if p.debug {
1156                 defer p.out(p.in("restore"))
1157         }
1158         if pt.offset == p.pt.offset {
1159                 return
1160         }
1161         p.pt = pt
1162 }
1163
1164 // get the slice of bytes from the savepoint start to the current position.
1165 func (p *parser) sliceFrom(start savepoint) []byte {
1166         return p.data[start.position.offset:p.pt.position.offset]
1167 }
1168
1169 func (p *parser) getMemoized(node interface{}) (resultTuple, bool) {
1170         if len(p.memo) == 0 {
1171                 return resultTuple{}, false
1172         }
1173         m := p.memo[p.pt.offset]
1174         if len(m) == 0 {
1175                 return resultTuple{}, false
1176         }
1177         res, ok := m[node]
1178         return res, ok
1179 }
1180
1181 func (p *parser) setMemoized(pt savepoint, node interface{}, tuple resultTuple) {
1182         if p.memo == nil {
1183                 p.memo = make(map[int]map[interface{}]resultTuple)
1184         }
1185         m := p.memo[pt.offset]
1186         if m == nil {
1187                 m = make(map[interface{}]resultTuple)
1188                 p.memo[pt.offset] = m
1189         }
1190         m[node] = tuple
1191 }
1192
1193 func (p *parser) buildRulesTable(g *grammar) {
1194         p.rules = make(map[string]*rule, len(g.rules))
1195         for _, r := range g.rules {
1196                 p.rules[r.name] = r
1197         }
1198 }
1199
1200 func (p *parser) parse(g *grammar) (val interface{}, err error) {
1201         if len(g.rules) == 0 {
1202                 p.addErr(errNoRule)
1203                 return nil, p.errs.err()
1204         }
1205
1206         // TODO : not super critical but this could be generated
1207         p.buildRulesTable(g)
1208
1209         if p.recover {
1210                 // panic can be used in action code to stop parsing immediately
1211                 // and return the panic as an error.
1212                 defer func() {
1213                         if e := recover(); e != nil {
1214                                 if p.debug {
1215                                         defer p.out(p.in("panic handler"))
1216                                 }
1217                                 val = nil
1218                                 switch e := e.(type) {
1219                                 case error:
1220                                         p.addErr(e)
1221                                 default:
1222                                         p.addErr(fmt.Errorf("%v", e))
1223                                 }
1224                                 err = p.errs.err()
1225                         }
1226                 }()
1227         }
1228
1229         // start rule is rule [0]
1230         p.read() // advance to first rune
1231         val, ok := p.parseRule(g.rules[0])
1232         if !ok {
1233                 if len(*p.errs) == 0 {
1234                         // make sure this doesn't go out silently
1235                         p.addErr(errNoMatch)
1236                 }
1237                 return nil, p.errs.err()
1238         }
1239         return val, p.errs.err()
1240 }
1241
1242 func (p *parser) parseRule(rule *rule) (interface{}, bool) {
1243         if p.debug {
1244                 defer p.out(p.in("parseRule " + rule.name))
1245         }
1246
1247         if p.memoize {
1248                 res, ok := p.getMemoized(rule)
1249                 if ok {
1250                         p.restore(res.end)
1251                         return res.v, res.b
1252                 }
1253         }
1254
1255         start := p.pt
1256         p.rstack = append(p.rstack, rule)
1257         p.pushV()
1258         val, ok := p.parseExpr(rule.expr)
1259         p.popV()
1260         p.rstack = p.rstack[:len(p.rstack)-1]
1261         if ok && p.debug {
1262                 p.print(strings.Repeat(" ", p.depth) + "MATCH", string(p.sliceFrom(start)))
1263         }
1264
1265         if p.memoize {
1266                 p.setMemoized(start, rule, resultTuple{val, ok, p.pt})
1267         }
1268         return val, ok
1269 }
1270
1271 func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {
1272         var pt savepoint
1273         var ok bool
1274
1275         if p.memoize {
1276                 res, ok := p.getMemoized(expr)
1277                 if ok {
1278                         p.restore(res.end)
1279                         return res.v, res.b
1280                 }
1281                 pt = p.pt
1282         }
1283
1284         p.exprCnt++
1285         var val interface{}
1286         switch expr := expr.(type) {
1287         case *actionExpr:
1288                 val, ok = p.parseActionExpr(expr)
1289         case *andCodeExpr:
1290                 val, ok = p.parseAndCodeExpr(expr)
1291         case *andExpr:
1292                 val, ok = p.parseAndExpr(expr)
1293         case *anyMatcher:
1294                 val, ok = p.parseAnyMatcher(expr)
1295         case *charClassMatcher:
1296                 val, ok = p.parseCharClassMatcher(expr)
1297         case *choiceExpr:
1298                 val, ok = p.parseChoiceExpr(expr)
1299         case *labeledExpr:
1300                 val, ok = p.parseLabeledExpr(expr)
1301         case *litMatcher:
1302                 val, ok = p.parseLitMatcher(expr)
1303         case *notCodeExpr:
1304                 val, ok = p.parseNotCodeExpr(expr)
1305         case *notExpr:
1306                 val, ok = p.parseNotExpr(expr)
1307         case *oneOrMoreExpr:
1308                 val, ok = p.parseOneOrMoreExpr(expr)
1309         case *ruleRefExpr:
1310                 val, ok = p.parseRuleRefExpr(expr)
1311         case *seqExpr:
1312                 val, ok = p.parseSeqExpr(expr)
1313         case *zeroOrMoreExpr:
1314                 val, ok = p.parseZeroOrMoreExpr(expr)
1315         case *zeroOrOneExpr:
1316                 val, ok = p.parseZeroOrOneExpr(expr)
1317         default:
1318                 panic(fmt.Sprintf("unknown expression type %T", expr))
1319         }
1320         if p.memoize {
1321                 p.setMemoized(pt, expr, resultTuple{val, ok, p.pt})
1322         }
1323         return val, ok
1324 }
1325
1326 func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) {
1327         if p.debug {
1328                 defer p.out(p.in("parseActionExpr"))
1329         }
1330
1331         start := p.pt
1332         val, ok := p.parseExpr(act.expr)
1333         if ok {
1334                 p.cur.pos = start.position
1335                 p.cur.text = p.sliceFrom(start)
1336                 actVal, err := act.run(p)
1337                 if err != nil {
1338                         p.addErrAt(err, start.position)
1339                 }
1340                 val = actVal
1341         }
1342         if ok && p.debug {
1343                 p.print(strings.Repeat(" ", p.depth) + "MATCH", string(p.sliceFrom(start)))
1344         }
1345         return val, ok
1346 }
1347
1348 func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) {
1349         if p.debug {
1350                 defer p.out(p.in("parseAndCodeExpr"))
1351         }
1352
1353         ok, err := and.run(p)
1354         if err != nil {
1355                 p.addErr(err)
1356         }
1357         return nil, ok
1358 }
1359
1360 func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) {
1361         if p.debug {
1362                 defer p.out(p.in("parseAndExpr"))
1363         }
1364
1365         pt := p.pt
1366         p.pushV()
1367         _, ok := p.parseExpr(and.expr)
1368         p.popV()
1369         p.restore(pt)
1370         return nil, ok
1371 }
1372
1373 func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) {
1374         if p.debug {
1375                 defer p.out(p.in("parseAnyMatcher"))
1376         }
1377
1378         if p.pt.rn != utf8.RuneError {
1379                 start := p.pt
1380                 p.read()
1381                 return p.sliceFrom(start), true
1382         }
1383         return nil, false
1384 }
1385
1386 func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) {
1387         if p.debug {
1388                 defer p.out(p.in("parseCharClassMatcher"))
1389         }
1390
1391         cur := p.pt.rn
1392         // can't match EOF
1393         if cur == utf8.RuneError {
1394                 return nil, false
1395         }
1396         start := p.pt
1397         if chr.ignoreCase {
1398                 cur = unicode.ToLower(cur)
1399         }
1400
1401         // try to match in the list of available chars
1402         for _, rn := range chr.chars {
1403                 if rn == cur {
1404                         if chr.inverted {
1405                                 return nil, false
1406                         }
1407                         p.read()
1408                         return p.sliceFrom(start), true
1409                 }
1410         }
1411
1412         // try to match in the list of ranges
1413         for i := 0; i < len(chr.ranges); i += 2 {
1414                 if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] {
1415                         if chr.inverted {
1416                                 return nil, false
1417                         }
1418                         p.read()
1419                         return p.sliceFrom(start), true
1420                 }
1421         }
1422
1423         // try to match in the list of Unicode classes
1424         for _, cl := range chr.classes {
1425                 if unicode.Is(cl, cur) {
1426                         if chr.inverted {
1427                                 return nil, false
1428                         }
1429                         p.read()
1430                         return p.sliceFrom(start), true
1431                 }
1432         }
1433
1434         if chr.inverted {
1435                 p.read()
1436                 return p.sliceFrom(start), true
1437         }
1438         return nil, false
1439 }
1440
1441 func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) {
1442         if p.debug {
1443                 defer p.out(p.in("parseChoiceExpr"))
1444         }
1445
1446         for _, alt := range ch.alternatives {
1447                 p.pushV()
1448                 val, ok := p.parseExpr(alt)
1449                 p.popV()
1450                 if ok {
1451                         return val, ok
1452                 }
1453         }
1454         return nil, false
1455 }
1456
1457 func (p *parser) parseLabeledExpr(lab *labeledExpr) (interface{}, bool) {
1458         if p.debug {
1459                 defer p.out(p.in("parseLabeledExpr"))
1460         }
1461
1462         p.pushV()
1463         val, ok := p.parseExpr(lab.expr)
1464         p.popV()
1465         if ok && lab.label != "" {
1466                 m := p.vstack[len(p.vstack)-1]
1467                 m[lab.label] = val
1468         }
1469         return val, ok
1470 }
1471
1472 func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) {
1473         if p.debug {
1474                 defer p.out(p.in("parseLitMatcher"))
1475         }
1476
1477         start := p.pt
1478         for _, want := range lit.val {
1479                 cur := p.pt.rn
1480                 if lit.ignoreCase {
1481                         cur = unicode.ToLower(cur)
1482                 }
1483                 if cur != want {
1484                         p.restore(start)
1485                         return nil, false
1486                 }
1487                 p.read()
1488         }
1489         return p.sliceFrom(start), true
1490 }
1491
1492 func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) {
1493         if p.debug {
1494                 defer p.out(p.in("parseNotCodeExpr"))
1495         }
1496
1497         ok, err := not.run(p)
1498         if err != nil {
1499                 p.addErr(err)
1500         }
1501         return nil, !ok
1502 }
1503
1504 func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) {
1505         if p.debug {
1506                 defer p.out(p.in("parseNotExpr"))
1507         }
1508
1509         pt := p.pt
1510         p.pushV()
1511         _, ok := p.parseExpr(not.expr)
1512         p.popV()
1513         p.restore(pt)
1514         return nil, !ok
1515 }
1516
1517 func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) {
1518         if p.debug {
1519                 defer p.out(p.in("parseOneOrMoreExpr"))
1520         }
1521
1522         var vals []interface{}
1523
1524         for {
1525                 p.pushV()
1526                 val, ok := p.parseExpr(expr.expr)
1527                 p.popV()
1528                 if !ok {
1529                         if len(vals) == 0 {
1530                                 // did not match once, no match
1531                                 return nil, false
1532                         }
1533                         return vals, true
1534                 }
1535                 vals = append(vals, val)
1536         }
1537 }
1538
1539 func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) {
1540         if p.debug {
1541                 defer p.out(p.in("parseRuleRefExpr " + ref.name))
1542         }
1543
1544         if ref.name == "" {
1545                 panic(fmt.Sprintf("%s: invalid rule: missing name", ref.pos))
1546         }
1547
1548         rule := p.rules[ref.name]
1549         if rule == nil {
1550                 p.addErr(fmt.Errorf("undefined rule: %s", ref.name))
1551                 return nil, false
1552         }
1553         return p.parseRule(rule)
1554 }
1555
1556 func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) {
1557         if p.debug {
1558                 defer p.out(p.in("parseSeqExpr"))
1559         }
1560
1561         var vals []interface{}
1562
1563         pt := p.pt
1564         for _, expr := range seq.exprs {
1565                 val, ok := p.parseExpr(expr)
1566                 if !ok {
1567                         p.restore(pt)
1568                         return nil, false
1569                 }
1570                 vals = append(vals, val)
1571         }
1572         return vals, true
1573 }
1574
1575 func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) {
1576         if p.debug {
1577                 defer p.out(p.in("parseZeroOrMoreExpr"))
1578         }
1579
1580         var vals []interface{}
1581
1582         for {
1583                 p.pushV()
1584                 val, ok := p.parseExpr(expr.expr)
1585                 p.popV()
1586                 if !ok {
1587                         return vals, true
1588                 }
1589                 vals = append(vals, val)
1590         }
1591 }
1592
1593 func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) {
1594         if p.debug {
1595                 defer p.out(p.in("parseZeroOrOneExpr"))
1596         }
1597
1598         p.pushV()
1599         val, _ := p.parseExpr(expr.expr)
1600         p.popV()
1601         // whether it matched or not, consider it a match
1602         return val, true
1603 }
1604
1605 func rangeTable(class string) *unicode.RangeTable {
1606         if rt, ok := unicode.Categories[class]; ok {
1607                 return rt
1608         }
1609         if rt, ok := unicode.Properties[class]; ok {
1610                 return rt
1611         }
1612         if rt, ok := unicode.Scripts[class]; ok {
1613                 return rt
1614         }
1615
1616         // cannot happen
1617         panic(fmt.Sprintf("invalid Unicode class: %s", class))
1618 }
1619