parser: add support for object type
This commit is contained in:
parent
4e690ec67d
commit
16d5eb5f08
10
ast/ast.go
10
ast/ast.go
@ -88,11 +88,11 @@ func (l *ListType) Add(node Node) {
|
|||||||
|
|
||||||
// ObjectType represents a HCL Object Type
|
// ObjectType represents a HCL Object Type
|
||||||
type ObjectType struct {
|
type ObjectType struct {
|
||||||
Lbrace token.Pos // position of "{"
|
Lbrace token.Pos // position of "{"
|
||||||
Rbrace token.Pos // position of "}"
|
Rbrace token.Pos // position of "}"
|
||||||
List []Node // the nodes in lexical order
|
List *ObjectList // the nodes in lexical order
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *ObjectType) Pos() token.Pos {
|
func (o *ObjectType) Pos() token.Pos {
|
||||||
return b.Lbrace
|
return o.Lbrace
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ func Walk(node Node, fn func(Node) bool) {
|
|||||||
Walk(l, fn)
|
Walk(l, fn)
|
||||||
}
|
}
|
||||||
case *ObjectType:
|
case *ObjectType:
|
||||||
for _, l := range n.List {
|
for _, l := range n.List.Items {
|
||||||
Walk(l, fn)
|
Walk(l, fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,10 @@ var errEofToken = errors.New("EOF token found")
|
|||||||
|
|
||||||
// Parse returns the fully parsed source and returns the abstract syntax tree.
|
// Parse returns the fully parsed source and returns the abstract syntax tree.
|
||||||
func (p *Parser) Parse() (ast.Node, error) {
|
func (p *Parser) Parse() (ast.Node, error) {
|
||||||
|
return p.parseObjectList()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parseObjectList() (*ast.ObjectList, error) {
|
||||||
defer un(trace(p, "ParseObjectList"))
|
defer un(trace(p, "ParseObjectList"))
|
||||||
node := &ast.ObjectList{}
|
node := &ast.ObjectList{}
|
||||||
|
|
||||||
@ -75,11 +79,11 @@ func (p *Parser) parseObjectItem() (*ast.ObjectItem, error) {
|
|||||||
case token.LBRACE:
|
case token.LBRACE:
|
||||||
if len(keys) > 1 {
|
if len(keys) > 1 {
|
||||||
// nested object
|
// nested object
|
||||||
fmt.Println("nested object")
|
panic("nested object is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// object
|
// object
|
||||||
fmt.Println("object")
|
panic("normal object is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("not yet implemented: %s", p.tok.Type)
|
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
|
// parseListType parses a list type and returns a ListType AST
|
||||||
func (p *Parser) parseListType() (*ast.ListType, error) {
|
func (p *Parser) parseListType() (*ast.ListType, error) {
|
||||||
defer un(trace(p, "ParseListType"))
|
defer un(trace(p, "ParseListType"))
|
||||||
|
|
||||||
|
// we assume that the currently scanned token is a LBRACK
|
||||||
l := &ast.ListType{
|
l := &ast.ListType{
|
||||||
Lbrack: p.tok.Pos,
|
Lbrack: p.tok.Pos,
|
||||||
}
|
}
|
||||||
@ -177,7 +204,9 @@ func (p *Parser) parseListType() (*ast.ListType, error) {
|
|||||||
case token.BOOL:
|
case token.BOOL:
|
||||||
// TODO(arslan) should we support? not supported by HCL yet
|
// TODO(arslan) should we support? not supported by HCL yet
|
||||||
case token.LBRACK:
|
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:
|
case token.RBRACK:
|
||||||
// finished
|
// finished
|
||||||
l.Rbrack = p.tok.Pos
|
l.Rbrack = p.tok.Pos
|
||||||
@ -198,13 +227,6 @@ func (p *Parser) parseLiteralType() (*ast.LiteralType, error) {
|
|||||||
}, nil
|
}, 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.
|
// scan returns the next token from the underlying scanner.
|
||||||
// If a token has been unscanned then read that instead.
|
// If a token has been unscanned then read that instead.
|
||||||
func (p *Parser) scan() token.Token {
|
func (p *Parser) scan() token.Token {
|
||||||
|
@ -12,7 +12,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestParseType(t *testing.T) {
|
func TestParseType(t *testing.T) {
|
||||||
src := `foo = ["fatih", "arslan", 1224]`
|
src := `foo = {
|
||||||
|
fatih = "true"
|
||||||
|
arslan = "deneme"
|
||||||
|
}`
|
||||||
|
|
||||||
p := New([]byte(src))
|
p := New([]byte(src))
|
||||||
p.enableTrace = true
|
p.enableTrace = true
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user