diff --git a/parse.go b/parse.go index 04ef562..4d9619a 100644 --- a/parse.go +++ b/parse.go @@ -15,20 +15,15 @@ func (e *errParse) Error() string { } type parser struct { - ast map[string]section + ast ast l *lexer tok token } func newParser(data []byte) *parser { p := parser{ - ast: map[string]section{ - "": section{ - name: "", - props: map[string]property{}, - }, - }, - l: lex(string(data)), + ast: newAST(), + l: lex(string(data)), } return &p } @@ -49,31 +44,17 @@ func (p *parser) parse() error { case tokenError: return &errParse{p.l.line, p.l.col, p.tok.val} case tokenSection: - var sec section - sec, ok := p.ast[p.tok.val] - if !ok { - sec = section{ - name: p.tok.val, - props: map[string]property{}, - } - } + sec := newSection(p.tok.val) if err := p.parseSection(&sec); err != nil { return err } - p.ast[sec.name] = sec + p.ast.addSection(sec) case tokenKey: - var prop property - prop, ok := p.ast[""].props[p.tok.val] - if !ok { - prop = property{ - key: p.tok.val, - val: []string{}, - } - } + prop := newProperty(p.tok.val) if err := p.parseProperty(&prop); err != nil { return err } - p.ast[""].props[prop.key] = prop + p.ast[""][0].addProperty(prop) } } } @@ -96,31 +77,17 @@ func (p *parser) parseSection(out *section) error { case tokenError: return &errParse{p.l.line, p.l.col, p.tok.val} case tokenKey: - var prop property - prop, ok := out.props[p.tok.val] - if !ok { - prop = property{ - key: p.tok.val, - val: []string{}, - } - } + prop := newProperty(p.tok.val) if err := p.parseProperty(&prop); err != nil { return err } - out.props[prop.key] = prop + out.addProperty(prop) case tokenSection: - var sec section - sec, ok := p.ast[p.tok.val] - if !ok { - sec = section{ - name: p.tok.val, - props: map[string]property{}, - } - } + sec := newSection(p.tok.val) if err := p.parseSection(&sec); err != nil { return err } - p.ast[sec.name] = sec + p.ast.addSection(sec) default: return nil } diff --git a/parse_test.go b/parse_test.go index 66feb82..43b8b1b 100644 --- a/parse_test.go +++ b/parse_test.go @@ -9,30 +9,34 @@ import ( func TestParse(t *testing.T) { tests := []struct { input string - want map[string]section + want ast }{ { input: "version=1.2.3\n\n[user]\nname=root\nshell=/bin/bash", - want: map[string]section{ - "": section{ - name: "", - props: map[string]property{ - "version": property{ - key: "version", - val: []string{"1.2.3"}, + want: ast{ + "": []section{ + section{ + name: "", + props: map[string]property{ + "version": property{ + key: "version", + val: []string{"1.2.3"}, + }, }, }, }, - "user": section{ - name: "user", - props: map[string]property{ - "name": property{ - key: "name", - val: []string{"root"}, - }, - "shell": property{ - key: "shell", - val: []string{"/bin/bash"}, + "user": []section{ + section{ + name: "user", + props: map[string]property{ + "name": property{ + key: "name", + val: []string{"root"}, + }, + "shell": property{ + key: "shell", + val: []string{"/bin/bash"}, + }, }, }, }, @@ -50,43 +54,49 @@ organization=Acme Widgets Inc. server=192.0.2.62 port=143 file="payroll.dat"`, - want: map[string]section{ - "": section{ - name: "", - props: map[string]property{ - "version": property{ - key: "version", - val: []string{"1.2.3"}, + want: ast{ + "": []section{ + section{ + name: "", + props: map[string]property{ + "version": property{ + key: "version", + val: []string{"1.2.3"}, + }, }, }, }, - "owner": section{ - name: "owner", - props: map[string]property{ - "name": property{ - key: "name", - val: []string{"John Doe"}, - }, - "organization": property{ - key: "organization", - val: []string{"Acme Widgets Inc."}, + "owner": []section{ + section{ + name: "owner", + props: map[string]property{ + "name": property{ + key: "name", + val: []string{"John Doe"}, + }, + "organization": property{ + key: "organization", + val: []string{"Acme Widgets Inc."}, + }, }, }, }, - "database": section{ - name: "database", - props: map[string]property{ - "server": property{ - key: "server", - val: []string{"192.0.2.62"}, - }, - "port": property{ - key: "port", - val: []string{"143"}, - }, - "file": property{ - key: "file", - val: []string{`"payroll.dat"`}, + "database": []section{ + section{ + name: "database", + props: map[string]property{ + "server": property{ + key: "server", + val: []string{"192.0.2.62"}, + }, + "port": property{ + key: "port", + val: []string{"143"}, + }, + "file": property{ + key: "file", + val: []string{`"payroll.dat"`}, + }, }, }, },