Fix numbers parsing

This commit is contained in:
Thomas Pelletier
2013-02-24 21:59:18 +01:00
parent 89919c7041
commit 4198942e1a
5 changed files with 61 additions and 17 deletions
+7 -2
View File
@@ -199,7 +199,7 @@ func lexRvalue(l *lexer) stateFn {
case '\n': case '\n':
l.ignore() l.ignore()
l.pos += 1 l.pos += 1
l.emit(tokenEOF) /*l.emit(tokenEOF)*/
return lexVoid return lexVoid
} }
@@ -270,6 +270,7 @@ func lexComma(l *lexer) stateFn {
} }
func lexKey(l *lexer) stateFn { func lexKey(l *lexer) stateFn {
l.ignore()
for isAlpha(l.next()) { for isAlpha(l.next()) {
} }
l.backup() l.backup()
@@ -363,12 +364,16 @@ func lexNumber(l *lexer) stateFn {
next := l.next() next := l.next()
if next == '.' { point_seen = true if next == '.' { point_seen = true
} else if isDigit(next) { digit_seen = true } else if isDigit(next) { digit_seen = true
} else { break } } else {
l.backup()
break
}
} }
if !digit_seen { if !digit_seen {
return l.errorf("no digit in that number") return l.errorf("no digit in that number")
} }
fmt.Println("-->", l.input[l.pos:])
if point_seen { if point_seen {
l.emit(tokenFloat) l.emit(tokenFloat)
} else { } else {
+12
View File
@@ -218,3 +218,15 @@ func TestKeyEqualNumber(t *testing.T) {
token{tokenEOF, ""}, token{tokenEOF, ""},
}) })
} }
func TestMultiline(t *testing.T) {
testFlow(t, "foo = 42\nbar=21", []token{
token{tokenKey, "foo"},
token{tokenEqual, "="},
token{tokenInteger, "42"},
token{tokenKey, "bar"},
token{tokenEqual, "="},
token{tokenInteger, "21"},
token{tokenEOF, ""},
})
}
+8 -1
View File
@@ -73,6 +73,8 @@ func parseStart(p *parser) parserStateFn {
return parseGroup return parseGroup
case tokenKey: case tokenKey:
return parseAssign return parseAssign
case tokenEOF:
return nil
default: default:
panic("unexpected token") panic("unexpected token")
} }
@@ -95,7 +97,12 @@ func parseAssign(p *parser) parserStateFn {
key := p.getToken() key := p.getToken()
p.assume(tokenEqual) p.assume(tokenEqual)
value := parseRvalue(p) value := parseRvalue(p)
p.tree.Set(key.val, value) final_key := key.val
if p.currentGroup != "" {
final_key = p.currentGroup + "." + key.val
}
fmt.Println("Setting k:", final_key, "val:", value)
p.tree.Set(final_key, value)
return parseStart(p) return parseStart(p)
} }
+17 -10
View File
@@ -12,7 +12,7 @@ func assertTree(t *testing.T, tree *TomlTree, ref map[string]interface{}) {
} }
} }
func testCreateSubTree(t *testing.T) { func TestCreateSubTree(t *testing.T) {
tree := make(TomlTree) tree := make(TomlTree)
tree.createSubTree("a.b.c") tree.createSubTree("a.b.c")
tree.Set("a.b.c", 42) tree.Set("a.b.c", 42)
@@ -22,25 +22,32 @@ func testCreateSubTree(t *testing.T) {
} }
func testSimpleKV(t *testing.T) { func TestSimpleKV(t *testing.T) {
tree := Load("a = 42") tree := Load("a = 42")
assertTree(t, tree, map[string]interface{}{ assertTree(t, tree, map[string]interface{}{
"a": 42, "a": int64(42),
}) })
tree = Load("a = 42\nb = 21") tree = Load("a = 42\nb = 21")
assertTree(t, tree, map[string]interface{}{ assertTree(t, tree, map[string]interface{}{
"a": 42, "a": int64(42),
"b": 21, "b": int64(21),
}) })
} }
func testSimpleIntegers(t *testing.T) { func TestSimpleNumbers(t *testing.T) {
tree := Load("a = +42\nb = -21\nc = +4.2\nd = -2.1") tree := Load("a = +42\nb = -21\nc = +4.2\nd = -2.1")
assertTree(t, tree, map[string]interface{}{ assertTree(t, tree, map[string]interface{}{
"a": 42, "a": int64(42),
"b": -21, "b": int64(-21),
"c": 4.2, "c": float64(4.2),
"d": -4.2, "d": float64(-2.1),
}) })
} }
/*func TestSimpleDate(t *testing.T) {*/
/*tree := Load("a = 12")*/
/*assertTree(t, tree, map[string]interface{}{*/
/*"a": 42,*/
/*})*/
/*}*/
+17 -4
View File
@@ -9,6 +9,17 @@ import (
// This is the result of the parsing of a TOML file. // This is the result of the parsing of a TOML file.
type TomlTree map[string]interface{} type TomlTree map[string]interface{}
// Keys returns the keys of the toplevel tree.
// Warning: this is a costly operation.
func (t *TomlTree) Keys() []string {
keys := make([]string, 0)
mp := (map[string]interface{})(*t)
for k, _ := range mp {
keys = append(keys, k)
}
return keys
}
// Get an element from the tree. // Get an element from the tree.
// If the path described by the key does not exist, nil is returned. // If the path described by the key does not exist, nil is returned.
func (t *TomlTree) Get(key string) interface{} { func (t *TomlTree) Get(key string) interface{} {
@@ -32,11 +43,12 @@ func (t *TomlTree) Set(key string, value interface{}) {
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 {
(*subtree)[intermediate_key] = make(TomlTree) var new_tree TomlTree = make(TomlTree)
(*subtree)[intermediate_key] = &new_tree
} }
subtree = (*subtree)[intermediate_key].(*TomlTree) subtree = (*subtree)[intermediate_key].(*TomlTree)
} }
(*subtree)[keys[len(key) - 1]] = value (*subtree)[keys[len(keys) - 1]] = value
} }
// createSubTree takes a tree and a key andcreate the necessary intermediate // createSubTree takes a tree and a key andcreate the necessary intermediate
@@ -49,9 +61,10 @@ func (t *TomlTree) createSubTree(key string) {
for _, intermediate_key := range strings.Split(key, ".") { for _, intermediate_key := range strings.Split(key, ".") {
_, exists := (*subtree)[intermediate_key] _, exists := (*subtree)[intermediate_key]
if !exists { if !exists {
(*subtree)[intermediate_key] = make(TomlTree) var new_tree TomlTree = make(TomlTree)
(*subtree)[intermediate_key] = &new_tree
} }
subtree = (*subtree)[intermediate_key].(*TomlTree) subtree = ((*subtree)[intermediate_key]).(*TomlTree)
} }
} }