From 16d5eb5f08c90f51076f8d91062e5dbcef4fdf09 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Sat, 17 Oct 2015 01:14:40 +0300 Subject: [PATCH] parser: add support for object type --- ast/ast.go | 10 +++++----- ast/walk.go | 2 +- parser/parser.go | 42 ++++++++++++++++++++++++++++++++---------- parser/parser_test.go | 6 +++++- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index b0d8251..c234e5b 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -88,11 +88,11 @@ func (l *ListType) Add(node Node) { // ObjectType represents a HCL Object Type type ObjectType struct { - Lbrace token.Pos // position of "{" - Rbrace token.Pos // position of "}" - List []Node // the nodes in lexical order + Lbrace token.Pos // position of "{" + Rbrace token.Pos // position of "}" + List *ObjectList // the nodes in lexical order } -func (b *ObjectType) Pos() token.Pos { - return b.Lbrace +func (o *ObjectType) Pos() token.Pos { + return o.Lbrace } diff --git a/ast/walk.go b/ast/walk.go index c015a67..f198c3f 100644 --- a/ast/walk.go +++ b/ast/walk.go @@ -27,7 +27,7 @@ func Walk(node Node, fn func(Node) bool) { Walk(l, fn) } case *ObjectType: - for _, l := range n.List { + for _, l := range n.List.Items { Walk(l, fn) } } diff --git a/parser/parser.go b/parser/parser.go index d007578..b9c128a 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -30,6 +30,10 @@ var errEofToken = errors.New("EOF token found") // Parse returns the fully parsed source and returns the abstract syntax tree. func (p *Parser) Parse() (ast.Node, error) { + return p.parseObjectList() +} + +func (p *Parser) parseObjectList() (*ast.ObjectList, error) { defer un(trace(p, "ParseObjectList")) node := &ast.ObjectList{} @@ -75,11 +79,11 @@ func (p *Parser) parseObjectItem() (*ast.ObjectItem, error) { case token.LBRACE: if len(keys) > 1 { // nested object - fmt.Println("nested object") + panic("nested object is not implemented") } // object - fmt.Println("object") + panic("normal object is not implemented") } return nil, fmt.Errorf("not yet implemented: %s", p.tok.Type) @@ -154,10 +158,33 @@ func (p *Parser) parseObjectKey() ([]*ast.ObjectKey, error) { } } +// parseObjectType parses an object type and returns a ObjectType AST +func (p *Parser) parseObjectType() (*ast.ObjectType, error) { + defer un(trace(p, "ParseObjectType")) + + // we assume that the currently scanned token is a LBRACE + o := &ast.ObjectType{ + Lbrace: p.tok.Pos, + } + + l, err := p.parseObjectList() + + // if we hit RBRACE, we are good to go (means we parsed all Items), if it's + // not a RBRACE, it's an syntax error and we just return it. + if err != nil && p.tok.Type != token.RBRACE { + return nil, err + } + + o.List = l + o.Rbrace = p.tok.Pos // advanced via parseObjectList + return o, nil +} + // parseListType parses a list type and returns a ListType AST func (p *Parser) parseListType() (*ast.ListType, error) { defer un(trace(p, "ParseListType")) + // we assume that the currently scanned token is a LBRACK l := &ast.ListType{ Lbrack: p.tok.Pos, } @@ -177,7 +204,9 @@ func (p *Parser) parseListType() (*ast.ListType, error) { case token.BOOL: // TODO(arslan) should we support? not supported by HCL yet case token.LBRACK: - // TODO(arslan) should we support nested lists? + // TODO(arslan) should we support nested lists? Even though it's + // written in README of HCL, it's not a parse of the grammar + // (defined in parse.y) case token.RBRACK: // finished l.Rbrack = p.tok.Pos @@ -198,13 +227,6 @@ func (p *Parser) parseLiteralType() (*ast.LiteralType, error) { }, nil } -// parseObjectType parses an object type and returns a ObjectType AST -func (p *Parser) parseObjectType() (*ast.ObjectType, error) { - defer un(trace(p, "ParseObjectYpe")) - - return nil, errors.New("ObjectType is not implemented yet") -} - // scan returns the next token from the underlying scanner. // If a token has been unscanned then read that instead. func (p *Parser) scan() token.Token { diff --git a/parser/parser_test.go b/parser/parser_test.go index 437c254..ddade4b 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -12,7 +12,11 @@ import ( ) func TestParseType(t *testing.T) { - src := `foo = ["fatih", "arslan", 1224]` + src := `foo = { + fatih = "true" + arslan = "deneme" +}` + p := New([]byte(src)) p.enableTrace = true