parser: add initial AST definitions
This commit is contained in:
parent
c62cc48b92
commit
8e99146570
56
parser/ast.go
Normal file
56
parser/ast.go
Normal 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
|
||||||
|
}
|
@ -1 +1,16 @@
|
|||||||
package parser
|
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() {
|
||||||
|
}
|
||||||
|
@ -2,10 +2,10 @@ package scanner
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// Position describes an arbitrary source position
|
// Pos describes an arbitrary source position
|
||||||
// including the file, line, and column location.
|
// including the file, line, and column location.
|
||||||
// A Position is valid if the line number is > 0.
|
// A Position is valid if the line number is > 0.
|
||||||
type Position struct {
|
type Pos struct {
|
||||||
Filename string // filename, if any
|
Filename string // filename, if any
|
||||||
Offset int // offset, starting at 0
|
Offset int // offset, starting at 0
|
||||||
Line int // line number, starting at 1
|
Line int // line number, starting at 1
|
||||||
@ -13,7 +13,7 @@ type Position struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsValid returns true if the position is valid.
|
// 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:
|
// 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
|
// line:column valid position without file name
|
||||||
// file invalid position with file name
|
// file invalid position with file name
|
||||||
// - invalid position without file name
|
// - invalid position without file name
|
||||||
func (p Position) String() string {
|
func (p Pos) String() string {
|
||||||
s := p.Filename
|
s := p.Filename
|
||||||
if p.IsValid() {
|
if p.IsValid() {
|
||||||
if s != "" {
|
if s != "" {
|
||||||
|
@ -19,8 +19,8 @@ type Scanner struct {
|
|||||||
src []byte // Source buffer for immutable access
|
src []byte // Source buffer for immutable access
|
||||||
|
|
||||||
// Source Position
|
// Source Position
|
||||||
srcPos Position // current position
|
srcPos Pos // current position
|
||||||
prevPos Position // previous position, used for peek() method
|
prevPos Pos // previous position, used for peek() method
|
||||||
|
|
||||||
lastCharLen int // length of last character in bytes
|
lastCharLen int // length of last character in bytes
|
||||||
lastLineLen int // length of last line in characters (for correct column reporting)
|
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
|
// Error is called for each error encountered. If no Error
|
||||||
// function is set, the error is reported to os.Stderr.
|
// 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 is incremented by one for each error encountered.
|
||||||
ErrorCount int
|
ErrorCount int
|
||||||
@ -39,7 +39,7 @@ type Scanner struct {
|
|||||||
// Scan. The Filename field is always left untouched by the Scanner. If
|
// 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
|
// an error is reported (via Error) and Position is invalid, the scanner is
|
||||||
// not inside a token.
|
// not inside a token.
|
||||||
tokPos Position
|
tokPos Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewScannerstring creates and initializes a new instance of Scanner using
|
// 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
|
// recentPosition returns the position of the character immediately after the
|
||||||
// character or token returned by the last call to Scan.
|
// 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
|
pos.Offset = s.srcPos.Offset - s.lastCharLen
|
||||||
switch {
|
switch {
|
||||||
case s.srcPos.Column > 0:
|
case s.srcPos.Column > 0:
|
||||||
|
@ -184,7 +184,7 @@ func TestPosition(t *testing.T) {
|
|||||||
|
|
||||||
s := NewScanner(buf.Bytes())
|
s := NewScanner(buf.Bytes())
|
||||||
|
|
||||||
pos := Position{"", 4, 1, 5}
|
pos := Pos{"", 4, 1, 5}
|
||||||
s.Scan()
|
s.Scan()
|
||||||
for _, listName := range orderedTokenLists {
|
for _, listName := range orderedTokenLists {
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ func testError(t *testing.T, src, pos, msg string, tok TokenType) {
|
|||||||
s := NewScanner([]byte(src))
|
s := NewScanner([]byte(src))
|
||||||
|
|
||||||
errorCalled := false
|
errorCalled := false
|
||||||
s.Error = func(p Position, m string) {
|
s.Error = func(p Pos, m string) {
|
||||||
if !errorCalled {
|
if !errorCalled {
|
||||||
if pos != p.String() {
|
if pos != p.String() {
|
||||||
t.Errorf("pos = %q, want %q for %q", p, pos, src)
|
t.Errorf("pos = %q, want %q for %q", p, pos, src)
|
||||||
|
@ -5,7 +5,7 @@ import "strconv"
|
|||||||
// Token defines a single HCL token which can be obtained via the Scanner
|
// Token defines a single HCL token which can be obtained via the Scanner
|
||||||
type Token struct {
|
type Token struct {
|
||||||
token TokenType
|
token TokenType
|
||||||
pos Position
|
pos Pos
|
||||||
text string
|
text string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ func (t Token) Type() TokenType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pos returns the token's position
|
// Pos returns the token's position
|
||||||
func (t Token) Pos() Position {
|
func (t Token) Pos() Pos {
|
||||||
return t.pos
|
return t.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user