Array implementation

This commit is contained in:
Thomas Pelletier
2021-02-01 21:25:20 -05:00
parent 91d7afbc0a
commit bac65cc530
2 changed files with 140 additions and 23 deletions
+124
View File
@@ -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
View File
@@ -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()