More sensible state naming. No need to prefix every state function with state_.
This commit is contained in:
parent
e2e4fbd901
commit
a569c430d5
|
@ -40,14 +40,15 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
doubleQuote3 = []interface{}{doubleQuote, doubleQuote, doubleQuote}
|
keySeparatorDot = []interface{}{whitespace, dot, whitespace}
|
||||||
hex4 = []interface{}{hex, hex, hex, hex}
|
doubleQuote3 = []interface{}{doubleQuote, doubleQuote, doubleQuote}
|
||||||
shortUtf8Match = []interface{}{backslash, 'u', hex4}
|
hex4 = []interface{}{hex, hex, hex, hex}
|
||||||
longUtf8Match = []interface{}{backslash, 'U', hex4, hex4}
|
shortUtf8Match = []interface{}{backslash, 'u', hex4}
|
||||||
|
longUtf8Match = []interface{}{backslash, 'U', hex4, hex4}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewParser creates a new parser, using the provided input string
|
// NewParser creates a new parser, using the provided input string
|
||||||
// as the data to parse.
|
// as the data to parse.
|
||||||
func NewParser(input string) *parsekit.P {
|
func NewParser(input string) *parsekit.P {
|
||||||
return parsekit.New(input, stateKeyValuePair)
|
return parsekit.New(input, startKeyValuePair)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// A '#' hash symbol marks the rest of the line as a comment.
|
// A '#' hash symbol marks the rest of the line as a comment.
|
||||||
func stateCommentStart(p *parsekit.P) {
|
func startComment(p *parsekit.P) {
|
||||||
p.SkipConsecutive(hash)
|
p.SkipConsecutive(hash)
|
||||||
p.RouteTo(stateCommentContent)
|
p.RouteTo(commentContents)
|
||||||
}
|
}
|
||||||
|
|
||||||
// All characters up to the end of the line are included in the comment.
|
// All characters up to the end of the line are included in the comment.
|
||||||
func stateCommentContent(p *parsekit.P) {
|
func commentContents(p *parsekit.P) {
|
||||||
switch {
|
switch {
|
||||||
case p.AtEndOfLine():
|
case p.AtEndOfLine():
|
||||||
p.EmitLiteralTrim(ItemComment)
|
p.EmitLiteralTrim(ItemComment)
|
||||||
|
|
|
@ -2,7 +2,7 @@ package parser
|
||||||
|
|
||||||
import "github.com/mmakaay/toml/parsekit"
|
import "github.com/mmakaay/toml/parsekit"
|
||||||
|
|
||||||
func stateEndOfFile(p *parsekit.P) {
|
func endOfFile(p *parsekit.P) {
|
||||||
if p.AtEndOfFile() {
|
if p.AtEndOfFile() {
|
||||||
p.Emit(parsekit.ItemEOF, "EOF") // todo Automate within parser?
|
p.Emit(parsekit.ItemEOF, "EOF") // todo Automate within parser?
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,23 +3,23 @@ package parser
|
||||||
import "github.com/mmakaay/toml/parsekit"
|
import "github.com/mmakaay/toml/parsekit"
|
||||||
|
|
||||||
// The primary building block of a TOML document is the key/value pair.
|
// The primary building block of a TOML document is the key/value pair.
|
||||||
func stateKeyValuePair(p *parsekit.P) {
|
func startKeyValuePair(p *parsekit.P) {
|
||||||
switch {
|
switch {
|
||||||
case p.After(whitespace + carriageReturn + newline).Ignore():
|
case p.After(whitespace + carriageReturn + newline).Ignore():
|
||||||
p.RouteRepeat()
|
p.RouteRepeat()
|
||||||
case p.After(hash).Backup():
|
case p.After(hash).Backup():
|
||||||
p.RouteTo(stateCommentStart).ThenReturnHere()
|
p.RouteTo(startComment).ThenReturnHere()
|
||||||
case p.After(startOfKey).Backup():
|
case p.After(startOfKey).Backup():
|
||||||
p.RouteTo(stateKey)
|
p.RouteTo(startKey)
|
||||||
default:
|
default:
|
||||||
p.RouteTo(stateEndOfFile)
|
p.RouteTo(endOfFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A key may be either bare, quoted or dotted.
|
// A key may be either bare, quoted or dotted.
|
||||||
func stateKey(p *parsekit.P) {
|
func startKey(p *parsekit.P) {
|
||||||
if p.After(bareKeyChars).Backup() {
|
if p.After(bareKeyChars).Backup() {
|
||||||
p.RouteTo(statebareKey)
|
p.RouteTo(startBareKey)
|
||||||
} else {
|
} else {
|
||||||
p.UnexpectedInput("a valid key name")
|
p.UnexpectedInput("a valid key name")
|
||||||
}
|
}
|
||||||
|
@ -29,24 +29,24 @@ func stateKey(p *parsekit.P) {
|
||||||
// underscores, and dashes (A-Za-z0-9_-). Note that bare
|
// underscores, and dashes (A-Za-z0-9_-). Note that bare
|
||||||
// keys are allowed to be composed of only ASCII digits,
|
// keys are allowed to be composed of only ASCII digits,
|
||||||
// e.g. 1234, but are always interpreted as strings.
|
// e.g. 1234, but are always interpreted as strings.
|
||||||
func statebareKey(p *parsekit.P) {
|
func startBareKey(p *parsekit.P) {
|
||||||
p.AcceptConsecutive(bareKeyChars) // TODO make a plan for adding this to After()
|
p.AcceptConsecutive(bareKeyChars) // TODO make a plan for adding this to After()
|
||||||
p.EmitLiteral(ItemKey)
|
p.EmitLiteral(ItemKey)
|
||||||
p.RouteTo(stateEndOfKeyOrKeyDot)
|
p.RouteTo(endOfKeyOrDot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dotted keys are a sequence of bare or quoted keys joined with a dot.
|
// Dotted keys are a sequence of bare or quoted keys joined with a dot.
|
||||||
// This allows for grouping similar properties together:
|
// This allows for grouping similar properties together:
|
||||||
func stateEndOfKeyOrKeyDot(p *parsekit.P) {
|
func endOfKeyOrDot(p *parsekit.P) {
|
||||||
// Whitespace around dot-separated parts is ignored, however,
|
// Whitespace around dot-separated parts is ignored, however,
|
||||||
// best practice is to not use any extraneous whitespace.
|
// best practice is to not use any extraneous whitespace.
|
||||||
p.SkipConsecutive(whitespace)
|
p.SkipConsecutive(whitespace)
|
||||||
if p.After(dot).Store() {
|
if p.After(dot).Store() {
|
||||||
p.SkipConsecutive(whitespace)
|
p.SkipConsecutive(whitespace)
|
||||||
p.EmitLiteral(ItemKeyDot)
|
p.EmitLiteral(ItemKeyDot)
|
||||||
p.RouteTo(stateKey)
|
p.RouteTo(startKey)
|
||||||
} else {
|
} else {
|
||||||
p.RouteTo(stateKeyAssignment)
|
p.RouteTo(startKeyAssignment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ func stateEndOfKeyOrKeyDot(p *parsekit.P) {
|
||||||
// Whitespace is ignored around key names and values. The key, equals
|
// Whitespace is ignored around key names and values. The key, equals
|
||||||
// sign, and value must be on the same line (though some values can
|
// sign, and value must be on the same line (though some values can
|
||||||
// be broken over multiple lines).
|
// be broken over multiple lines).
|
||||||
func stateKeyAssignment(p *parsekit.P) {
|
func startKeyAssignment(p *parsekit.P) {
|
||||||
p.SkipConsecutive(whitespace)
|
p.SkipConsecutive(whitespace)
|
||||||
if p.After(equal).Store() {
|
if p.After(equal).Store() {
|
||||||
p.EmitLiteral(ItemAssignment)
|
p.EmitLiteral(ItemAssignment)
|
||||||
p.SkipConsecutive(whitespace)
|
p.SkipConsecutive(whitespace)
|
||||||
p.RouteTo(stateValue)
|
p.RouteTo(startValue)
|
||||||
} else {
|
} else {
|
||||||
p.UnexpectedInput("a value assignment")
|
p.UnexpectedInput("a value assignment")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ import "github.com/mmakaay/toml/parsekit"
|
||||||
// and multi-line literal. All strings must contain only valid UTF-8 characters.
|
// and multi-line literal. All strings must contain only valid UTF-8 characters.
|
||||||
// * Multi-line basic strings are surrounded by three quotation marks on each side.
|
// * Multi-line basic strings are surrounded by three quotation marks on each side.
|
||||||
// * Basic strings are surrounded by quotation marks.
|
// * Basic strings are surrounded by quotation marks.
|
||||||
func stateStringValue(p *parsekit.P) {
|
func startString(p *parsekit.P) {
|
||||||
switch {
|
switch {
|
||||||
case p.After(doubleQuote3).Ignore():
|
case p.After(doubleQuote3).Ignore():
|
||||||
p.RouteTo(stateMultiLineBasicString)
|
p.RouteTo(startMultiLineBasicString)
|
||||||
case p.After(doubleQuote).Ignore():
|
case p.After(doubleQuote).Ignore():
|
||||||
p.RouteTo(startBasicString)
|
p.RouteTo(startBasicString)
|
||||||
default:
|
default:
|
||||||
|
@ -31,7 +31,7 @@ func stateStringValue(p *parsekit.P) {
|
||||||
//
|
//
|
||||||
// Any Unicode character may be used except those that must be escaped:
|
// Any Unicode character may be used except those that must be escaped:
|
||||||
// quotation mark, backslash, and the control characters (U+0000 to U+001F, U+007F).
|
// quotation mark, backslash, and the control characters (U+0000 to U+001F, U+007F).
|
||||||
func parseString(p *parsekit.P) {
|
func parseBasicString(p *parsekit.P) {
|
||||||
switch {
|
switch {
|
||||||
case p.AtEndOfFile():
|
case p.AtEndOfFile():
|
||||||
p.UnexpectedEndOfFile("basic string token")
|
p.UnexpectedEndOfFile("basic string token")
|
||||||
|
@ -51,7 +51,7 @@ func parseString(p *parsekit.P) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func startBasicString(p *parsekit.P) {
|
func startBasicString(p *parsekit.P) {
|
||||||
p.RouteTo(parseString).ThenTo(basicStringSpecifics)
|
p.RouteTo(parseBasicString).ThenTo(basicStringSpecifics)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specific handling of input for basic strings.
|
// Specific handling of input for basic strings.
|
||||||
|
@ -65,7 +65,7 @@ func basicStringSpecifics(p *parsekit.P) {
|
||||||
if err := p.EmitInterpreted(ItemString); err != nil { // TODO testcase?
|
if err := p.EmitInterpreted(ItemString); err != nil { // TODO testcase?
|
||||||
p.EmitError("Invalid data in string: %s", err)
|
p.EmitError("Invalid data in string: %s", err)
|
||||||
} else {
|
} else {
|
||||||
p.RouteTo(stateKeyValuePair)
|
p.RouteTo(startKeyValuePair)
|
||||||
}
|
}
|
||||||
case p.After(backslash).Backup():
|
case p.After(backslash).Backup():
|
||||||
p.EmitError("Invalid escape sequence")
|
p.EmitError("Invalid escape sequence")
|
||||||
|
@ -74,6 +74,6 @@ func basicStringSpecifics(p *parsekit.P) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func stateMultiLineBasicString(p *parsekit.P) {
|
func startMultiLineBasicString(p *parsekit.P) {
|
||||||
p.EmitError("Not yet implemented")
|
p.EmitError("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@ import "github.com/mmakaay/toml/parsekit"
|
||||||
|
|
||||||
// Values must be of the following types: String, Integer, Float, Boolean,
|
// Values must be of the following types: String, Integer, Float, Boolean,
|
||||||
// Datetime, Array, or Inline Table. Unspecified values are invalid.
|
// Datetime, Array, or Inline Table. Unspecified values are invalid.
|
||||||
func stateValue(p *parsekit.P) {
|
func startValue(p *parsekit.P) {
|
||||||
p.SkipConsecutive(whitespace)
|
p.SkipConsecutive(whitespace)
|
||||||
if p.Upcoming(quoteChars) {
|
if p.Upcoming(quoteChars) {
|
||||||
p.RouteTo(stateStringValue)
|
p.RouteTo(startString)
|
||||||
} else {
|
} else {
|
||||||
p.UnexpectedInput("a value")
|
p.UnexpectedInput("a value")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue