// Code generated by 'egg -o ./internal/parser/parser.go -package parser -start Config config.ebnf', DO NOT EDIT. // Parser generated from config.ebnf. package parser import ( "errors" "fmt" "go/token" "strconv" "unicode" "unicode/utf8" "modernc.org/scanner" ) var _ = unicode.MaxRune // Symbols const ( TOK_EOF = Symbol(0) // EOF TOK_003d = Symbol(1) // '=' boolean = Symbol(2) // boolean br = Symbol(3) // br lbrace = Symbol(4) // lbrace number = Symbol(5) // number rbrace = Symbol(6) // rbrace str = Symbol(7) // str white_space = Symbol(8) // white_space word = Symbol(9) // word Config = Symbol(10) // Config Doc = Symbol(11) // Doc Stmt = Symbol(12) // Stmt Assignment = Symbol(13) // Assignment Command = Symbol(14) // Command Values = Symbol(15) // Values Value = Symbol(16) // Value Body = Symbol(17) // Body Word = Symbol(18) // Word Number = Symbol(19) // Number Boolean = Symbol(20) // Boolean String = Symbol(21) // String ) const SymbolNames = "EOF'='booleanbrlbracenumberrbracestrwhite_spacewordConfigDocStmtAssignmentCommandValuesValueBodyWordNumberBooleanString" var SymbolIndex = [...]uint8{0, 3, 6, 13, 15, 21, 27, 33, 36, 47, 51, 57, 60, 64, 74, 81, 87, 92, 96, 100, 106, 113, 119} func (s Symbol) String() string { idx := int(s) - 0 if s < 0 || idx >= len(SymbolIndex)-1 { return "Symbol(" + strconv.FormatInt(int64(s), 10) + ")" } return SymbolNames[SymbolIndex[idx]:SymbolIndex[idx+1]] } var errorSets = [...][]Symbol{ {String, Boolean, Number, Word, Body, Value, Values, word, str, number, lbrace, br, boolean, TOK_003d}, {TOK_003d}, {String, Boolean, Number, Word, Value, word, str, number, lbrace, br, boolean}, {String, Boolean, Number, Word, Value, word, str, number, boolean}, {String, Boolean, Number, Word, word, str, number, boolean}, {word, str, number, boolean}, {boolean}, {lbrace, br}, {br}, {lbrace}, {number}, {Word, Stmt, word, rbrace}, {rbrace}, {str}, {Word, Stmt, word}, {Word, word}, {word}, } type Parser struct { cache [][]int32 eof bool errBudget int id rune // from scanSep, valid if .n != 0 n int // from scanSep, valid if != 0 off int sc *scanner.RecScanner src []byte tok scanner.Token // current lookahead tokIndex int32 // For scanner.Token(tokIndex) } type Symbol int32 // scan recognizes longest UTF-8 lexemes. Lower IDs take precedence on same length. // // id 0: $ // id 1: = // id 2: (true|false) // id 3: (;) // id 4: (\{) // id 5: (-?[0-9]+(\.[0-9]+)?) // id 6: (\}) // id 7: (("[^"]*")|('[^']*')|(`)(([^\x60]))*(`)) // id 8: ( |\t|\r|\n|#.*) // id 9: (((([a-zA-Z]))|((\$|_|-))))(((([a-zA-Z]))|((-?[0-9]+(\.[0-9]+)?))|((\$|_|-))))* // // ID == -1 is returned when no lexeme was recognized. func (*Parser) scan(s []byte) (id, length int) { const endOfText = 0x110000 var pos, pos0, width, width1 int id = -1 var r, r1 rune _ = pos0 _ = r _ = r1 _ = width1 step := func(pos int) (r rune, n int) { if pos < len(s) { c := s[pos] if c < utf8.RuneSelf { return rune(c), 1 } return utf8.DecodeRune(s[pos:]) } return endOfText, 0 } move := func() { pos += width if r, width = r1, width1; r != endOfText { r1, width1 = step(pos + width) } } accept := func(x rune) bool { if r == x { move() return true } return false } _ = accept accept2 := func(x rune) bool { if r <= x { move() return true } return false } _ = accept2 r, r1 = endOfText, endOfText width, width1 = 0, 0 r, width = step(pos) if r != endOfText { r1, width1 = step(pos + width) } if accept('\t') { goto l41 } if accept('\n') { goto l43 } if accept('\r') { goto l45 } if accept(' ') { goto l47 } if accept('"') { goto l49 } if accept('#') { goto l61 } if accept('$') { goto l69 } if accept('\'') { goto l172 } if accept('-') { goto l184 } if accept(';') { goto l252 } if accept('=') { goto l254 } if accept('_') { goto l268 } if accept('`') { goto l280 } if accept('f') { goto l292 } if accept('t') { goto l360 } if accept('{') { goto l414 } if accept('}') { goto l416 } if r < '0' { goto l34out } if accept2('9') { goto l239 } l34out: if r < 'A' { goto l36out } if accept2('Z') { goto l256 } if r < 'a' { goto l36out } if accept2('e') { goto l256 } if r < 'g' { goto l36out } if accept2('s') { goto l256 } if r < 'u' { goto l36out } if accept2('z') { goto l256 } l36out: if r == endOfText { goto l418 } return id, length l41: id, length = 8, pos return id, length l43: id, length = 8, pos return id, length l45: id, length = 8, pos return id, length l47: id, length = 8, pos return id, length l49: if accept('"') { goto l54 } if accept2('!') { goto l56 } if r < '#' { goto l51out } if accept2('\U0010ffff') { goto l56 } l51out: return id, length l54: id, length = 7, pos return id, length l56: if accept('"') { goto l54 } if accept2('!') { goto l56 } if r < '#' { goto l58out } if accept2('\U0010ffff') { goto l56 } l58out: return id, length l61: id, length = 8, pos if accept2('\t') { goto l65 } if r < '\v' { goto l62out } if accept2('\U0010ffff') { goto l65 } l62out: return id, length l65: id, length = 8, pos if accept2('\t') { goto l65 } if r < '\v' { goto l66out } if accept2('\U0010ffff') { goto l65 } l66out: return id, length l69: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l76out } if accept2('9') { goto l105 } l76out: if r < 'A' { goto l78out } if accept2('Z') { goto l148 } if r < 'a' { goto l78out } if accept2('z') { goto l148 } l78out: return id, length l81: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l88out } if accept2('9') { goto l105 } l88out: if r < 'A' { goto l90out } if accept2('Z') { goto l148 } if r < 'a' { goto l90out } if accept2('z') { goto l148 } l90out: return id, length l93: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l100out } if accept2('9') { goto l105 } l100out: if r < 'A' { goto l102out } if accept2('Z') { goto l148 } if r < 'a' { goto l102out } if accept2('z') { goto l148 } l102out: return id, length l105: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('.') { goto l119 } if accept('_') { goto l160 } if r < '0' { goto l114out } if accept2('9') { goto l105 } l114out: if r < 'A' { goto l116out } if accept2('Z') { goto l148 } if r < 'a' { goto l116out } if accept2('z') { goto l148 } l116out: return id, length l119: if r < '0' { goto l119out } if accept2('9') { goto l122 } l119out: return id, length l122: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l129out } if accept2('9') { goto l134 } l129out: if r < 'A' { goto l131out } if accept2('Z') { goto l148 } if r < 'a' { goto l131out } if accept2('z') { goto l148 } l131out: return id, length l134: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('.') { goto l119 } if accept('_') { goto l160 } if r < '0' { goto l143out } if accept2('9') { goto l134 } l143out: if r < 'A' { goto l145out } if accept2('Z') { goto l148 } if r < 'a' { goto l145out } if accept2('z') { goto l148 } l145out: return id, length l148: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l155out } if accept2('9') { goto l105 } l155out: if r < 'A' { goto l157out } if accept2('Z') { goto l148 } if r < 'a' { goto l157out } if accept2('z') { goto l148 } l157out: return id, length l160: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l167out } if accept2('9') { goto l105 } l167out: if r < 'A' { goto l169out } if accept2('Z') { goto l148 } if r < 'a' { goto l169out } if accept2('z') { goto l148 } l169out: return id, length l172: if accept('\'') { goto l177 } if accept2('&') { goto l179 } if r < '(' { goto l174out } if accept2('\U0010ffff') { goto l179 } l174out: return id, length l177: id, length = 7, pos return id, length l179: if accept('\'') { goto l177 } if accept2('&') { goto l179 } if r < '(' { goto l181out } if accept2('\U0010ffff') { goto l179 } l181out: return id, length l184: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l191out } if accept2('9') { goto l196 } l191out: if r < 'A' { goto l193out } if accept2('Z') { goto l148 } if r < 'a' { goto l193out } if accept2('z') { goto l148 } l193out: return id, length l196: id, length = 5, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('.') { goto l210 } if accept('_') { goto l160 } if r < '0' { goto l205out } if accept2('9') { goto l196 } l205out: if r < 'A' { goto l207out } if accept2('Z') { goto l148 } if r < 'a' { goto l207out } if accept2('z') { goto l148 } l207out: return id, length l210: if r < '0' { goto l210out } if accept2('9') { goto l213 } l210out: return id, length l213: id, length = 5, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l220out } if accept2('9') { goto l225 } l220out: if r < 'A' { goto l222out } if accept2('Z') { goto l148 } if r < 'a' { goto l222out } if accept2('z') { goto l148 } l222out: return id, length l225: id, length = 5, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('.') { goto l119 } if accept('_') { goto l160 } if r < '0' { goto l234out } if accept2('9') { goto l225 } l234out: if r < 'A' { goto l236out } if accept2('Z') { goto l148 } if r < 'a' { goto l236out } if accept2('z') { goto l148 } l236out: return id, length l239: id, length = 5, pos if accept('.') { goto l245 } if r < '0' { goto l242out } if accept2('9') { goto l239 } l242out: return id, length l245: if r < '0' { goto l245out } if accept2('9') { goto l248 } l245out: return id, length l248: id, length = 5, pos if r < '0' { goto l249out } if accept2('9') { goto l248 } l249out: return id, length l252: id, length = 3, pos return id, length l254: id, length = 1, pos return id, length l256: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l263out } if accept2('9') { goto l105 } l263out: if r < 'A' { goto l265out } if accept2('Z') { goto l148 } if r < 'a' { goto l265out } if accept2('z') { goto l148 } l265out: return id, length l268: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l275out } if accept2('9') { goto l105 } l275out: if r < 'A' { goto l277out } if accept2('Z') { goto l148 } if r < 'a' { goto l277out } if accept2('z') { goto l148 } l277out: return id, length l280: if accept('`') { goto l285 } if accept2('_') { goto l287 } if r < 'a' { goto l282out } if accept2('\U0010ffff') { goto l287 } l282out: return id, length l285: id, length = 7, pos return id, length l287: if accept('`') { goto l285 } if accept2('_') { goto l287 } if r < 'a' { goto l289out } if accept2('\U0010ffff') { goto l287 } l289out: return id, length l292: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if accept('a') { goto l306 } if r < '0' { goto l301out } if accept2('9') { goto l105 } l301out: if r < 'A' { goto l303out } if accept2('Z') { goto l148 } if r < 'b' { goto l303out } if accept2('z') { goto l148 } l303out: return id, length l306: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if accept('l') { goto l320 } if r < '0' { goto l315out } if accept2('9') { goto l105 } l315out: if r < 'A' { goto l317out } if accept2('Z') { goto l148 } if r < 'a' { goto l317out } if accept2('k') { goto l148 } if r < 'm' { goto l317out } if accept2('z') { goto l148 } l317out: return id, length l320: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if accept('s') { goto l334 } if r < '0' { goto l329out } if accept2('9') { goto l105 } l329out: if r < 'A' { goto l331out } if accept2('Z') { goto l148 } if r < 'a' { goto l331out } if accept2('r') { goto l148 } if r < 't' { goto l331out } if accept2('z') { goto l148 } l331out: return id, length l334: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if accept('e') { goto l348 } if r < '0' { goto l343out } if accept2('9') { goto l105 } l343out: if r < 'A' { goto l345out } if accept2('Z') { goto l148 } if r < 'a' { goto l345out } if accept2('d') { goto l148 } if r < 'f' { goto l345out } if accept2('z') { goto l148 } l345out: return id, length l348: id, length = 2, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l355out } if accept2('9') { goto l105 } l355out: if r < 'A' { goto l357out } if accept2('Z') { goto l148 } if r < 'a' { goto l357out } if accept2('z') { goto l148 } l357out: return id, length l360: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if accept('r') { goto l374 } if r < '0' { goto l369out } if accept2('9') { goto l105 } l369out: if r < 'A' { goto l371out } if accept2('Z') { goto l148 } if r < 'a' { goto l371out } if accept2('q') { goto l148 } if r < 's' { goto l371out } if accept2('z') { goto l148 } l371out: return id, length l374: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if accept('u') { goto l388 } if r < '0' { goto l383out } if accept2('9') { goto l105 } l383out: if r < 'A' { goto l385out } if accept2('Z') { goto l148 } if r < 'a' { goto l385out } if accept2('t') { goto l148 } if r < 'v' { goto l385out } if accept2('z') { goto l148 } l385out: return id, length l388: id, length = 9, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if accept('e') { goto l402 } if r < '0' { goto l397out } if accept2('9') { goto l105 } l397out: if r < 'A' { goto l399out } if accept2('Z') { goto l148 } if r < 'a' { goto l399out } if accept2('d') { goto l148 } if r < 'f' { goto l399out } if accept2('z') { goto l148 } l399out: return id, length l402: id, length = 2, pos if accept('$') { goto l81 } if accept('-') { goto l93 } if accept('_') { goto l160 } if r < '0' { goto l409out } if accept2('9') { goto l105 } l409out: if r < 'A' { goto l411out } if accept2('Z') { goto l148 } if r < 'a' { goto l411out } if accept2('z') { goto l148 } l411out: return id, length l414: id, length = 4, pos return id, length l416: id, length = 6, pos return id, length l418: id, length = 0, pos return id, length } // Scan is used internally from Parse. func (p *Parser) Scan() (r scanner.Token) { return p.sc.Scan() } // init initalizes 'p' with content in 'src', assuming it comes from 'name'. // 'src' becomes "owned" by 'p'. init invalidates any pre-existing ASTs produced by 'p'. Mutating // 'src' invalidates the current AST returned from any parsing function called after init. func (p *Parser) init(name string, src []byte) (err error) { p.eof = false p.errBudget = 10 p.n = 0 p.off = 0 p.src = src p.tok = scanner.Token{} p.tokIndex = 0 p.sc = scanner.NewRecScanner(name, p.src, p.scan, int(white_space)) return nil } // Assignment grammar: // // # Statements // Assignment = "=" Values br . // // State 0 // on '=' // shift and goto state 1 // State 1 // on boolean, number, str, word, Value, Word, Number, Boolean, String // call Values and goto state 2 // State 2 // on br // shift and goto state 3 // State 3 // Accept // // Assignment is used internally from Parse. func (p *Parser) Assignment() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Assignment), 0) // state0: accept, errorSet = false, 1 switch Symbol(p.tok.Ch) { case TOK_003d: r = append(r, p.shift()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = false, 3 switch Symbol(p.tok.Ch) { case boolean, number, str, word, Value, Word, Number, Boolean, String: r = p.add(r, p.Values()) goto state2 } return p.stop(r, accept, errorSet) state2: accept, errorSet = false, 8 switch Symbol(p.tok.Ch) { case br: r = append(r, p.shift()) goto state3 } return p.stop(r, accept, errorSet) state3: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) } // Body grammar: // // Body = lbrace [ Doc ] rbrace . // // State 0 // on lbrace // shift and goto state 1 // State 1 // on rbrace // shift and goto state 2 // on word, Stmt, Word // call Doc and goto state 3 // State 2 // Accept // State 3 // on rbrace // shift and goto state 2 // // Body is used internally from Parse. func (p *Parser) Body() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Body), 0) // state0: accept, errorSet = false, 9 switch Symbol(p.tok.Ch) { case lbrace: r = append(r, p.shift()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = false, 11 switch Symbol(p.tok.Ch) { case rbrace: r = append(r, p.shift()) goto state2 case word, Stmt, Word: r = p.add(r, p.Doc()) goto state3 } return p.stop(r, accept, errorSet) state2: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) state3: accept, errorSet = false, 12 switch Symbol(p.tok.Ch) { case rbrace: r = append(r, p.shift()) goto state2 } return p.stop(r, accept, errorSet) } // Boolean grammar: // // Boolean = boolean . // // State 0 // on boolean // shift and goto state 1 // State 1 // Accept // // Boolean is used internally from Parse. func (p *Parser) Boolean() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Boolean), 0) // state0: accept, errorSet = false, 6 switch Symbol(p.tok.Ch) { case boolean: r = append(r, p.shift()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) } // Command grammar: // // Command = [Values] ( Body | br ) . // // State 0 // on br // shift and goto state 1 // on boolean, number, str, word, Value, Word, Number, Boolean, String // call Values and goto state 2 // on lbrace // call Body and goto state 1 // State 1 // Accept // State 2 // on br // shift and goto state 1 // on lbrace // call Body and goto state 1 // // Command is used internally from Parse. func (p *Parser) Command() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Command), 0) // state0: accept, errorSet = false, 2 switch Symbol(p.tok.Ch) { case br: r = append(r, p.shift()) goto state1 case boolean, number, str, word, Value, Word, Number, Boolean, String: r = p.add(r, p.Values()) goto state2 case lbrace: r = p.add(r, p.Body()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) state2: accept, errorSet = false, 7 switch Symbol(p.tok.Ch) { case br: r = append(r, p.shift()) goto state1 case lbrace: r = p.add(r, p.Body()) goto state1 } return p.stop(r, accept, errorSet) } // Config grammar: // // Config = Doc . // // State 0 // on word, Stmt, Word // call Doc and goto state 1 // State 1 // Accept // // Config is used internally from Parse. func (p *Parser) Config() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Config), 0) // state0: accept, errorSet = false, 14 switch Symbol(p.tok.Ch) { case word, Stmt, Word: r = p.add(r, p.Doc()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 0 if accept = accept && p.eof; accept { r = append(r, p.shift()) } r[1] = int32(len(r) - 2) if !accept { p.err(p.tok.Position(), "%q [%s]: expected %v", p.tok.Src(), Symbol(p.tok.Ch), errorSets[errorSet]) } return r } // Doc grammar: // // Doc = Stmt { Stmt } . // // State 0 // on word, Word // call Stmt and goto state 1 // State 1 // Accept // on word, Word // call Stmt and goto state 1 // // Doc is used internally from Parse. func (p *Parser) Doc() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Doc), 0) // state0: accept, errorSet = false, 15 switch Symbol(p.tok.Ch) { case word, Word: r = p.add(r, p.Stmt()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 15 switch Symbol(p.tok.Ch) { case word, Word: r = p.add(r, p.Stmt()) goto state1 } return p.stop(r, accept, errorSet) } // Number grammar: // // Number = number . // // State 0 // on number // shift and goto state 1 // State 1 // Accept // // Number is used internally from Parse. func (p *Parser) Number() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Number), 0) // state0: accept, errorSet = false, 10 switch Symbol(p.tok.Ch) { case number: r = append(r, p.shift()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) } // Stmt grammar: // // Stmt = Word (Assignment | Command) . // // State 0 // on word // call Word and goto state 1 // State 1 // on '=' // call Assignment and goto state 2 // on boolean, br, lbrace, number, str, word, Values, Value, Body, Word, Number, Boolean, String // call Command and goto state 2 // State 2 // Accept // // Stmt is used internally from Parse. func (p *Parser) Stmt() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Stmt), 0) // state0: accept, errorSet = false, 16 switch Symbol(p.tok.Ch) { case word: r = p.add(r, p.Word()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = false, 0 switch Symbol(p.tok.Ch) { case TOK_003d: r = p.add(r, p.Assignment()) goto state2 case boolean, br, lbrace, number, str, word, Values, Value, Body, Word, Number, Boolean, String: r = p.add(r, p.Command()) goto state2 } return p.stop(r, accept, errorSet) state2: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) } // String grammar: // // String = str . // // State 0 // on str // shift and goto state 1 // State 1 // Accept // // String is used internally from Parse. func (p *Parser) String() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(String), 0) // state0: accept, errorSet = false, 13 switch Symbol(p.tok.Ch) { case str: r = append(r, p.shift()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) } // Value grammar: // // Value = Word | String | Number | Boolean . // // State 0 // on word // call Word and goto state 1 // on number // call Number and goto state 1 // on boolean // call Boolean and goto state 1 // on str // call String and goto state 1 // State 1 // Accept // // Value is used internally from Parse. func (p *Parser) Value() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Value), 0) // state0: accept, errorSet = false, 5 switch Symbol(p.tok.Ch) { case word: r = p.add(r, p.Word()) goto state1 case number: r = p.add(r, p.Number()) goto state1 case boolean: r = p.add(r, p.Boolean()) goto state1 case str: r = p.add(r, p.String()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) } // Values grammar: // // # Value types // Values = Value {Value} . // // State 0 // on boolean, number, str, word, Word, Number, Boolean, String // call Value and goto state 1 // State 1 // Accept // on boolean, number, str, word, Word, Number, Boolean, String // call Value and goto state 1 // // Values is used internally from Parse. func (p *Parser) Values() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Values), 0) // state0: accept, errorSet = false, 4 switch Symbol(p.tok.Ch) { case boolean, number, str, word, Word, Number, Boolean, String: r = p.add(r, p.Value()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 4 switch Symbol(p.tok.Ch) { case boolean, number, str, word, Word, Number, Boolean, String: r = p.add(r, p.Value()) goto state1 } return p.stop(r, accept, errorSet) } // Word grammar: // // # Atoms // Word = word . // // State 0 // on word // shift and goto state 1 // State 1 // Accept // // Word is used internally from Parse. func (p *Parser) Word() (r []int32) { accept, errorSet := false, 0 r = append(p.get(), -int32(Word), 0) // state0: accept, errorSet = false, 16 switch Symbol(p.tok.Ch) { case word: r = append(r, p.shift()) goto state1 } return p.stop(r, accept, errorSet) state1: accept, errorSet = true, 0 return p.stop(r, accept, errorSet) } func (p *Parser) shift() (r int32) { r = p.tokIndex if !p.eof { p.tok = p.Scan() p.tokIndex++ p.eof = p.tok.Ch == rune(TOK_EOF) } return r } func (p *Parser) get() (r []int32) { if n := len(p.cache); n != 0 { r = p.cache[n-1][:0] p.cache = p.cache[:n-1] } return r } func (p *Parser) add(r, s []int32) (t []int32) { p.cache = append(p.cache, s) return append(r, s...) } func (p *Parser) stop(r []int32, accept bool, errorSet int) []int32 { r[1] = int32(len(r) - 2) if !accept { p.err(p.tok.Position(), "%q [%s]: expected %v", p.tok.Src(), Symbol(p.tok.Ch), errorSets[errorSet]) } return r } // EOF reports whether the parser lookahead token is EOF. func (p *Parser) EOF() bool { return p.eof } // Token returns the n-th token in 'p'. Token panics if 'n' is out of range. func (p *Parser) Token(n int32) (r scanner.Token) { return p.sc.Token(int(n)) } // Parse parses 'src'. 'src' becomes "owned" by the parser and must not be // mutated afterwards. func (p *Parser) Parse(name string, src []byte) (ast []int32, err error) { if err = p.init(name, src); err != nil { return nil, err } defer func() { switch e := recover(); x := e.(type) { case nil: // ok case scanner.ErrList: err = x case error: err = errors.Join(err, x) default: err = errors.Join(err, fmt.Errorf("%v", x)) } }() p.tok = p.Scan() ast = p.Config() return ast, p.sc.Err() } func (p *Parser) err0(pos token.Position, s string, args ...any) { p.sc.AddErr(pos, s, args...) if p.errBudget--; p.errBudget == 0 { p.sc.AddErr(pos, "too many errors") } } func (p *Parser) err(pos token.Position, s string, args ...any) { p.err0(pos, s, args...) p.shift() if p.eof { panic(p.sc.Err()) } }