parser: implement parsing assignments, stil wip
This commit is contained in:
parent
82c5032a95
commit
99099cda62
@ -14,32 +14,54 @@ const (
|
||||
Object
|
||||
)
|
||||
|
||||
// Node is an element in the abstract syntax tree.
|
||||
// Node is an element in the abstract syntax tree.
|
||||
type Node interface {
|
||||
node()
|
||||
String() string
|
||||
Pos() scanner.Pos
|
||||
}
|
||||
|
||||
func (Source) node() {}
|
||||
func (IdentStatement) node() {}
|
||||
func (BlockStatement) node() {}
|
||||
func (AssignStatement) node() {}
|
||||
func (ListStatement) node() {}
|
||||
func (ObjectStatement) node() {}
|
||||
|
||||
// Source represents a single HCL source file
|
||||
type Source struct {
|
||||
nodes []Node
|
||||
}
|
||||
|
||||
func (s Source) add(node Node) {
|
||||
s.nodes = append(s.nodes, node)
|
||||
}
|
||||
|
||||
func (s Source) String() string {
|
||||
buf := ""
|
||||
for _, n := range s.nodes {
|
||||
buf += n.String()
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
func (s Source) Pos() scanner.Pos {
|
||||
// always returns the uninitiliazed position
|
||||
return scanner.Pos{}
|
||||
}
|
||||
|
||||
// IdentStatement represents an identifier.
|
||||
type IdentStatement struct {
|
||||
pos scanner.Pos // position of the literal
|
||||
token scanner.Token
|
||||
value string
|
||||
}
|
||||
|
||||
func (i IdentStatement) String() string {
|
||||
return i.value
|
||||
return i.token.String()
|
||||
}
|
||||
|
||||
func (i IdentStatement) Pos() scanner.Pos {
|
||||
return i.pos
|
||||
return i.token.Pos()
|
||||
}
|
||||
|
||||
type BlockStatement struct {
|
||||
|
@ -3,11 +3,12 @@ package parser
|
||||
import "github.com/fatih/hcl/scanner"
|
||||
|
||||
type Parser struct {
|
||||
sc *scanner.Scanner
|
||||
buf struct {
|
||||
tok scanner.Token // last read token
|
||||
n int // buffer size (max = 1)
|
||||
}
|
||||
sc *scanner.Scanner
|
||||
|
||||
tok scanner.Token // last read token
|
||||
prevTok scanner.Token // previous read token
|
||||
|
||||
n int // buffer size (max = 1)
|
||||
}
|
||||
|
||||
func NewParser(src []byte) *Parser {
|
||||
@ -16,33 +17,81 @@ func NewParser(src []byte) *Parser {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse returns the fully parsed source and returns the abstract syntax tree.
|
||||
func (p *Parser) Parse() Node {
|
||||
tok := p.scan()
|
||||
|
||||
node := Source{}
|
||||
|
||||
switch tok.Type() {
|
||||
case scanner.IDENT:
|
||||
// p.parseStatement()
|
||||
n := p.parseStatement()
|
||||
node.add(n)
|
||||
case scanner.EOF:
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (p *Parser) parseStatement() Node {
|
||||
tok := p.scan()
|
||||
|
||||
if tok.Type().IsLiteral() {
|
||||
return p.parseIdent()
|
||||
}
|
||||
|
||||
switch tok.Type() {
|
||||
case scanner.LBRACE:
|
||||
return p.parseObject()
|
||||
case scanner.LBRACK:
|
||||
return p.parseList()
|
||||
case scanner.ASSIGN:
|
||||
return p.parseAssignment()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseIdent() Node {
|
||||
return IdentStatement{
|
||||
token: p.tok,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseObject() Node {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseList() Node {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAssignment() Node {
|
||||
return AssignStatement{
|
||||
lhs: IdentStatement{
|
||||
token: p.prevTok,
|
||||
},
|
||||
assign: p.tok.Pos(),
|
||||
rhs: p.parseStatement(),
|
||||
}
|
||||
}
|
||||
|
||||
// scan returns the next token from the underlying scanner.
|
||||
// If a token has been unscanned then read that instead.
|
||||
func (p *Parser) scan() scanner.Token {
|
||||
// If we have a token on the buffer, then return it.
|
||||
if p.buf.n != 0 {
|
||||
p.buf.n = 0
|
||||
return p.buf.tok
|
||||
if p.n != 0 {
|
||||
p.n = 0
|
||||
return p.tok
|
||||
}
|
||||
|
||||
// store previous token
|
||||
p.prevTok = p.tok
|
||||
|
||||
// Otherwise read the next token from the scanner and Save it to the buffer
|
||||
// in case we unscan later.
|
||||
p.buf.tok = p.sc.Scan()
|
||||
|
||||
return p.buf.tok
|
||||
p.tok = p.sc.Scan()
|
||||
return p.tok
|
||||
}
|
||||
|
||||
// unscan pushes the previously read token back onto the buffer.
|
||||
func (p *Parser) unread() { p.buf.n = 1 }
|
||||
func (p *Parser) unscan() { p.n = 1 }
|
||||
|
Loading…
Reference in New Issue
Block a user