aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
author2026-03-09 23:05:42 +0300
committer2026-03-09 23:05:42 +0300
commit00394a80501960ad26787b5c44435ed5ed67ad84 (patch)
tree672eb918c552c858f32e9533dc3799af6b75769f /internal
parent'-' sign in words accepted (diff)
downloadconf-0.1.0.tar.gz
conf-0.1.0.tar.bz2
conf-0.1.0.tar.xz
conf-0.1.0.zip
Полностью переписал библиотеку. Перевёл с EBNF на PEG.v0.1.0
Diffstat (limited to '')
-rw-r--r--internal/ast/processor.go119
-rw-r--r--internal/ast/tree.go43
-rw-r--r--internal/parser/parser.go1803
3 files changed, 0 insertions, 1965 deletions
diff --git a/internal/ast/processor.go b/internal/ast/processor.go
deleted file mode 100644
index 55dce59..0000000
--- a/internal/ast/processor.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package ast
-
-import (
- "fmt"
- "strconv"
-
- "go.neonxp.ru/conf/internal/parser"
- "go.neonxp.ru/conf/model"
-)
-
-func ToDoc(config *Node) (model.Body, error) {
- if len(config.Children) < 1 {
- return nil, fmt.Errorf("invalid ast tree")
- }
-
- doc := config.Children[0]
-
- return processDoc(doc), nil
-}
-
-func processDoc(docNode *Node) model.Body {
- doc := make(model.Body, 0, len(docNode.Children))
- for _, stmt := range docNode.Children {
- processStmt(&doc, stmt)
- }
- return doc
-}
-
-func processStmt(doc *model.Body, stmt *Node) {
- ident := extractIdent(stmt.Children[0])
- nodeBody := stmt.Children[1]
- switch nodeBody.Symbol {
- case parser.Command:
- *doc = append(*doc, processDirective(ident, nodeBody))
- case parser.Assignment:
- *doc = append(*doc, processSetting(ident, nodeBody))
- }
-}
-
-func processDirective(ident string, directive *Node) *model.Directive {
- result := &model.Directive{
- Name: ident,
- }
-
- for _, child := range directive.Children {
- // Can be arguments OR body OR both
- switch child.Symbol {
- case parser.Values:
- result.Arguments = extractValues(child)
- case parser.Body:
- // Children[0] = '{', Children[1] = Body, Children[2] = '}'
- result.Body = processDoc(child.Children[1])
- }
- }
-
- return result
-}
-
-func processSetting(ident string, setting *Node) *model.Setting {
- result := &model.Setting{
- Key: ident,
- Value: extractValues(setting.Children[1]), // Children[0] = '=', Children[1] = Values, Children[2] = ';'
- }
-
- return result
-}
-
-func extractIdent(word *Node) string {
- return word.Children[0].Source
-}
-
-func extractValues(args *Node) []model.Value {
- result := make([]model.Value, len(args.Children))
- for i, child := range args.Children {
- v, err := extractValue(child)
- if err != nil {
- result[i] = err
- continue
- }
- result[i] = v
- }
-
- return result
-}
-
-func extractValue(value *Node) (any, error) {
- v := value.Children[0]
- s := v.Children[0].Source
- switch v.Symbol {
- case parser.Word:
- return model.Word(s), nil
- case parser.String:
- return unquote(s), nil
- case parser.Number:
- d, err := strconv.Atoi(s)
- if err == nil {
- return d, nil
- }
- fl, err := strconv.ParseFloat(s, 32)
- if err == nil {
- return fl, nil
- }
- return nil, fmt.Errorf("invalid number: %s (%s)", v.Source, s)
- case parser.Boolean:
- return s == "true", nil
- default:
- return nil, fmt.Errorf("unknown value type: %s (%s)", v.Symbol, s)
- }
-}
-
-func unquote(str string) string {
- if len(str) == 0 {
- return ""
- }
- if str[0:1] == `"` || str[0:1] == "'" || str[0:1] == "`" {
- return str[1 : len(str)-1]
- }
- return str
-}
diff --git a/internal/ast/tree.go b/internal/ast/tree.go
deleted file mode 100644
index 72b7c78..0000000
--- a/internal/ast/tree.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package ast
-
-import (
- "go.neonxp.ru/conf/internal/parser"
- "modernc.org/scanner"
-)
-
-func Parse(p *parser.Parser, data []int32) []*Node {
- nodes := make([]*Node, 0, 2)
- for len(data) != 0 {
- next := int32(1)
- var node *Node
- switch n := data[0]; {
- case n < 0:
- next = 2 + data[1]
- node = &Node{
- Symbol: parser.Symbol(-data[0]),
- Children: Parse(p, data[2:next]),
- }
- default:
- tok := p.Token(n)
- node = &Node{
- Token: tok,
- Symbol: parser.Symbol(tok.Ch),
- Source: tok.Src(),
- Col: tok.Position().Column,
- Line: tok.Position().Line,
- }
- }
- nodes = append(nodes, node)
- data = data[next:]
- }
- return nodes
-}
-
-type Node struct {
- Symbol parser.Symbol
- Token scanner.Token
- Children []*Node
- Source string
- Col int
- Line int
-}
diff --git a/internal/parser/parser.go b/internal/parser/parser.go
deleted file mode 100644
index 171878d..0000000
--- a/internal/parser/parser.go
+++ /dev/null
@@ -1,1803 +0,0 @@
-// 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())
- }
-}