parser: add initial AST definitions

This commit is contained in:
Fatih Arslan 2015-10-08 01:38:39 +03:00
parent c62cc48b92
commit 8e99146570
6 changed files with 84 additions and 13 deletions

56
parser/ast.go Normal file
View File

@ -0,0 +1,56 @@
package parser
import "github.com/fatih/hcl/scanner"
type NodeType int
const (
Unknown NodeType = 0
Number
Float
Bool
String
List
Object
)
// Node is an element in the parse tree.
type Node interface {
String() string
Type() NodeType
Start() scanner.Pos
End() scanner.Pos
}
// IdentStatement represents an identifier.
type IdentStatement struct {
Token scanner.Token
Pos scanner.Pos // position of the literal
Value string
}
type BlockStatement struct {
Lbrace scanner.Pos // position of "{"
Rbrace scanner.Pos // position of "}"
List []Node // the nodes in lexical order
}
// AssignStatement represents an assignment
type AssignStatement struct {
Lhs Node // left hand side of the assignment
Rhs Node // right hand side of the assignment
Assign scanner.Pos // position of "="
}
// ListStatement represents a list
type ListStatement struct {
Lbrack scanner.Pos // position of "["
Rbrack scanner.Pos // position of "]"
List []Node // the elements in lexical order
}
// ObjectStatment represents an object
type ObjectStatement struct {
Idents []Node // the idents in elements in lexical order
BlockStatement
}

View File

@ -1 +1,16 @@
package parser
import "github.com/fatih/hcl/scanner"
type Parser struct {
sc *scanner.Scanner
}
func NewParser(src []byte) *Parser {
return &Parser{
sc: scanner.NewScanner(src),
}
}
func (p *Parser) Parse() {
}

View File

@ -2,10 +2,10 @@ package scanner
import "fmt"
// Position describes an arbitrary source position
// Pos describes an arbitrary source position
// including the file, line, and column location.
// A Position is valid if the line number is > 0.
type Position struct {
type Pos struct {
Filename string // filename, if any
Offset int // offset, starting at 0
Line int // line number, starting at 1
@ -13,7 +13,7 @@ type Position struct {
}
// IsValid returns true if the position is valid.
func (p *Position) IsValid() bool { return p.Line > 0 }
func (p *Pos) IsValid() bool { return p.Line > 0 }
// String returns a string in one of several forms:
//
@ -21,7 +21,7 @@ func (p *Position) IsValid() bool { return p.Line > 0 }
// line:column valid position without file name
// file invalid position with file name
// - invalid position without file name
func (p Position) String() string {
func (p Pos) String() string {
s := p.Filename
if p.IsValid() {
if s != "" {

View File

@ -19,8 +19,8 @@ type Scanner struct {
src []byte // Source buffer for immutable access
// Source Position
srcPos Position // current position
prevPos Position // previous position, used for peek() method
srcPos Pos // current position
prevPos Pos // previous position, used for peek() method
lastCharLen int // length of last character in bytes
lastLineLen int // length of last line in characters (for correct column reporting)
@ -30,7 +30,7 @@ type Scanner struct {
// Error is called for each error encountered. If no Error
// function is set, the error is reported to os.Stderr.
Error func(pos Position, msg string)
Error func(pos Pos, msg string)
// ErrorCount is incremented by one for each error encountered.
ErrorCount int
@ -39,7 +39,7 @@ type Scanner struct {
// Scan. The Filename field is always left untouched by the Scanner. If
// an error is reported (via Error) and Position is invalid, the scanner is
// not inside a token.
tokPos Position
tokPos Pos
}
// NewScannerstring creates and initializes a new instance of Scanner using
@ -449,7 +449,7 @@ func (s *Scanner) scanIdentifier() string {
// recentPosition returns the position of the character immediately after the
// character or token returned by the last call to Scan.
func (s *Scanner) recentPosition() (pos Position) {
func (s *Scanner) recentPosition() (pos Pos) {
pos.Offset = s.srcPos.Offset - s.lastCharLen
switch {
case s.srcPos.Column > 0:

View File

@ -184,7 +184,7 @@ func TestPosition(t *testing.T) {
s := NewScanner(buf.Bytes())
pos := Position{"", 4, 1, 5}
pos := Pos{"", 4, 1, 5}
s.Scan()
for _, listName := range orderedTokenLists {
@ -369,7 +369,7 @@ func testError(t *testing.T, src, pos, msg string, tok TokenType) {
s := NewScanner([]byte(src))
errorCalled := false
s.Error = func(p Position, m string) {
s.Error = func(p Pos, m string) {
if !errorCalled {
if pos != p.String() {
t.Errorf("pos = %q, want %q for %q", p, pos, src)

View File

@ -5,7 +5,7 @@ import "strconv"
// Token defines a single HCL token which can be obtained via the Scanner
type Token struct {
token TokenType
pos Position
pos Pos
text string
}
@ -92,7 +92,7 @@ func (t Token) Type() TokenType {
}
// Pos returns the token's position
func (t Token) Pos() Position {
func (t Token) Pos() Pos {
return t.pos
}