Fix parsing bugs + boolean impl

This commit is contained in:
Thomas Pelletier
2021-02-06 08:54:40 -05:00
parent a466f0ca79
commit 540c2a7b59
3 changed files with 68 additions and 36 deletions
+22 -3
View File
@@ -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
+24 -11
View File
@@ -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
View File
@@ -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) {