go-toml/parse2/grammar.go.bak

222 lines
6.7 KiB
Go

package parse2
import "git.makaay.nl/mauricem/go-parsekit/tokenize"
var (
c, a, m, tok = tokenize.C, tokenize.A, tokenize.M, tokenize.T
// Overall Structure
toml = c.Seq(expression, c.ZeroOrMore(newline.Then(expression)))
expression = c.Any(
c.Seq(ws, comment.Optional()),
c.Seq(ws, keyval, ws, comment.Optional()),
c.Seq(ws, table, ws, comment.Optional()))
// ABNF definitions
alpha = a.Letter
digit = a.Digit
// Whitespace, Newline
ws = c.ZeroOrMore(wschar)
tab = a.Tab
space = a.Space
wschar = tab.Or(space)
newline = a.Newline
wsOrNewline = ws.Or(newline)
// Comment
comment = commentStartSymbol.Then(c.ZeroOrMore(nonEOL))
commentStartSymbol = a.Hash
nonEOL = c.Any(a.Rune(0x09), printableASCII, nonASCII)
printableASCII = a.RuneRange(0x20, 0x7E)
nonASCII = a.RuneRange(0x80, 0xD7FF).Or(a.RuneRange(0xE000, 0x10FFFF))
// Key-Value Pairs
keyval = c.Seq(key, keyvalSep, val)
key = simpleKey.Or(dottedKey)
simpleKey = quotedKey.Or(unquotedKey)
unquotedKey = c.OneOrMore(c.Any(alpha, digit, minus, underscore))
quotedKey = basicString.Or(literalString)
dottedKey = c.Seq(simpleKey, c.OneOrMore(dotSep.Then(simpleKey)))
dotSep = c.Seq(ws, a.Dot, ws)
keyvalSep = c.Seq(ws, a.Equal, ws)
val = c.Any(string, boolean, array, inlineTable, dateTime, float, integer)
// String
string = c.Any(mlBasicString, basicString, mlLiteralString, literalString)
// Basic String
basicString = c.Seq(quotationMark, c.ZeroOrMore(basicChar), quotationMark)
quotationMark = a.DoubleQuote
basicChar = escaped.Or(basicUnescaped)
basicUnescaped = c.Any(printableASCII.Except(quotationMark.Or(escape)), nonASCII)
escaped = escape.Then(escapeSeqChar)
escape = a.Backslash
escapeSeqChar = c.Any(
a.Runes('"', '\\', 'b', 'f', 'n', 'r', 't'),
a.Rune('u').Then(a.HexDigit.Times(4)),
a.Rune('U').Then(a.HexDigit.Times(8)))
// Multiline Basic String
mlBasicString = c.Seq(mlBasicStringDelim, mlBasicBody, mlBasicStringDelim)
mlBasicStringDelim = quotationMark.Times(3)
mlBasicBody = c.ZeroOrMore(c.Any(mlBasicChar, newline, mlBasicBodyConcat))
mlBasicChar = mlBasicUnescaped.Or(escaped)
mlBasicUnescaped = c.Any(printableASCII.Except(a.Backslash), nonASCII)
mlBasicBodyConcat = c.Seq(escape, ws, newline, c.ZeroOrMore(wsOrNewline))
// Literal String
literalString = c.Seq(apostrophe, c.ZeroOrMore(literalChar), apostrophe)
apostrophe = a.SingleQuote
literalChar = c.Any(a.Tab, printableASCII.Except(apostrophe), nonASCII)
// Multiline Literal String
mlLiteralString = c.Seq(mlLiteralStringDelim, mlLiteralBody, mlLiteralStringDelim)
mlLiteralStringDelim = apostrophe.Times(3)
mlLiteralBody = c.ZeroOrMore(mlLiteralChar.Or(newline))
mlLiteralChar = c.Any(a.Tab, printableASCII, nonASCII)
// Integer
integer = c.Any(decInt, hexInt, octInt, binInt)
minus = a.Minus
plus = a.Plus
underscore = a.Underscore
decInt = c.Optional(plus.Or(minus)).Then(unsignedDecInt)
unsignedDecInt = c.Any(digit, digit1to9.Then(c.OneOrMore(intDigitOrUnderscoreIntDigit)))
digit1to9 = a.DigitNotZero
intDigitOrUnderscoreIntDigit = c.Any(digit, underscore.Then(digit))
hexInt = c.Seq(hexPrefix, hexDigit, c.ZeroOrMore(hexDigitOrUnderscoreHexDigit))
hexPrefix = a.Zero.Then(a.Rune('x'))
hexDigit = a.HexDigit
hexDigitOrUnderscoreHexDigit = c.Any(hexDigit, underscore.Then(hexDigit))
octInt = c.Seq(octPrefix, digit0to7, c.ZeroOrMore(octDigitOrUnderscoreOctDigit))
octPrefix = a.Zero.Then(a.Rune('o'))
digit0to7 = a.RuneRange('0', '7')
octDigitOrUnderscoreOctDigit = c.Any(digit0to7, underscore.Then(digit0to7))
binInt = c.Seq(binPrefix, digit0to1, c.ZeroOrMore(binDigitOrUnderscoreBinDigit))
binPrefix = a.Zero.Then(a.Rune('b'))
digit0to1 = a.Runes('0', '1')
binDigitOrUnderscoreBinDigit = c.Any(digit0to1, underscore.Then(digit0to1))
// Float
float = standardFloat.Or(specialFloat)
standardFloat = c.Seq(floatIntPart, exp.Or(frac.Then(c.Optional(exp))))
floatIntPart = decInt
exp = a.StrNoCase("e").Then(floatIntPart)
frac = c.Seq(decimalPoint, zeroPrefixableInt)
decimalPoint = a.Dot
zeroPrefixableInt = c.Seq(digit, c.ZeroOrMore(intDigitOrUnderscoreIntDigit))
specialFloat = c.Optional(plus.Or(minus)).Then(inf.Or(nan))
inf = a.Str("inf")
nan = a.Str("nan")
// Boolean
boolean = boolTrue.Or(boolFalse)
boolTrue = a.Str("true")
boolFalse = a.Str("false")
// Date and time (as defined in RFC 3339)
dateTime = c.Any(offsetDateTime, localDateTime, localDate, localTime)
offsetDateTime = c.Seq(fullDate, timeDelim, fullTime)
localDateTime = c.Seq(fullDate, timeDelim, partialTime)
localDate = fullDate
localTime = partialTime
dateFullYear = digit.Times(4)
dateMonth = digit.Times(2)
dateMday = digit.Times(2)
timeDelim = a.Runes('T', 't', ' ')
timeHour = digit.Times(2)
timeMinute = digit.Times(2)
timeSecond = digit.Times(2)
timeSecfrac = a.Dot.Then(c.OneOrMore(digit))
timeNumOffset = c.Seq(plus.Or(minus), timeHour, a.Colon, timeMinute)
timeOffset = c.Any(a.Runes('Z', 'z'), timeNumOffset)
partialTime = c.Seq(timeHour, a.Colon, timeMinute, a.Colon, timeSecond, timeSecfrac.Optional())
fullTime = c.Seq(partialTime, timeOffset)
fullDate = c.Seq(dateFullYear, minus, dateMonth, minus, dateMday)
// Array
array = c.Seq(arrayOpen, arrayvalues.Optional(), wsCommentNewline, arrayClose)
arrayOpen = a.SquareOpen
arrayClose = a.SquareClose
arrayvalues = c.Seq(arrayValue, c.ZeroOrMore(c.Seq(arraySep, arrayValue)), arraySep.Optional())
arraySep = ws.Then(a.Comma)
arrayValue = wsCommentNewline.Then(val)
wsCommentNewline = c.ZeroOrMore(wschar.Or(comment.Optional().Then(newline)))
// Table
table = stdTable.Or(arrayTable)
// Standard Table
stdTable = c.Seq(stdTableOpen, key, stdTableClose)
stdTableOpen = a.SquareOpen.Then(ws)
stdTableClose = ws.Then(a.SquareClose)
// Inline Table
inlineTable = c.Seq(inlineTableOpen, inlineTableKeyvals, inlineTableClose)
inlineTableOpen = a.CurlyOpen.Then(ws)
inlineTableClose = ws.Then(a.CurlyClose)
inlineTableKeyvals = c.Seq(inlineTableKeyval, c.ZeroOrMore(c.Seq(inlineTableSep, inlineTableKeyval)))
inlineTableKeyval = c.Seq(key, keyvalSep, val)
inlineTableSep = c.Seq(ws, a.Comma, ws)
// Array Table
arrayTable = c.Seq(arrayTableOpen, key, arrayTableClose)
arrayTableOpen = a.SquareOpen.Times(2).Then(ws)
arrayTableClose = ws.Then(a.SquareClose.Times(2))
)
func init() {
}