74 lines
2.3 KiB
Go
74 lines
2.3 KiB
Go
package lexer
|
|
|
|
import "github.com/mmakaay/toml/parser"
|
|
|
|
// The primary building block of a TOML document is the key/value pair.
|
|
func stateKeyValuePair(l *parser.Parser) parser.StateFn {
|
|
switch {
|
|
case l.SkipConsecutive(whitespace + carriageReturn + newline):
|
|
return stateKeyValuePair
|
|
case l.Upcoming(hash):
|
|
return l.ToChildState(stateCommentStart)
|
|
case l.Upcoming(startOfKey):
|
|
return l.ToChildState(stateKey)
|
|
default:
|
|
return stateEndOfFile
|
|
}
|
|
}
|
|
|
|
// A key may be either bare, quoted or dotted.
|
|
func stateKey(l *parser.Parser) parser.StateFn {
|
|
if l.AcceptMatching(bareKeyChars) {
|
|
return statebareKeyChars
|
|
}
|
|
return l.UnexpectedInputError("a valid key name")
|
|
}
|
|
|
|
// Bare keys may only contain ASCII letters, ASCII digits,
|
|
// underscores, and dashes (A-Za-z0-9_-). Note that bare
|
|
// keys are allowed to be composed of only ASCII digits,
|
|
// e.g. 1234, but are always interpreted as strings.
|
|
func statebareKeyChars(l *parser.Parser) parser.StateFn {
|
|
l.AcceptConsecutive(bareKeyChars)
|
|
l.EmitLiteral(ItemKey)
|
|
return stateEndOfKeyOrKeyDot
|
|
}
|
|
|
|
// Dotted keys are a sequence of bare or quoted keys joined with a dot.
|
|
// This allows for grouping similar properties together:
|
|
func stateEndOfKeyOrKeyDot(l *parser.Parser) parser.StateFn {
|
|
// Whitespace around dot-separated parts is ignored, however,
|
|
// best practice is to not use any extraneous whitespace.
|
|
l.SkipConsecutive(whitespace)
|
|
if l.SkipMatching(dot) {
|
|
l.Emit(ItemKeyDot, "")
|
|
l.SkipConsecutive(whitespace)
|
|
return stateKey
|
|
}
|
|
return stateKeyAssignment
|
|
}
|
|
|
|
// Keys are on the left of the equals sign and values are on the right.
|
|
// Whitespace is ignored around key names and values. The key, equals
|
|
// sign, and value must be on the same line (though some values can
|
|
// be broken over multiple lines).
|
|
func stateKeyAssignment(l *parser.Parser) parser.StateFn {
|
|
l.SkipConsecutive(whitespace)
|
|
if l.SkipMatching(equal) {
|
|
l.Emit(ItemAssignment, "")
|
|
l.SkipConsecutive(whitespace)
|
|
return stateValue
|
|
}
|
|
return l.UnexpectedInputError("a value assignment")
|
|
}
|
|
|
|
// Values must be of the following types: String, Integer, Float, Boolean,
|
|
// Datetime, Array, or Inline Table. Unspecified values are invalid.
|
|
func stateValue(l *parser.Parser) parser.StateFn {
|
|
l.SkipConsecutive(whitespace)
|
|
if l.Upcoming(quoteChars) {
|
|
return stateStringValue
|
|
}
|
|
return l.UnexpectedInputError("a value")
|
|
}
|