22 pos: position{line: 19, col: 1, offset: 148},
24 pos: position{line: 19, col: 9, offset: 158},
25 run: (*parser).callonStart1,
27 pos: position{line: 19, col: 9, offset: 158},
30 pos: position{line: 19, col: 9, offset: 158},
33 pos: position{line: 19, col: 16, offset: 165},
35 pos: position{line: 19, col: 16, offset: 165},
41 pos: position{line: 19, col: 22, offset: 171},
45 pos: position{line: 19, col: 24, offset: 173},
54 pos: position{line: 27, col: 1, offset: 307},
56 pos: position{line: 27, col: 8, offset: 316},
57 run: (*parser).callonItem1,
59 pos: position{line: 27, col: 8, offset: 316},
62 pos: position{line: 27, col: 8, offset: 316},
66 pos: position{line: 27, col: 10, offset: 318},
69 pos: position{line: 27, col: 14, offset: 322},
70 alternatives: []interface{}{
72 pos: position{line: 27, col: 14, offset: 322},
76 pos: position{line: 27, col: 22, offset: 330},
80 pos: position{line: 27, col: 30, offset: 338},
84 pos: position{line: 27, col: 36, offset: 344},
88 pos: position{line: 27, col: 51, offset: 359},
89 name: "UntypedNumeric",
92 pos: position{line: 27, col: 68, offset: 376},
96 pos: position{line: 27, col: 82, offset: 390},
108 pos: position{line: 31, col: 1, offset: 422},
110 pos: position{line: 31, col: 9, offset: 432},
111 run: (*parser).callonArray1,
113 pos: position{line: 31, col: 9, offset: 432},
114 exprs: []interface{}{
116 pos: position{line: 31, col: 9, offset: 432},
121 pos: position{line: 31, col: 13, offset: 436},
123 expr: &zeroOrMoreExpr{
124 pos: position{line: 31, col: 19, offset: 442},
126 pos: position{line: 31, col: 19, offset: 442},
132 pos: position{line: 31, col: 25, offset: 448},
136 pos: position{line: 31, col: 27, offset: 450},
146 pos: position{line: 35, col: 1, offset: 504},
148 pos: position{line: 35, col: 9, offset: 514},
149 run: (*parser).callonTuple1,
151 pos: position{line: 35, col: 9, offset: 514},
152 exprs: []interface{}{
154 pos: position{line: 35, col: 9, offset: 514},
159 pos: position{line: 35, col: 13, offset: 518},
161 expr: &oneOrMoreExpr{
162 pos: position{line: 35, col: 19, offset: 524},
164 pos: position{line: 35, col: 19, offset: 524},
170 pos: position{line: 35, col: 25, offset: 530},
174 pos: position{line: 35, col: 27, offset: 532},
183 name: "UntypedNumeric",
184 pos: position{line: 39, col: 1, offset: 586},
186 pos: position{line: 39, col: 18, offset: 605},
187 run: (*parser).callonUntypedNumeric1,
189 pos: position{line: 39, col: 18, offset: 605},
192 pos: position{line: 39, col: 25, offset: 612},
199 name: "TypedNumeric",
200 pos: position{line: 46, col: 1, offset: 704},
202 pos: position{line: 46, col: 16, offset: 721},
203 run: (*parser).callonTypedNumeric1,
205 pos: position{line: 46, col: 16, offset: 721},
206 exprs: []interface{}{
208 pos: position{line: 46, col: 16, offset: 721},
211 pos: position{line: 46, col: 18, offset: 723},
216 pos: position{line: 46, col: 23, offset: 728},
221 pos: position{line: 46, col: 27, offset: 732},
224 pos: position{line: 46, col: 34, offset: 739},
234 pos: position{line: 53, col: 1, offset: 838},
236 pos: position{line: 53, col: 7, offset: 846},
237 alternatives: []interface{}{
239 pos: position{line: 53, col: 7, offset: 846},
240 name: "HexLengthPrefixed",
243 pos: position{line: 53, col: 27, offset: 866},
250 name: "HexLengthPrefixed",
251 pos: position{line: 55, col: 1, offset: 874},
253 pos: position{line: 55, col: 21, offset: 896},
254 run: (*parser).callonHexLengthPrefixed1,
256 pos: position{line: 55, col: 21, offset: 896},
257 exprs: []interface{}{
259 pos: position{line: 55, col: 21, offset: 896},
264 pos: position{line: 55, col: 26, offset: 901},
267 pos: position{line: 55, col: 35, offset: 910},
277 pos: position{line: 59, col: 1, offset: 974},
279 pos: position{line: 59, col: 10, offset: 985},
280 run: (*parser).callonHexRaw1,
282 pos: position{line: 59, col: 10, offset: 985},
283 exprs: []interface{}{
285 pos: position{line: 59, col: 10, offset: 985},
290 pos: position{line: 59, col: 14, offset: 989},
293 pos: position{line: 59, col: 23, offset: 998},
303 pos: position{line: 63, col: 1, offset: 1063},
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',},
322 pos: position{line: 71, col: 1, offset: 1223},
324 pos: position{line: 71, col: 8, offset: 1232},
325 run: (*parser).callonType1,
327 pos: position{line: 71, col: 9, offset: 1233},
328 alternatives: []interface{}{
330 pos: position{line: 71, col: 9, offset: 1233},
335 pos: position{line: 71, col: 17, offset: 1241},
345 pos: position{line: 75, col: 1, offset: 1284},
347 pos: position{line: 75, col: 11, offset: 1296},
348 run: (*parser).callonInteger1,
350 pos: position{line: 75, col: 11, offset: 1296},
351 exprs: []interface{}{
353 pos: position{line: 75, col: 11, offset: 1296},
355 pos: position{line: 75, col: 11, offset: 1296},
361 pos: position{line: 75, col: 16, offset: 1301},
362 expr: &charClassMatcher{
363 pos: position{line: 75, col: 16, offset: 1301},
365 ranges: []rune{'0','9',},
376 pos: position{line: 79, col: 1, offset: 1344},
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},
386 ranges: []rune{'0','9','a','z','A','Z',},
395 pos: position{line: 83, col: 1, offset: 1404},
397 pos: position{line: 83, col: 15, offset: 1420},
398 run: (*parser).callonPlaceholder1,
400 pos: position{line: 83, col: 15, offset: 1420},
401 exprs: []interface{}{
403 pos: position{line: 83, col: 15, offset: 1420},
408 pos: position{line: 83, col: 19, offset: 1424},
411 pos: position{line: 83, col: 25, offset: 1430},
416 pos: position{line: 83, col: 31, offset: 1436},
426 pos: position{line: 89, col: 1, offset: 1509},
428 pos: position{line: 89, col: 10, offset: 1520},
429 run: (*parser).callonString1,
431 pos: position{line: 89, col: 10, offset: 1520},
432 exprs: []interface{}{
434 pos: position{line: 89, col: 10, offset: 1520},
439 pos: position{line: 89, col: 14, offset: 1524},
441 pos: position{line: 89, col: 16, offset: 1526},
442 alternatives: []interface{}{
444 pos: position{line: 89, col: 16, offset: 1526},
445 exprs: []interface{}{
447 pos: position{line: 89, col: 16, offset: 1526},
449 pos: position{line: 89, col: 17, offset: 1527},
454 line: 89, col: 29, offset: 1539,
459 pos: position{line: 89, col: 33, offset: 1543},
460 exprs: []interface{}{
462 pos: position{line: 89, col: 33, offset: 1543},
467 pos: position{line: 89, col: 38, offset: 1548},
468 name: "EscapeSequence",
476 pos: position{line: 89, col: 56, offset: 1566},
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',},
497 name: "EscapeSequence",
498 pos: position{line: 102, col: 1, offset: 1871},
500 pos: position{line: 102, col: 18, offset: 1890},
501 alternatives: []interface{}{
503 pos: position{line: 102, col: 18, offset: 1890},
504 name: "SingleCharEscape",
507 pos: position{line: 102, col: 37, offset: 1909},
508 name: "UnicodeEscape",
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',},
525 name: "UnicodeEscape",
526 pos: position{line: 106, col: 1, offset: 1958},
528 pos: position{line: 106, col: 17, offset: 1976},
529 exprs: []interface{}{
531 pos: position{line: 106, col: 17, offset: 1976},
536 pos: position{line: 106, col: 21, offset: 1980},
540 pos: position{line: 106, col: 30, offset: 1989},
544 pos: position{line: 106, col: 39, offset: 1998},
548 pos: position{line: 106, col: 48, offset: 2007},
556 pos: position{line: 108, col: 1, offset: 2017},
557 expr: &charClassMatcher{
558 pos: position{line: 108, col: 12, offset: 2030},
560 ranges: []rune{'0','9','a','f',},
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},
574 chars: []rune{' ','\n','\t','\r',},
582 pos: position{line: 112, col: 1, offset: 2072},
584 pos: position{line: 112, col: 7, offset: 2080},
586 line: 112, col: 8, offset: 2081,
592 func (c *current) onStart1(items_ interface{}) (interface{}, error) {
593 items := items_.([]interface{})
597 return Tuple(items), nil
600 func (p *parser) callonStart1() (interface{}, error) {
601 stack := p.vstack[len(p.vstack)-1]
603 return p.cur.onStart1(stack["items_"])
606 func (c *current) onItem1(it interface{}) (interface{}, error) {
610 func (p *parser) callonItem1() (interface{}, error) {
611 stack := p.vstack[len(p.vstack)-1]
613 return p.cur.onItem1(stack["it"])
616 func (c *current) onArray1(items interface{}) (interface{}, error) {
617 return Array(items.([]interface{})), nil
620 func (p *parser) callonArray1() (interface{}, error) {
621 stack := p.vstack[len(p.vstack)-1]
623 return p.cur.onArray1(stack["items"])
626 func (c *current) onTuple1(items interface{}) (interface{}, error) {
627 return Tuple(items.([]interface{})), nil
630 func (p *parser) callonTuple1() (interface{}, error) {
631 stack := p.vstack[len(p.vstack)-1]
633 return p.cur.onTuple1(stack["items"])
636 func (c *current) onUntypedNumeric1(number interface{}) (interface{}, error) {
639 Number: number.(string),
643 func (p *parser) callonUntypedNumeric1() (interface{}, error) {
644 stack := p.vstack[len(p.vstack)-1]
646 return p.cur.onUntypedNumeric1(stack["number"])
649 func (c *current) onTypedNumeric1(t, number interface{}) (interface{}, error) {
652 Number: number.(string),
656 func (p *parser) callonTypedNumeric1() (interface{}, error) {
657 stack := p.vstack[len(p.vstack)-1]
659 return p.cur.onTypedNumeric1(stack["t"], stack["number"])
662 func (c *current) onHexLengthPrefixed1(hexbytes interface{}) (interface{}, error) {
663 return NewBytes(hexbytes.([]byte), true), nil
666 func (p *parser) callonHexLengthPrefixed1() (interface{}, error) {
667 stack := p.vstack[len(p.vstack)-1]
669 return p.cur.onHexLengthPrefixed1(stack["hexbytes"])
672 func (c *current) onHexRaw1(hexbytes interface{}) (interface{}, error) {
673 return NewBytes(hexbytes.([]byte), false), nil
676 func (p *parser) callonHexRaw1() (interface{}, error) {
677 stack := p.vstack[len(p.vstack)-1]
679 return p.cur.onHexRaw1(stack["hexbytes"])
682 func (c *current) onHexBytes1() (interface{}, error) {
683 bytez, err := hex.DecodeString(string(c.text))
690 func (p *parser) callonHexBytes1() (interface{}, error) {
691 stack := p.vstack[len(p.vstack)-1]
693 return p.cur.onHexBytes1()
696 func (c *current) onType1() (interface{}, error) {
697 return string(c.text), nil
700 func (p *parser) callonType1() (interface{}, error) {
701 stack := p.vstack[len(p.vstack)-1]
703 return p.cur.onType1()
706 func (c *current) onInteger1() (interface{}, error) {
707 return string(c.text), nil
710 func (p *parser) callonInteger1() (interface{}, error) {
711 stack := p.vstack[len(p.vstack)-1]
713 return p.cur.onInteger1()
716 func (c *current) onLabel1() (interface{}, error) {
717 return string(c.text), nil
720 func (p *parser) callonLabel1() (interface{}, error) {
721 stack := p.vstack[len(p.vstack)-1]
723 return p.cur.onLabel1()
726 func (c *current) onPlaceholder1(label interface{}) (interface{}, error) {
728 Label: label.(string),
732 func (p *parser) callonPlaceholder1() (interface{}, error) {
733 stack := p.vstack[len(p.vstack)-1]
735 return p.cur.onPlaceholder1(stack["label"])
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))
745 return NewString(text), nil
749 func (p *parser) callonString1() (interface{}, error) {
750 stack := p.vstack[len(p.vstack)-1]
752 return p.cur.onString1()
757 // errNoRule is returned when the grammar to parse has no rule.
758 errNoRule = errors.New("grammar has no rule")
760 // errInvalidEncoding is returned when the source is not properly
762 errInvalidEncoding = errors.New("invalid encoding")
764 // errNoMatch is returned if no match could be found.
765 errNoMatch = errors.New("no match found")
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
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.
775 // The default is false.
776 func Debug(b bool) Option {
777 return func(p *parser) Option {
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.
789 // The default is false.
790 func Memoize(b bool) Option {
791 return func(p *parser) Option {
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.
803 // The default is true.
804 func Recover(b bool) Option {
805 return func(p *parser) Option {
812 // ParseFile parses the file identified by filename.
813 func ParseFile(filename string, opts ...Option) (interface{}, error) {
814 f, err := os.Open(filename)
819 return ParseReader(filename, f, opts...)
822 // ParseReader parses the data from r using filename as information in the
824 func ParseReader(filename string, r io.Reader, opts ...Option) (interface{}, error) {
825 b, err := ioutil.ReadAll(r)
830 return Parse(filename, b, opts...)
833 // Parse parses the data from b using filename as information in the
835 func Parse(filename string, b []byte, opts ...Option) (interface{}, error) {
836 return newParser(filename, b, opts...).parse(g)
839 // position records a position in the text.
840 type position struct {
841 line, col, offset int
844 func (p position) String() string {
845 return fmt.Sprintf("%d:%d [%d]", p.line, p.col, p.offset)
848 // savepoint stores all state required to go back to this point in the
850 type savepoint struct {
856 type current struct {
857 pos position // start position of the match
858 text []byte // raw text of the match
863 type grammar struct {
875 type choiceExpr struct {
877 alternatives []interface{}
880 type actionExpr struct {
883 run func(*parser) (interface{}, error)
886 type seqExpr struct {
891 type labeledExpr struct {
904 type zeroOrOneExpr expr
905 type zeroOrMoreExpr expr
906 type oneOrMoreExpr expr
908 type ruleRefExpr struct {
913 type andCodeExpr struct {
915 run func(*parser) (bool, error)
918 type notCodeExpr struct {
920 run func(*parser) (bool, error)
923 type litMatcher struct {
929 type charClassMatcher struct {
934 classes []*unicode.RangeTable
939 type anyMatcher position
941 // errList cumulates the errors found by the parser.
944 func (e *errList) add(err error) {
948 func (e errList) err() error {
956 func (e *errList) dedupe() {
958 set := make(map[string]bool)
959 for _, err := range *e {
960 if msg := err.Error(); !set[msg] {
962 cleaned = append(cleaned, err)
968 func (e errList) Error() string {
977 for i, err := range e {
981 buf.WriteString(err.Error())
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 {
995 // Error returns the error message.
996 func (p *parserError) Error() string {
997 return p.prefix + ": " + p.Inner.Error()
1000 // newParser creates a parser with the specified input source and options.
1001 func newParser(filename string, b []byte, opts ...Option) *parser {
1006 pt: savepoint{position: position{line: 1}},
1013 // setOptions applies the options to the parser.
1014 func (p *parser) setOptions(opts []Option) {
1015 for _, opt := range opts {
1020 type resultTuple struct {
1026 type parser struct {
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
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
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)
1061 p.vstack = p.vstack[:len(p.vstack)+1]
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
1071 m = make(map[string]interface{})
1072 p.vstack[len(p.vstack)-1] = m
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]
1081 p.vstack[len(p.vstack)-1] = nil
1083 p.vstack = p.vstack[:len(p.vstack)-1]
1086 func (p *parser) print(prefix, s string) string {
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)
1096 func (p *parser) in(s string) string {
1098 return p.print(strings.Repeat(" ", p.depth) + ">", s)
1101 func (p *parser) out(s string) string {
1103 return p.print(strings.Repeat(" ", p.depth) + "<", s)
1106 func (p *parser) addErr(err error) {
1107 p.addErrAt(err, p.pt.position)
1110 func (p *parser) addErrAt(err error, pos position) {
1111 var buf bytes.Buffer
1112 if p.filename != "" {
1113 buf.WriteString(p.filename)
1116 buf.WriteString(":")
1118 buf.WriteString(fmt.Sprintf("%d:%d (%d)", pos.line, pos.col, pos.offset))
1119 if len(p.rstack) > 0 {
1121 buf.WriteString(": ")
1123 rule := p.rstack[len(p.rstack)-1]
1124 if rule.displayName != "" {
1125 buf.WriteString("rule " + rule.displayName)
1127 buf.WriteString("rule " + rule.name)
1130 pe := &parserError{Inner: err, prefix: buf.String()}
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:])
1146 if rn == utf8.RuneError {
1148 p.addErr(errInvalidEncoding)
1153 // restore parser position to the savepoint pt.
1154 func (p *parser) restore(pt savepoint) {
1156 defer p.out(p.in("restore"))
1158 if pt.offset == p.pt.offset {
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]
1169 func (p *parser) getMemoized(node interface{}) (resultTuple, bool) {
1170 if len(p.memo) == 0 {
1171 return resultTuple{}, false
1173 m := p.memo[p.pt.offset]
1175 return resultTuple{}, false
1181 func (p *parser) setMemoized(pt savepoint, node interface{}, tuple resultTuple) {
1183 p.memo = make(map[int]map[interface{}]resultTuple)
1185 m := p.memo[pt.offset]
1187 m = make(map[interface{}]resultTuple)
1188 p.memo[pt.offset] = m
1193 func (p *parser) buildRulesTable(g *grammar) {
1194 p.rules = make(map[string]*rule, len(g.rules))
1195 for _, r := range g.rules {
1200 func (p *parser) parse(g *grammar) (val interface{}, err error) {
1201 if len(g.rules) == 0 {
1203 return nil, p.errs.err()
1206 // TODO : not super critical but this could be generated
1207 p.buildRulesTable(g)
1210 // panic can be used in action code to stop parsing immediately
1211 // and return the panic as an error.
1213 if e := recover(); e != nil {
1215 defer p.out(p.in("panic handler"))
1218 switch e := e.(type) {
1222 p.addErr(fmt.Errorf("%v", e))
1229 // start rule is rule [0]
1230 p.read() // advance to first rune
1231 val, ok := p.parseRule(g.rules[0])
1233 if len(*p.errs) == 0 {
1234 // make sure this doesn't go out silently
1235 p.addErr(errNoMatch)
1237 return nil, p.errs.err()
1239 return val, p.errs.err()
1242 func (p *parser) parseRule(rule *rule) (interface{}, bool) {
1244 defer p.out(p.in("parseRule " + rule.name))
1248 res, ok := p.getMemoized(rule)
1256 p.rstack = append(p.rstack, rule)
1258 val, ok := p.parseExpr(rule.expr)
1260 p.rstack = p.rstack[:len(p.rstack)-1]
1262 p.print(strings.Repeat(" ", p.depth) + "MATCH", string(p.sliceFrom(start)))
1266 p.setMemoized(start, rule, resultTuple{val, ok, p.pt})
1271 func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {
1276 res, ok := p.getMemoized(expr)
1286 switch expr := expr.(type) {
1288 val, ok = p.parseActionExpr(expr)
1290 val, ok = p.parseAndCodeExpr(expr)
1292 val, ok = p.parseAndExpr(expr)
1294 val, ok = p.parseAnyMatcher(expr)
1295 case *charClassMatcher:
1296 val, ok = p.parseCharClassMatcher(expr)
1298 val, ok = p.parseChoiceExpr(expr)
1300 val, ok = p.parseLabeledExpr(expr)
1302 val, ok = p.parseLitMatcher(expr)
1304 val, ok = p.parseNotCodeExpr(expr)
1306 val, ok = p.parseNotExpr(expr)
1307 case *oneOrMoreExpr:
1308 val, ok = p.parseOneOrMoreExpr(expr)
1310 val, ok = p.parseRuleRefExpr(expr)
1312 val, ok = p.parseSeqExpr(expr)
1313 case *zeroOrMoreExpr:
1314 val, ok = p.parseZeroOrMoreExpr(expr)
1315 case *zeroOrOneExpr:
1316 val, ok = p.parseZeroOrOneExpr(expr)
1318 panic(fmt.Sprintf("unknown expression type %T", expr))
1321 p.setMemoized(pt, expr, resultTuple{val, ok, p.pt})
1326 func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) {
1328 defer p.out(p.in("parseActionExpr"))
1332 val, ok := p.parseExpr(act.expr)
1334 p.cur.pos = start.position
1335 p.cur.text = p.sliceFrom(start)
1336 actVal, err := act.run(p)
1338 p.addErrAt(err, start.position)
1343 p.print(strings.Repeat(" ", p.depth) + "MATCH", string(p.sliceFrom(start)))
1348 func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) {
1350 defer p.out(p.in("parseAndCodeExpr"))
1353 ok, err := and.run(p)
1360 func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) {
1362 defer p.out(p.in("parseAndExpr"))
1367 _, ok := p.parseExpr(and.expr)
1373 func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) {
1375 defer p.out(p.in("parseAnyMatcher"))
1378 if p.pt.rn != utf8.RuneError {
1381 return p.sliceFrom(start), true
1386 func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) {
1388 defer p.out(p.in("parseCharClassMatcher"))
1393 if cur == utf8.RuneError {
1398 cur = unicode.ToLower(cur)
1401 // try to match in the list of available chars
1402 for _, rn := range chr.chars {
1408 return p.sliceFrom(start), true
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] {
1419 return p.sliceFrom(start), true
1423 // try to match in the list of Unicode classes
1424 for _, cl := range chr.classes {
1425 if unicode.Is(cl, cur) {
1430 return p.sliceFrom(start), true
1436 return p.sliceFrom(start), true
1441 func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) {
1443 defer p.out(p.in("parseChoiceExpr"))
1446 for _, alt := range ch.alternatives {
1448 val, ok := p.parseExpr(alt)
1457 func (p *parser) parseLabeledExpr(lab *labeledExpr) (interface{}, bool) {
1459 defer p.out(p.in("parseLabeledExpr"))
1463 val, ok := p.parseExpr(lab.expr)
1465 if ok && lab.label != "" {
1466 m := p.vstack[len(p.vstack)-1]
1472 func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) {
1474 defer p.out(p.in("parseLitMatcher"))
1478 for _, want := range lit.val {
1481 cur = unicode.ToLower(cur)
1489 return p.sliceFrom(start), true
1492 func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) {
1494 defer p.out(p.in("parseNotCodeExpr"))
1497 ok, err := not.run(p)
1504 func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) {
1506 defer p.out(p.in("parseNotExpr"))
1511 _, ok := p.parseExpr(not.expr)
1517 func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) {
1519 defer p.out(p.in("parseOneOrMoreExpr"))
1522 var vals []interface{}
1526 val, ok := p.parseExpr(expr.expr)
1530 // did not match once, no match
1535 vals = append(vals, val)
1539 func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) {
1541 defer p.out(p.in("parseRuleRefExpr " + ref.name))
1545 panic(fmt.Sprintf("%s: invalid rule: missing name", ref.pos))
1548 rule := p.rules[ref.name]
1550 p.addErr(fmt.Errorf("undefined rule: %s", ref.name))
1553 return p.parseRule(rule)
1556 func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) {
1558 defer p.out(p.in("parseSeqExpr"))
1561 var vals []interface{}
1564 for _, expr := range seq.exprs {
1565 val, ok := p.parseExpr(expr)
1570 vals = append(vals, val)
1575 func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) {
1577 defer p.out(p.in("parseZeroOrMoreExpr"))
1580 var vals []interface{}
1584 val, ok := p.parseExpr(expr.expr)
1589 vals = append(vals, val)
1593 func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) {
1595 defer p.out(p.in("parseZeroOrOneExpr"))
1599 val, _ := p.parseExpr(expr.expr)
1601 // whether it matched or not, consider it a match
1605 func rangeTable(class string) *unicode.RangeTable {
1606 if rt, ok := unicode.Categories[class]; ok {
1609 if rt, ok := unicode.Properties[class]; ok {
1612 if rt, ok := unicode.Scripts[class]; ok {
1617 panic(fmt.Sprintf("invalid Unicode class: %s", class))