Array implementation
This commit is contained in:
@@ -27,6 +27,9 @@ type builder interface {
|
|||||||
Dot(b []byte)
|
Dot(b []byte)
|
||||||
Boolean(b []byte)
|
Boolean(b []byte)
|
||||||
Equal(b []byte)
|
Equal(b []byte)
|
||||||
|
ArrayBegin()
|
||||||
|
ArrayEnd()
|
||||||
|
ArraySeparator()
|
||||||
}
|
}
|
||||||
|
|
||||||
type position struct {
|
type position struct {
|
||||||
@@ -38,6 +41,18 @@ type documentBuilder struct {
|
|||||||
document Document
|
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) {
|
func (d *documentBuilder) Equal(b []byte) {
|
||||||
s := string(b)
|
s := string(b)
|
||||||
fmt.Printf("EQUAL: '%s'\n", s)
|
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 {
|
func (p *parser) parseExpression() error {
|
||||||
err := p.parseWhitespace()
|
err := p.parseWhitespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -325,11 +356,104 @@ func (p *parser) parseVal() error {
|
|||||||
return p.parseBool()
|
return p.parseBool()
|
||||||
case '\'', '"':
|
case '\'', '"':
|
||||||
return p.parseString()
|
return p.parseString()
|
||||||
|
case '[':
|
||||||
|
return p.parseArray()
|
||||||
// TODO
|
// TODO
|
||||||
default:
|
default:
|
||||||
return &InvalidCharacter{r: r}
|
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 {
|
func (p *parser) parseString() error {
|
||||||
r := p.peek()
|
r := p.peek()
|
||||||
|
|
||||||
|
|||||||
+16
-23
@@ -24,6 +24,11 @@ var inputs = []string{
|
|||||||
`a."b".c = true`,
|
`a."b".c = true`,
|
||||||
`a = "foo"`,
|
`a = "foo"`,
|
||||||
`b = 'sample thingy'`,
|
`b = 'sample thingy'`,
|
||||||
|
`a = []`,
|
||||||
|
`b = ["foo"]`,
|
||||||
|
`c = [[[]]]`,
|
||||||
|
`d = ["foo","bar"]`,
|
||||||
|
`d = ["foo", "test"]`,
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParse(t *testing.T) {
|
||||||
@@ -40,29 +45,17 @@ func TestParse(t *testing.T) {
|
|||||||
type noopBuilder struct {
|
type noopBuilder struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n noopBuilder) Whitespace(b []byte) {
|
func (n noopBuilder) ArraySeparator() {}
|
||||||
}
|
func (n noopBuilder) ArrayBegin() {}
|
||||||
|
func (n noopBuilder) ArrayEnd() {}
|
||||||
func (n noopBuilder) Comment(b []byte) {
|
func (n noopBuilder) Whitespace(b []byte) {}
|
||||||
}
|
func (n noopBuilder) Comment(b []byte) {}
|
||||||
|
func (n noopBuilder) UnquotedKey(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) LiteralString(b []byte) {
|
func (n noopBuilder) Boolean(b []byte) {}
|
||||||
}
|
func (n noopBuilder) Equal(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) {
|
func BenchmarkParseAll(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
|||||||
Reference in New Issue
Block a user