More sensible state naming. No need to prefix every state function with state_.

This commit is contained in:
Maurice Makaay 2019-05-18 01:49:30 +00:00
parent e2e4fbd901
commit a569c430d5
6 changed files with 31 additions and 30 deletions

View File

@ -40,14 +40,15 @@ const (
)
var (
doubleQuote3 = []interface{}{doubleQuote, doubleQuote, doubleQuote}
hex4 = []interface{}{hex, hex, hex, hex}
shortUtf8Match = []interface{}{backslash, 'u', hex4}
longUtf8Match = []interface{}{backslash, 'U', hex4, hex4}
keySeparatorDot = []interface{}{whitespace, dot, whitespace}
doubleQuote3 = []interface{}{doubleQuote, doubleQuote, doubleQuote}
hex4 = []interface{}{hex, hex, hex, hex}
shortUtf8Match = []interface{}{backslash, 'u', hex4}
longUtf8Match = []interface{}{backslash, 'U', hex4, hex4}
)
// NewParser creates a new parser, using the provided input string
// as the data to parse.
func NewParser(input string) *parsekit.P {
return parsekit.New(input, stateKeyValuePair)
return parsekit.New(input, startKeyValuePair)
}

View File

@ -5,13 +5,13 @@ import (
)
// 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.RouteTo(stateCommentContent)
p.RouteTo(commentContents)
}
// 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 {
case p.AtEndOfLine():
p.EmitLiteralTrim(ItemComment)

View File

@ -2,7 +2,7 @@ package parser
import "github.com/mmakaay/toml/parsekit"
func stateEndOfFile(p *parsekit.P) {
func endOfFile(p *parsekit.P) {
if p.AtEndOfFile() {
p.Emit(parsekit.ItemEOF, "EOF") // todo Automate within parser?
} else {

View File

@ -3,23 +3,23 @@ package parser
import "github.com/mmakaay/toml/parsekit"
// The primary building block of a TOML document is the key/value pair.
func stateKeyValuePair(p *parsekit.P) {
func startKeyValuePair(p *parsekit.P) {
switch {
case p.After(whitespace + carriageReturn + newline).Ignore():
p.RouteRepeat()
case p.After(hash).Backup():
p.RouteTo(stateCommentStart).ThenReturnHere()
p.RouteTo(startComment).ThenReturnHere()
case p.After(startOfKey).Backup():
p.RouteTo(stateKey)
p.RouteTo(startKey)
default:
p.RouteTo(stateEndOfFile)
p.RouteTo(endOfFile)
}
}
// A key may be either bare, quoted or dotted.
func stateKey(p *parsekit.P) {
func startKey(p *parsekit.P) {
if p.After(bareKeyChars).Backup() {
p.RouteTo(statebareKey)
p.RouteTo(startBareKey)
} else {
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
// keys are allowed to be composed of only ASCII digits,
// 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.EmitLiteral(ItemKey)
p.RouteTo(stateEndOfKeyOrKeyDot)
p.RouteTo(endOfKeyOrDot)
}
// Dotted keys are a sequence of bare or quoted keys joined with a dot.
// 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,
// best practice is to not use any extraneous whitespace.
p.SkipConsecutive(whitespace)
if p.After(dot).Store() {
p.SkipConsecutive(whitespace)
p.EmitLiteral(ItemKeyDot)
p.RouteTo(stateKey)
p.RouteTo(startKey)
} 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
// sign, and value must be on the same line (though some values can
// be broken over multiple lines).
func stateKeyAssignment(p *parsekit.P) {
func startKeyAssignment(p *parsekit.P) {
p.SkipConsecutive(whitespace)
if p.After(equal).Store() {
p.EmitLiteral(ItemAssignment)
p.SkipConsecutive(whitespace)
p.RouteTo(stateValue)
p.RouteTo(startValue)
} else {
p.UnexpectedInput("a value assignment")
}

View File

@ -6,10 +6,10 @@ import "github.com/mmakaay/toml/parsekit"
// 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.
// * Basic strings are surrounded by quotation marks.
func stateStringValue(p *parsekit.P) {
func startString(p *parsekit.P) {
switch {
case p.After(doubleQuote3).Ignore():
p.RouteTo(stateMultiLineBasicString)
p.RouteTo(startMultiLineBasicString)
case p.After(doubleQuote).Ignore():
p.RouteTo(startBasicString)
default:
@ -31,7 +31,7 @@ func stateStringValue(p *parsekit.P) {
//
// 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).
func parseString(p *parsekit.P) {
func parseBasicString(p *parsekit.P) {
switch {
case p.AtEndOfFile():
p.UnexpectedEndOfFile("basic string token")
@ -51,7 +51,7 @@ func parseString(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.
@ -65,7 +65,7 @@ func basicStringSpecifics(p *parsekit.P) {
if err := p.EmitInterpreted(ItemString); err != nil { // TODO testcase?
p.EmitError("Invalid data in string: %s", err)
} else {
p.RouteTo(stateKeyValuePair)
p.RouteTo(startKeyValuePair)
}
case p.After(backslash).Backup():
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")
}

View File

@ -4,10 +4,10 @@ import "github.com/mmakaay/toml/parsekit"
// Values must be of the following types: String, Integer, Float, Boolean,
// Datetime, Array, or Inline Table. Unspecified values are invalid.
func stateValue(p *parsekit.P) {
func startValue(p *parsekit.P) {
p.SkipConsecutive(whitespace)
if p.Upcoming(quoteChars) {
p.RouteTo(stateStringValue)
p.RouteTo(startString)
} else {
p.UnexpectedInput("a value")
}