package parser import "github.com/mmakaay/toml/parsekit" // The primary building block of a TOML document is the key/value pair. func startKeyValuePair(p *parsekit.P) { switch { case p.On(whitespace + carriageReturn + newline).Skip(): p.Repeat() case p.On(hash).Stay(): p.RouteTo(startComment).ThenReturnHere() case p.On(startOfKey).RouteTo(startKey): default: p.RouteTo(endOfFile) } } // A key may be either bare, quoted or dotted. func startKey(p *parsekit.P) { switch { case p.On(bareKeyChars).RouteTo(startBareKey): default: 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 startBareKey(p *parsekit.P) { p.AcceptConsecutive(bareKeyChars) // TODO make a plan for adding this to After() p.EmitLiteral(ItemKey) 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 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.On(dot).Accept() { p.SkipConsecutive(whitespace) p.EmitLiteral(ItemKeyDot) p.RouteTo(startKey) } else { p.RouteTo(startKeyAssignment) } } // 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 startKeyAssignment(p *parsekit.P) { p.SkipConsecutive(whitespace) if p.On(equal).Accept() { p.EmitLiteral(ItemAssignment) p.SkipConsecutive(whitespace) p.RouteTo(startValue) } else { p.UnexpectedInput("a value assignment") } }