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) { switch { case p.After(whitespace + carriageReturn + newline).Ignore(): p.RouteRepeat() case p.After(hash).Backup(): p.RouteTo(stateCommentStart).ThenReturnHere() case p.After(startOfKey).Backup(): p.RouteTo(stateKey) default: p.RouteTo(stateEndOfFile) } } // A key may be either bare, quoted or dotted. func stateKey(p *parsekit.P) { if p.After(bareKeyChars).Backup() { p.RouteTo(statebareKey) } else { p.UnexpectedInput("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 statebareKey(p *parsekit.P) { p.AcceptConsecutive(bareKeyChars) // TODO make a plan for adding this to After() p.EmitLiteral(ItemKey) p.RouteTo(stateEndOfKeyOrKeyDot) } // 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) { // 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) } else { p.RouteTo(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(p *parsekit.P) { p.SkipConsecutive(whitespace) if p.After(equal).Store() { p.EmitLiteral(ItemAssignment) p.SkipConsecutive(whitespace) p.RouteTo(stateValue) } else { p.UnexpectedInput("a value assignment") } }