aboutsummaryrefslogtreecommitdiff
path: root/internal/parser/parser.go
diff options
context:
space:
mode:
author2026-02-16 21:37:31 +0300
committer2026-02-17 20:13:24 +0300
commitd3fd3ba6f9796df96ec4eae9124a460fbb05eb59 (patch)
tree57803d91f8ae7bd3085b0b393bdf81bcc2ac0dfa /internal/parser/parser.go
downloadconf-d3fd3ba6f9796df96ec4eae9124a460fbb05eb59.tar.gz
conf-d3fd3ba6f9796df96ec4eae9124a460fbb05eb59.tar.bz2
conf-d3fd3ba6f9796df96ec4eae9124a460fbb05eb59.tar.xz
conf-d3fd3ba6f9796df96ec4eae9124a460fbb05eb59.zip
init
Diffstat (limited to 'internal/parser/parser.go')
-rw-r--r--internal/parser/parser.go992
1 files changed, 992 insertions, 0 deletions
diff --git a/internal/parser/parser.go b/internal/parser/parser.go
new file mode 100644
index 0000000..c1785f6
--- /dev/null
+++ b/internal/parser/parser.go
@@ -0,0 +1,992 @@
+// 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-Z0-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 l37 }
+ if accept('\n') { goto l39 }
+ if accept('\r') { goto l41 }
+ if accept(' ') { goto l43 }
+ if accept('"') { goto l45 }
+ if accept('#') { goto l57 }
+ if accept('\'') { goto l65 }
+ if accept('-') { goto l77 }
+ if accept(';') { goto l93 }
+ if accept('=') { goto l95 }
+ if accept('`') { goto l105 }
+ if accept('f') { goto l117 }
+ if accept('t') { goto l145 }
+ if accept('{') { goto l167 }
+ if accept('}') { goto l169 }
+ if r < '0' { goto l30out }
+ if accept2('9') { goto l80 }
+l30out:
+ if r < 'A' { goto l32out }
+ if accept2('Z') { goto l97 }
+ if accept('_') { goto l97 }
+ if r < 'a' { goto l32out }
+ if accept2('e') { goto l97 }
+ if r < 'g' { goto l32out }
+ if accept2('s') { goto l97 }
+ if r < 'u' { goto l32out }
+ if accept2('z') { goto l97 }
+l32out:
+ if r == endOfText { goto l171 }
+ return id, length
+l37:
+ id, length = 8, pos
+ return id, length
+l39:
+ id, length = 8, pos
+ return id, length
+l41:
+ id, length = 8, pos
+ return id, length
+l43:
+ id, length = 8, pos
+ return id, length
+l45:
+ if accept('"') { goto l50 }
+ if accept2('!') { goto l52 }
+ if r < '#' { goto l47out }
+ if accept2('\U0010ffff') { goto l52 }
+l47out:
+ return id, length
+l50:
+ id, length = 7, pos
+ return id, length
+l52:
+ if accept('"') { goto l50 }
+ if accept2('!') { goto l52 }
+ if r < '#' { goto l54out }
+ if accept2('\U0010ffff') { goto l52 }
+l54out:
+ return id, length
+l57:
+ id, length = 8, pos
+ if accept2('\t') { goto l61 }
+ if r < '\v' { goto l58out }
+ if accept2('\U0010ffff') { goto l61 }
+l58out:
+ return id, length
+l61:
+ id, length = 8, pos
+ if accept2('\t') { goto l61 }
+ if r < '\v' { goto l62out }
+ if accept2('\U0010ffff') { goto l61 }
+l62out:
+ return id, length
+l65:
+ if accept('\'') { goto l70 }
+ if accept2('&') { goto l72 }
+ if r < '(' { goto l67out }
+ if accept2('\U0010ffff') { goto l72 }
+l67out:
+ return id, length
+l70:
+ id, length = 7, pos
+ return id, length
+l72:
+ if accept('\'') { goto l70 }
+ if accept2('&') { goto l72 }
+ if r < '(' { goto l74out }
+ if accept2('\U0010ffff') { goto l72 }
+l74out:
+ return id, length
+l77:
+ if r < '0' { goto l77out }
+ if accept2('9') { goto l80 }
+l77out:
+ return id, length
+l80:
+ id, length = 5, pos
+ if accept('.') { goto l86 }
+ if r < '0' { goto l83out }
+ if accept2('9') { goto l80 }
+l83out:
+ return id, length
+l86:
+ if r < '0' { goto l86out }
+ if accept2('9') { goto l89 }
+l86out:
+ return id, length
+l89:
+ id, length = 5, pos
+ if r < '0' { goto l90out }
+ if accept2('9') { goto l89 }
+l90out:
+ return id, length
+l93:
+ id, length = 3, pos
+ return id, length
+l95:
+ id, length = 1, pos
+ return id, length
+l97:
+ id, length = 9, pos
+ if r < '0' { goto l98out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l98out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l98out }
+ if accept2('z') { goto l101 }
+l98out:
+ return id, length
+l101:
+ id, length = 9, pos
+ if r < '0' { goto l102out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l102out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l102out }
+ if accept2('z') { goto l101 }
+l102out:
+ return id, length
+l105:
+ if accept('`') { goto l110 }
+ if accept2('_') { goto l112 }
+ if r < 'a' { goto l107out }
+ if accept2('\U0010ffff') { goto l112 }
+l107out:
+ return id, length
+l110:
+ id, length = 7, pos
+ return id, length
+l112:
+ if accept('`') { goto l110 }
+ if accept2('_') { goto l112 }
+ if r < 'a' { goto l114out }
+ if accept2('\U0010ffff') { goto l112 }
+l114out:
+ return id, length
+l117:
+ id, length = 9, pos
+ if accept('a') { goto l123 }
+ if r < '0' { goto l120out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l120out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'b' { goto l120out }
+ if accept2('z') { goto l101 }
+l120out:
+ return id, length
+l123:
+ id, length = 9, pos
+ if accept('l') { goto l129 }
+ if r < '0' { goto l126out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l126out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l126out }
+ if accept2('k') { goto l101 }
+ if r < 'm' { goto l126out }
+ if accept2('z') { goto l101 }
+l126out:
+ return id, length
+l129:
+ id, length = 9, pos
+ if accept('s') { goto l135 }
+ if r < '0' { goto l132out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l132out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l132out }
+ if accept2('r') { goto l101 }
+ if r < 't' { goto l132out }
+ if accept2('z') { goto l101 }
+l132out:
+ return id, length
+l135:
+ id, length = 9, pos
+ if accept('e') { goto l141 }
+ if r < '0' { goto l138out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l138out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l138out }
+ if accept2('d') { goto l101 }
+ if r < 'f' { goto l138out }
+ if accept2('z') { goto l101 }
+l138out:
+ return id, length
+l141:
+ id, length = 2, pos
+ if r < '0' { goto l142out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l142out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l142out }
+ if accept2('z') { goto l101 }
+l142out:
+ return id, length
+l145:
+ id, length = 9, pos
+ if accept('r') { goto l151 }
+ if r < '0' { goto l148out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l148out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l148out }
+ if accept2('q') { goto l101 }
+ if r < 's' { goto l148out }
+ if accept2('z') { goto l101 }
+l148out:
+ return id, length
+l151:
+ id, length = 9, pos
+ if accept('u') { goto l157 }
+ if r < '0' { goto l154out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l154out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l154out }
+ if accept2('t') { goto l101 }
+ if r < 'v' { goto l154out }
+ if accept2('z') { goto l101 }
+l154out:
+ return id, length
+l157:
+ id, length = 9, pos
+ if accept('e') { goto l163 }
+ if r < '0' { goto l160out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l160out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l160out }
+ if accept2('d') { goto l101 }
+ if r < 'f' { goto l160out }
+ if accept2('z') { goto l101 }
+l160out:
+ return id, length
+l163:
+ id, length = 2, pos
+ if r < '0' { goto l164out }
+ if accept2('9') { goto l101 }
+ if r < 'A' { goto l164out }
+ if accept2('Z') { goto l101 }
+ if accept('_') { goto l101 }
+ if r < 'a' { goto l164out }
+ if accept2('z') { goto l101 }
+l164out:
+ return id, length
+l167:
+ id, length = 4, pos
+ return id, length
+l169:
+ id, length = 6, pos
+ return id, length
+l171:
+ 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())
+ }
+}
+