Composition over inheritance, why didn't I do that in the first place I wonder.

This commit is contained in:
Maurice Makaay 2019-06-28 08:34:35 +00:00
parent febe1ff568
commit ec3a47da8d
4 changed files with 14 additions and 18 deletions

View File

@ -25,7 +25,7 @@ func testParse(t *testing.T, p *parser, handler parse.Handler, test parseTest) {
} else if err != nil && test.expectedError != err.Error() { } else if err != nil && test.expectedError != err.Error() {
t.Errorf("Unexpected error for input %q:\nexpected: %s\nactual: %s\n", test.input, test.expectedError, err.Error()) t.Errorf("Unexpected error for input %q:\nexpected: %s\nactual: %s\n", test.input, test.expectedError, err.Error())
} else { } else {
result := p.Root.String() result := p.doc.Root.String()
if test.expected != result { if test.expected != result {
t.Errorf("Unexpected result for input %q:\nexpected: %s\nactual: %s\n", test.input, test.expected, result) t.Errorf("Unexpected result for input %q:\nexpected: %s\nactual: %s\n", test.input, test.expected, result)
} }

View File

@ -38,7 +38,7 @@ func (t *parser) startKeyValuePair(p *parse.API) {
key, ok := t.parseKey(p, []string{}) key, ok := t.parseKey(p, []string{})
if ok && p.Handle(t.startAssignment) { if ok && p.Handle(t.startAssignment) {
if value, ok := t.parseValue(p); ok { if value, ok := t.parseValue(p); ok {
err := t.SetKeyValuePair(key, value) err := t.doc.SetKeyValuePair(key, value)
if err != nil { if err != nil {
p.Error("%s", err) p.Error("%s", err)
} else if !p.Accept(endOfLineOrComment) { } else if !p.Accept(endOfLineOrComment) {

View File

@ -35,13 +35,8 @@ var (
optionalWhitespaceOrComment = c.ZeroOrMore(whitespaceOrComment) optionalWhitespaceOrComment = c.ZeroOrMore(whitespaceOrComment)
) )
// parser embeds the TOML ast.Document, so it can be extended with methods
// that implement the parsing logic. This makes the ast.Document part of
// the state of the parser, making it possible to let parsing code call
// ast.Document methods directly to build the abstract syntax tree for the
// parsed TOML input.
type parser struct { type parser struct {
*ast.Document doc *ast.Document
} }
func newParser() *parser { func newParser() *parser {
@ -52,13 +47,14 @@ func newParser() *parser {
// Run the TOML parser against the provided input data. // Run the TOML parser against the provided input data.
// //
// For an overview of allowed inputs, take a look at the documentation for // For an overview of allowed inputs, take a look at the documentation for
// parsekit.read.New(). // parsekit.read.New(). At the time of writing, you can make use of
// strings, types implementing io.Reader and bufio.Readers.
// //
// This function returns a TOML ast structure and an error (or nil when // This function returns a TOML abstract syntax table structure and an
// no error occurred). When an error occurred, the TOML ast struct will // error (or nil when no error occurred). When an error occurred, the
// contain the data that could be parsed up to the error. // TOML ast struct will contain the data that could be parsed up to the error.
func Run(input interface{}) (ast.Table, error) { func Run(input interface{}) (ast.Table, error) {
p := newParser() p := newParser()
err := parse.New(p.startDocument)(input) err := parse.New(p.startDocument)(input)
return p.Root, err return p.doc.Root, err
} }

View File

@ -79,7 +79,7 @@ func (t *parser) startArrayOfTables(p *parse.API) {
p.Expected("end of line or comment") p.Expected("end of line or comment")
return return
} }
if err := t.OpenArrayOfTables(key); err != nil { if err := t.doc.OpenArrayOfTables(key); err != nil {
p.Error("%s", err) p.Error("%s", err)
return return
} }
@ -135,7 +135,7 @@ func (t *parser) startPlainTable(p *parse.API) {
p.Expected("end of line or comment") p.Expected("end of line or comment")
return return
} }
if err := t.OpenTable(key); err != nil { if err := t.doc.OpenTable(key); err != nil {
p.Error("%s", err) p.Error("%s", err)
return return
} }
@ -170,7 +170,7 @@ func (t *parser) parseInlineTable(p *parse.API) (*ast.Value, bool) {
// Check for an empty inline table. // Check for an empty inline table.
if p.Accept(inlineTableClose) { if p.Accept(inlineTableClose) {
return ast.NewValue(ast.TypeTable, subdoc.Root), true return ast.NewValue(ast.TypeTable, subdoc.doc.Root), true
} }
// Not an empty table, parse the table data. // Not an empty table, parse the table data.
@ -186,7 +186,7 @@ func (t *parser) parseInlineTable(p *parse.API) (*ast.Value, bool) {
if !ok { if !ok {
return nil, false return nil, false
} }
err := subdoc.SetKeyValuePair(key, value) err := subdoc.doc.SetKeyValuePair(key, value)
if err != nil { if err != nil {
p.Error("%s", err) p.Error("%s", err)
return nil, false return nil, false
@ -194,7 +194,7 @@ func (t *parser) parseInlineTable(p *parse.API) (*ast.Value, bool) {
// Check for the end of the inline table. // Check for the end of the inline table.
if p.Accept(inlineTableClose) { if p.Accept(inlineTableClose) {
return ast.NewValue(ast.TypeTable, subdoc.Root), true return ast.NewValue(ast.TypeTable, subdoc.doc.Root), true
} }
// Not the end of the inline table? Then we should find a key/value pair separator. // Not the end of the inline table? Then we should find a key/value pair separator.