Array implementation
This commit is contained in:
@@ -27,6 +27,9 @@ type builder interface {
|
||||
Dot(b []byte)
|
||||
Boolean(b []byte)
|
||||
Equal(b []byte)
|
||||
ArrayBegin()
|
||||
ArrayEnd()
|
||||
ArraySeparator()
|
||||
}
|
||||
|
||||
type position struct {
|
||||
@@ -38,6 +41,18 @@ type documentBuilder struct {
|
||||
document Document
|
||||
}
|
||||
|
||||
func (d *documentBuilder) ArraySeparator() {
|
||||
fmt.Println(", ARRAY SEPARATOR")
|
||||
}
|
||||
|
||||
func (d *documentBuilder) ArrayBegin() {
|
||||
fmt.Println("[ ARRAY BEGIN")
|
||||
}
|
||||
|
||||
func (d *documentBuilder) ArrayEnd() {
|
||||
fmt.Println("] ARRAY END")
|
||||
}
|
||||
|
||||
func (d *documentBuilder) Equal(b []byte) {
|
||||
s := string(b)
|
||||
fmt.Printf("EQUAL: '%s'\n", s)
|
||||
@@ -243,6 +258,22 @@ func (p *parser) parse() error {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseRequiredNewline() error {
|
||||
r := p.next()
|
||||
switch r {
|
||||
case '\n':
|
||||
p.ignore()
|
||||
return nil
|
||||
case '\r':
|
||||
r = p.next()
|
||||
if r == '\n' {
|
||||
p.ignore()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return &InvalidCharacter{r: r}
|
||||
}
|
||||
|
||||
func (p *parser) parseExpression() error {
|
||||
err := p.parseWhitespace()
|
||||
if err != nil {
|
||||
@@ -325,11 +356,104 @@ func (p *parser) parseVal() error {
|
||||
return p.parseBool()
|
||||
case '\'', '"':
|
||||
return p.parseString()
|
||||
case '[':
|
||||
return p.parseArray()
|
||||
// TODO
|
||||
default:
|
||||
return &InvalidCharacter{r: r}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseArray() error {
|
||||
//array = array-open [ array-values ] ws-comment-newline array-close
|
||||
|
||||
err := p.expect('[')
|
||||
if err != nil {
|
||||
panic("arrays should start with [")
|
||||
}
|
||||
|
||||
p.builder.ArrayBegin()
|
||||
|
||||
err = p.parseWhitespaceCommentNewline()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := p.peek()
|
||||
|
||||
if r == ']' {
|
||||
p.next()
|
||||
p.ignore()
|
||||
p.builder.ArrayEnd()
|
||||
return nil
|
||||
}
|
||||
|
||||
err = p.parseVal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
err = p.parseWhitespaceCommentNewline()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := p.peek()
|
||||
|
||||
if r == ']' {
|
||||
p.next()
|
||||
p.ignore()
|
||||
p.builder.ArrayEnd()
|
||||
return nil
|
||||
}
|
||||
|
||||
err := p.expect(',')
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.builder.ArraySeparator()
|
||||
p.ignore()
|
||||
|
||||
err = p.parseWhitespaceCommentNewline()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = p.parseVal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseWhitespaceCommentNewline() error {
|
||||
// ws-comment-newline = *( wschar / ([ comment ] newline) )
|
||||
|
||||
for {
|
||||
if isWhitespace(p.peek()) {
|
||||
err := p.parseWhitespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if p.peek() == '#' {
|
||||
err := p.parseComment()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
r := p.peek()
|
||||
if r != '\n' && r != '\r' {
|
||||
return nil
|
||||
}
|
||||
err := p.parseRequiredNewline()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseString() error {
|
||||
r := p.peek()
|
||||
|
||||
|
||||
+16
-23
@@ -24,6 +24,11 @@ var inputs = []string{
|
||||
`a."b".c = true`,
|
||||
`a = "foo"`,
|
||||
`b = 'sample thingy'`,
|
||||
`a = []`,
|
||||
`b = ["foo"]`,
|
||||
`c = [[[]]]`,
|
||||
`d = ["foo","bar"]`,
|
||||
`d = ["foo", "test"]`,
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
@@ -40,29 +45,17 @@ func TestParse(t *testing.T) {
|
||||
type noopBuilder struct {
|
||||
}
|
||||
|
||||
func (n noopBuilder) Whitespace(b []byte) {
|
||||
}
|
||||
|
||||
func (n noopBuilder) Comment(b []byte) {
|
||||
}
|
||||
|
||||
func (n noopBuilder) UnquotedKey(b []byte) {
|
||||
}
|
||||
|
||||
func (n noopBuilder) LiteralString(b []byte) {
|
||||
}
|
||||
|
||||
func (n noopBuilder) BasicString(b []byte) {
|
||||
}
|
||||
|
||||
func (n noopBuilder) Dot(b []byte) {
|
||||
}
|
||||
|
||||
func (n noopBuilder) Boolean(b []byte) {
|
||||
}
|
||||
|
||||
func (n noopBuilder) Equal(b []byte) {
|
||||
}
|
||||
func (n noopBuilder) ArraySeparator() {}
|
||||
func (n noopBuilder) ArrayBegin() {}
|
||||
func (n noopBuilder) ArrayEnd() {}
|
||||
func (n noopBuilder) Whitespace(b []byte) {}
|
||||
func (n noopBuilder) Comment(b []byte) {}
|
||||
func (n noopBuilder) UnquotedKey(b []byte) {}
|
||||
func (n noopBuilder) LiteralString(b []byte) {}
|
||||
func (n noopBuilder) BasicString(b []byte) {}
|
||||
func (n noopBuilder) Dot(b []byte) {}
|
||||
func (n noopBuilder) Boolean(b []byte) {}
|
||||
func (n noopBuilder) Equal(b []byte) {}
|
||||
|
||||
func BenchmarkParseAll(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
Reference in New Issue
Block a user