Fix parsing bugs + boolean impl
This commit is contained in:
+22
-3
@@ -23,6 +23,25 @@ var scanFollowsFalse = scanFollows([]byte{'f', 'a', 'l', 's', 'e'})
|
||||
var scanFollowsArrayTableBegin = scanFollows([]byte{arrayOrTableBegin, arrayOrTableBegin})
|
||||
var scanFollowsArrayTableEnd = scanFollows([]byte{arrayOrTableEnd, arrayOrTableEnd})
|
||||
|
||||
func scanNewline(b []byte) ([]byte, []byte, error) {
|
||||
if len(b) == 0 {
|
||||
return nil, nil, fmt.Errorf("not enough bytes for new line")
|
||||
}
|
||||
if b[0] == '\n' {
|
||||
return b[:1], b[1:], nil
|
||||
}
|
||||
if b[0] == '\r' {
|
||||
if len(b) < 2 {
|
||||
return nil, nil, fmt.Errorf("not enough bytes for windows newline")
|
||||
}
|
||||
if b[1] == '\n' {
|
||||
return b[:2], b[2:], nil
|
||||
}
|
||||
return nil, nil, unexpectedCharacter{r: '\n', b: b[2:]}
|
||||
}
|
||||
return nil, nil, unexpectedCharacter{b: b}
|
||||
}
|
||||
|
||||
const (
|
||||
dot = '.'
|
||||
equal = '='
|
||||
@@ -94,7 +113,7 @@ func scan(b []byte) ([]byte, []byte, error) {
|
||||
|
||||
func scanUnquotedKey(b []byte) ([]byte, []byte, error) {
|
||||
//unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _
|
||||
for i := 1; i < len(b); i++ {
|
||||
for i := 0; i < len(b); i++ {
|
||||
if !isUnquotedKeyChar(b[i]) {
|
||||
return b[:i], b[i:], nil
|
||||
}
|
||||
@@ -153,7 +172,7 @@ func scanWindowsNewline(b []byte) ([]byte, []byte, error) {
|
||||
}
|
||||
|
||||
func scanWhitespace(b []byte) ([]byte, []byte) {
|
||||
for i := 1; i < len(b); i++ {
|
||||
for i := 0; i < len(b); i++ {
|
||||
switch b[i] {
|
||||
case ' ', '\t':
|
||||
continue
|
||||
@@ -176,7 +195,7 @@ func scanComment(b []byte) ([]byte, []byte, error) {
|
||||
for i := 1; i < len(b); i++ {
|
||||
switch b[i] {
|
||||
case '\n':
|
||||
return b[:i+1], b[i+1:], nil
|
||||
return b[:i], b[i:], nil
|
||||
}
|
||||
}
|
||||
return b, nil, nil
|
||||
|
||||
@@ -51,12 +51,20 @@ func parseExpression(b []byte) ([]byte, error) {
|
||||
_, rest, err := scanComment(b)
|
||||
return rest, err
|
||||
}
|
||||
if b[0] == '\n' || b[0] == '\r' {
|
||||
_, rest, err := scanNewline(b)
|
||||
return rest, err
|
||||
}
|
||||
|
||||
var err error
|
||||
if b[0] == '[' {
|
||||
// TODO: parse 'table'
|
||||
panic("todo")
|
||||
} else {
|
||||
rest, err := parseKeyval(b)
|
||||
return rest, err
|
||||
b, err = parseKeyval(b)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b = parseWhitespace(b)
|
||||
@@ -107,11 +115,20 @@ func parseVal(b []byte) ([]byte, error) {
|
||||
case '\'':
|
||||
if scanFollowsMultilineLiteralStringDelimiter(b) {
|
||||
_, b, err = parseMultilineLiteralString(b)
|
||||
} else {
|
||||
_, b, err = scanLiteralString(b)
|
||||
}
|
||||
_, b, err = scanLiteralString(b)
|
||||
return b, err
|
||||
// TODO boolean
|
||||
|
||||
case 't':
|
||||
if !scanFollowsTrue(b) {
|
||||
return nil, fmt.Errorf("expected 'true'")
|
||||
}
|
||||
return b[4:], nil
|
||||
case 'f':
|
||||
if !scanFollowsFalse(b) {
|
||||
return nil, fmt.Errorf("expected 'false'")
|
||||
}
|
||||
return b[5:], nil
|
||||
// TODO array
|
||||
|
||||
// TODO inline-table
|
||||
@@ -247,8 +264,8 @@ func parseKey(b []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
for {
|
||||
if len(b) > 0 && (b[0] == '.' || isWhitespace(b[0])) {
|
||||
b = parseWhitespace(b)
|
||||
b = parseWhitespace(b)
|
||||
if len(b) > 0 && b[0] == '.' {
|
||||
b, err = expect('.', b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -266,10 +283,6 @@ func parseKey(b []byte) ([]byte, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func isWhitespace(b byte) bool {
|
||||
return b == ' ' || b == '\t'
|
||||
}
|
||||
|
||||
func parseSimpleKey(b []byte) ([]byte, error) {
|
||||
//simple-key = quoted-key / unquoted-key
|
||||
//unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _
|
||||
|
||||
+22
-22
@@ -35,7 +35,7 @@ var inputs = []string{
|
||||
`[ test ]`,
|
||||
`[ "hello".world ]`,
|
||||
`[test]
|
||||
a = false`,
|
||||
a = false`,
|
||||
`[[foo]]`,
|
||||
}
|
||||
|
||||
@@ -66,27 +66,27 @@ func TestParse(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type noopParser struct {
|
||||
}
|
||||
|
||||
func (n noopParser) ArrayTableBegin() {}
|
||||
func (n noopParser) ArrayTableEnd() {}
|
||||
func (n noopParser) StandardTableBegin() {}
|
||||
func (n noopParser) StandardTableEnd() {}
|
||||
func (n noopParser) InlineTableSeparator() {}
|
||||
func (n noopParser) InlineTableBegin() {}
|
||||
func (n noopParser) InlineTableEnd() {}
|
||||
func (n noopParser) ArraySeparator() {}
|
||||
func (n noopParser) ArrayBegin() {}
|
||||
func (n noopParser) ArrayEnd() {}
|
||||
func (n noopParser) Whitespace(b []byte) {}
|
||||
func (n noopParser) Comment(b []byte) {}
|
||||
func (n noopParser) UnquotedKey(b []byte) {}
|
||||
func (n noopParser) LiteralString(b []byte) {}
|
||||
func (n noopParser) BasicString(b []byte) {}
|
||||
func (n noopParser) Dot(b []byte) {}
|
||||
func (n noopParser) Boolean(b []byte) {}
|
||||
func (n noopParser) Equal(b []byte) {}
|
||||
//type noopParser struct {
|
||||
//}
|
||||
//
|
||||
//func (n noopParser) ArrayTableBegin() {}
|
||||
//func (n noopParser) ArrayTableEnd() {}
|
||||
//func (n noopParser) StandardTableBegin() {}
|
||||
//func (n noopParser) StandardTableEnd() {}
|
||||
//func (n noopParser) InlineTableSeparator() {}
|
||||
//func (n noopParser) InlineTableBegin() {}
|
||||
//func (n noopParser) InlineTableEnd() {}
|
||||
//func (n noopParser) ArraySeparator() {}
|
||||
//func (n noopParser) ArrayBegin() {}
|
||||
//func (n noopParser) ArrayEnd() {}
|
||||
//func (n noopParser) Whitespace(b []byte) {}
|
||||
//func (n noopParser) Comment(b []byte) {}
|
||||
//func (n noopParser) UnquotedKey(b []byte) {}
|
||||
//func (n noopParser) LiteralString(b []byte) {}
|
||||
//func (n noopParser) BasicString(b []byte) {}
|
||||
//func (n noopParser) Dot(b []byte) {}
|
||||
//func (n noopParser) Boolean(b []byte) {}
|
||||
//func (n noopParser) Equal(b []byte) {}
|
||||
|
||||
//
|
||||
//func BenchmarkParseAll(b *testing.B) {
|
||||
|
||||
Reference in New Issue
Block a user