Accept spaces in keys
diff --git a/keysparsing.go b/keysparsing.go index 528f1de..7535379 100644 --- a/keysparsing.go +++ b/keysparsing.go
@@ -13,7 +13,16 @@ var buffer bytes.Buffer inQuotes := false escapeNext := false + ignoreSpace := true + expectDot := false + for _, char := range key { + if ignoreSpace { + if char == ' ' { + continue + } + ignoreSpace = false + } if escapeNext { buffer.WriteRune(char) escapeNext = false @@ -25,18 +34,31 @@ continue case '"': inQuotes = !inQuotes + expectDot = false case '.': if inQuotes { buffer.WriteRune(char) } else { groups = append(groups, buffer.String()) buffer.Reset() + ignoreSpace = true + expectDot = false + } + case ' ': + if inQuotes { + buffer.WriteRune(char) + } else { + expectDot = true } default: if !inQuotes && !isValidBareChar(char) { return nil, fmt.Errorf("invalid bare character: %c", char) } + if !inQuotes && expectDot { + return nil, fmt.Errorf("what?") + } buffer.WriteRune(char) + expectDot = false } } if inQuotes {
diff --git a/lexer_test.go b/lexer_test.go index d1cd130..05958fc 100644 --- a/lexer_test.go +++ b/lexer_test.go
@@ -39,6 +39,15 @@ }) } +func TestNestedQuotedUnicodeKeyGroup(t *testing.T) { + testFlow(t, `[ j . "ʞ" . l ]`, []token{ + token{Position{1, 1}, tokenLeftBracket, "["}, + token{Position{1, 2}, tokenKeyGroup, ` j . "ʞ" . l `}, + token{Position{1, 15}, tokenRightBracket, "]"}, + token{Position{1, 16}, tokenEOF, ""}, + }) +} + func TestUnclosedKeyGroup(t *testing.T) { testFlow(t, "[hello world", []token{ token{Position{1, 1}, tokenLeftBracket, "["},
diff --git a/parser_test.go b/parser_test.go index 2998913..6672c06 100644 --- a/parser_test.go +++ b/parser_test.go
@@ -157,6 +157,41 @@ }) } +func TestNestedQuotedUnicodeKeys(t *testing.T) { + tree, err := Load("[ j . \"ʞ\" . l ]\nd = 42") + assertTree(t, tree, err, map[string]interface{}{ + "j": map[string]interface{}{ + "ʞ": map[string]interface{}{ + "l": map[string]interface{}{ + "d": int64(42), + }, + }, + }, + }) + + tree, err = Load("[ g . h . i ]\nd = 42") + assertTree(t, tree, err, map[string]interface{}{ + "g": map[string]interface{}{ + "h": map[string]interface{}{ + "i": map[string]interface{}{ + "d": int64(42), + }, + }, + }, + }) + + tree, err = Load("[ d.e.f ]\nk = 42") + assertTree(t, tree, err, map[string]interface{}{ + "d": map[string]interface{}{ + "e": map[string]interface{}{ + "f": map[string]interface{}{ + "k": int64(42), + }, + }, + }, + }) +} + func TestArrayOne(t *testing.T) { tree, err := Load("a = [1]") assertTree(t, tree, err, map[string]interface{}{