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) parsekit.StateFn { switch { case p.SkipConsecutive(whitespace + carriageReturn + newline): return stateKeyValuePair case p.Upcoming(hash): return p.ToChildState(stateCommentStart) case p.Upcoming(startOfKey): return stateKey default: return stateEndOfFile } } // A key may be either bare, quoted or dotted. func stateKey(p *parsekit.P) parsekit.StateFn { if p.AcceptMatching(bareKeyChars) { return statebareKeyChars } return 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 statebareKeyChars(p *parsekit.P) parsekit.StateFn { p.AcceptConsecutive(bareKeyChars) p.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(p *parsekit.P) parsekit.StateFn { // Whitespace around dot-separated parts is ignored, however, // best practice is to not use any extraneous whitespace. p.SkipConsecutive(whitespace) if p.SkipMatching(dot) { p.Emit(ItemKeyDot, "") p.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(p *parsekit.P) parsekit.StateFn { p.SkipConsecutive(whitespace) if p.SkipMatching(equal) { p.Emit(ItemAssignment, "") p.SkipConsecutive(whitespace) return stateValue } return p.UnexpectedInput("a value assignment") }