Handle dots in keys
This commit is contained in:
@@ -169,10 +169,6 @@ func lexVoid(l *lexer) stateFn {
|
|||||||
return lexEqual
|
return lexEqual
|
||||||
}
|
}
|
||||||
|
|
||||||
if isAlphanumeric(next) {
|
|
||||||
return lexKey
|
|
||||||
}
|
|
||||||
|
|
||||||
if isSpace(next) {
|
if isSpace(next) {
|
||||||
l.ignore()
|
l.ignore()
|
||||||
}
|
}
|
||||||
@@ -181,6 +177,10 @@ func lexVoid(l *lexer) stateFn {
|
|||||||
return lexRvalue
|
return lexRvalue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isKeyChar(next) {
|
||||||
|
return lexKey
|
||||||
|
}
|
||||||
|
|
||||||
if l.next() == eof {
|
if l.next() == eof {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,14 @@ func TestKeyWithSharpAndEqual(t *testing.T) {
|
|||||||
token{tokenEOF, ""},
|
token{tokenEOF, ""},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
func TestKeyWithSymbolsAndEqual(t *testing.T) {
|
||||||
|
testFlow(t, "~!@#$^&*()_+-`1234567890[]\\|/?><.,;:' = 5", []token{
|
||||||
|
token{tokenKey, "~!@#$^&*()_+-`1234567890[]\\|/?><.,;:'"},
|
||||||
|
token{tokenEqual, "="},
|
||||||
|
token{tokenInteger, "5"},
|
||||||
|
token{tokenEOF, ""},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestKeyEqualStringEscape(t *testing.T) {
|
func TestKeyEqualStringEscape(t *testing.T) {
|
||||||
testFlow(t, "foo = \"hello\\\"\"", []token{
|
testFlow(t, "foo = \"hello\\\"\"", []token{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ type parser struct {
|
|||||||
flow chan token
|
flow chan token
|
||||||
tree *TomlTree
|
tree *TomlTree
|
||||||
tokensBuffer []token
|
tokensBuffer []token
|
||||||
currentGroup string
|
currentGroup []string
|
||||||
seenGroupKeys []string
|
seenGroupKeys []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ func parseGroup(p *parser) parserStateFn {
|
|||||||
p.seenGroupKeys = append(p.seenGroupKeys, key.val)
|
p.seenGroupKeys = append(p.seenGroupKeys, key.val)
|
||||||
p.tree.createSubTree(key.val)
|
p.tree.createSubTree(key.val)
|
||||||
p.assume(tokenRightBracket)
|
p.assume(tokenRightBracket)
|
||||||
p.currentGroup = key.val
|
p.currentGroup = strings.Split(key.val, ".")
|
||||||
return parseStart(p)
|
return parseStart(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,14 +105,17 @@ func parseAssign(p *parser) parserStateFn {
|
|||||||
key := p.getToken()
|
key := p.getToken()
|
||||||
p.assume(tokenEqual)
|
p.assume(tokenEqual)
|
||||||
value := parseRvalue(p)
|
value := parseRvalue(p)
|
||||||
final_key := key.val
|
var final_key []string
|
||||||
if p.currentGroup != "" {
|
if len(p.currentGroup) > 0 {
|
||||||
final_key = p.currentGroup + "." + key.val
|
final_key = p.currentGroup
|
||||||
|
} else {
|
||||||
|
final_key = make([]string, 0)
|
||||||
}
|
}
|
||||||
if p.tree.Get(final_key) != nil {
|
final_key = append(final_key, key.val)
|
||||||
panic(fmt.Sprintf("the following key was defined twice: %s", final_key))
|
if p.tree.GetPath(final_key) != nil {
|
||||||
|
panic(fmt.Sprintf("the following key was defined twice: %s", strings.Join(final_key, ".")))
|
||||||
}
|
}
|
||||||
p.tree.Set(final_key, value)
|
p.tree.SetPath(final_key, value)
|
||||||
return parseStart(p)
|
return parseStart(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,8 +186,6 @@ func parseArray(p *parser) []interface{} {
|
|||||||
panic("unterminated array")
|
panic("unterminated array")
|
||||||
}
|
}
|
||||||
if follow.typ != tokenRightBracket && follow.typ != tokenComma {
|
if follow.typ != tokenRightBracket && follow.typ != tokenComma {
|
||||||
fmt.Println(follow.typ)
|
|
||||||
fmt.Println(follow.val)
|
|
||||||
panic("missing comma")
|
panic("missing comma")
|
||||||
}
|
}
|
||||||
if follow.typ == tokenComma {
|
if follow.typ == tokenComma {
|
||||||
@@ -199,7 +201,7 @@ func parse(flow chan token) *TomlTree {
|
|||||||
flow: flow,
|
flow: flow,
|
||||||
tree: &result,
|
tree: &result,
|
||||||
tokensBuffer: make([]token, 0),
|
tokensBuffer: make([]token, 0),
|
||||||
currentGroup: "",
|
currentGroup: make([]string, 0),
|
||||||
seenGroupKeys: make([]string, 0),
|
seenGroupKeys: make([]string, 0),
|
||||||
}
|
}
|
||||||
parser.run()
|
parser.run()
|
||||||
|
|||||||
@@ -42,8 +42,11 @@ func (t *TomlTree) Keys() []string {
|
|||||||
// Key is a dot-separated path (e.g. a.b.c).
|
// Key is a dot-separated path (e.g. a.b.c).
|
||||||
// Returns nil if the path does not exist in the tree.
|
// Returns nil if the path does not exist in the tree.
|
||||||
func (t *TomlTree) Get(key string) interface{} {
|
func (t *TomlTree) Get(key string) interface{} {
|
||||||
|
return t.GetPath(strings.Split(key, "."))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TomlTree) GetPath(keys []string) interface{} {
|
||||||
subtree := t
|
subtree := t
|
||||||
keys := strings.Split(key, ".")
|
|
||||||
for _, intermediate_key := range keys[:len(keys)-1] {
|
for _, intermediate_key := range keys[:len(keys)-1] {
|
||||||
_, exists := (*subtree)[intermediate_key]
|
_, exists := (*subtree)[intermediate_key]
|
||||||
if !exists {
|
if !exists {
|
||||||
@@ -67,8 +70,11 @@ func (t *TomlTree) GetDefault(key string, def interface{}) interface{} {
|
|||||||
// Key is a dot-separated path (e.g. a.b.c).
|
// Key is a dot-separated path (e.g. a.b.c).
|
||||||
// Creates all necessary intermediates trees, if needed.
|
// Creates all necessary intermediates trees, if needed.
|
||||||
func (t *TomlTree) Set(key string, value interface{}) {
|
func (t *TomlTree) Set(key string, value interface{}) {
|
||||||
|
t.SetPath(strings.Split(key, "."), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TomlTree) SetPath(keys []string, value interface{}) {
|
||||||
subtree := t
|
subtree := t
|
||||||
keys := strings.Split(key, ".")
|
|
||||||
for _, intermediate_key := range keys[:len(keys)-1] {
|
for _, intermediate_key := range keys[:len(keys)-1] {
|
||||||
_, exists := (*subtree)[intermediate_key]
|
_, exists := (*subtree)[intermediate_key]
|
||||||
if !exists {
|
if !exists {
|
||||||
|
|||||||
Reference in New Issue
Block a user