~mna/fastpeg

60101ff5ad34195b65b2ede1381202f98e4fe2d9 — Martin Angers 1 year, 25 days ago ccaaf5e master
internal/ast: work on ast types
1 files changed, 102 insertions(+), 16 deletions(-)

M internal/ast/ast.go
M internal/ast/ast.go => internal/ast/ast.go +102 -16
@@ 4,21 4,35 @@ import (
	"git.sr.ht/~mna/fastpeg/internal/bootstrap/token"
)

type Expression interface{}
// Node represents a node in the abstract syntax tree.
type Node interface {
	Start() token.Pos
	End() token.Pos
}

// Expression is any expression in the grammar.
type Expression interface {
	Node
	expr()
}

// Grammar represents a parsed fastpeg grammar.
type Grammar struct {
	Definitions []*Definition
}

func (g *Grammar) Start() token.Pos { return g.Definitions[0].Start() }
func (g *Grammar) End() token.Pos   { return g.Definitions[len(g.Definitions)-1].End() }

// Definition represents a single rule definition in a grammar.
type Definition struct {
	// Ident is the required identifier in a definition, i.e.:
	// identifier <- expression
	Ident *Identifier
	Ident *Word

	// Arrow indicates the location and type of arrow in the
	// definition.
	Arrow *Punctuation
	Arrow *Word

	// Expr is the expression associated with this definition's
	// identifier.


@@ 26,65 40,134 @@ type Definition struct {

	// EOS is the end-of-statement if present for this
	// definition, nil otherwise.
	EOS *Punctuation
	EOS *Word
}

func (d *Definition) Start() token.Pos { return d.Ident.Start() }
func (d *Definition) End() token.Pos {
	if d.EOS != nil {
		return d.EOS.End()
	}
	return d.Expr.End()
}

// Choice is a choice expression.
type Choice struct {
	// Exprs is the list of options, one expression for each
	// choice.
	Exprs []Expression

	// Seps is the list of choice separators between each option.
	Seps []*Punctuation
	Seps []*Word
}

func (c *Choice) Start() token.Pos { return c.Exprs[0].Start() }
func (c *Choice) End() token.Pos   { return c.Exprs[len(c.Exprs)-1].End() }

func (c *Choice) expr() {}

// Sequence is a sequence expression.
type Sequence struct {
	// Exprs is the list of expressions in this sequence.
	Exprs []Expression
}

func (s *Sequence) Start() token.Pos { return s.Exprs[0].Start() }
func (s *Sequence) End() token.Pos   { return s.Exprs[len(s.Exprs)-1].End() }

func (s *Sequence) expr() {}

// Coderef is a code reference expression.
type Coderef struct {
	Pos   token.Pos
	Type  token.Token
	Ident string
}

func (c *Coderef) Start() token.Pos { return c.Pos }

// TODO: should the token.Coderef be scanned from start to ending }?
func (c *Coderef) End() token.Pos { return c.Pos + token.Pos(len(c.Ident)) }

func (c *Coderef) expr() {}

// Label is a labeled expression.
type Label struct {
	Ident *Identifier
	Colon *Punctuation
	Ident *Word
	Colon *Word
	Expr  Expression
}

func (l *Label) Start() token.Pos { return l.Ident.Start() }
func (l *Label) End() token.Pos   { return l.Expr.End() }

func (l *Label) expr() {}

// Prefix is a prefixed expression.
type Prefix struct {
	Prefix *Punctuation
	Prefix *Word
	Expr   Expression
}

func (p *Prefix) Start() token.Pos { return p.Prefix.Start() }
func (p *Prefix) End() token.Pos   { return p.Expr.End() }

func (p *Prefix) expr() {}

// Suffix is a suffixed expression.
type Suffix struct {
	Suffix *Punctuation
	Expr   Expression
	Suffix *Word
}

func (s *Suffix) Start() token.Pos { return s.Expr.Start() }
func (s *Suffix) End() token.Pos   { return s.Suffix.End() }

func (s *Suffix) expr() {}

// Ruleref is a rule reference expression.
type Ruleref struct {
	Ident *Identifier
	Ident *Word
}

func (r *Ruleref) Start() token.Pos { return r.Ident.Start() }
func (r *Ruleref) End() token.Pos   { return r.Ident.End() }

func (r *Ruleref) expr() {}

// Literal is a literal string expression.
type Literal struct {
	Value *Word
}

func (l *Literal) Start() token.Pos { return l.Value.Start() }
func (l *Literal) End() token.Pos   { return l.Value.End() }

func (l *Literal) expr() {}

// CharClass is a character class expression.
type CharClass struct {
	Value *Word
}

func (c *CharClass) Start() token.Pos { return c.Value.Start() }
func (c *CharClass) End() token.Pos   { return c.Value.End() }

func (c *CharClass) expr() {}

// Any is a dot expression.
type Any struct {
	Dot *Punctuation
	Dot *Word
}

type Identifier struct {
	Pos   token.Pos
	Value string
}
func (a *Any) Start() token.Pos { return a.Dot.Start() }
func (a *Any) End() token.Pos   { return a.Dot.End() }

func (a *Any) expr() {}

type Punctuation struct {
// Word represents the representation of a literal (including identifiers)
// or punctuation in the grammar.
type Word struct {
	// Pos is the FileSet-dependent position of the start of
	// this punctuation.
	Pos token.Pos


@@ 92,3 175,6 @@ type Punctuation struct {
	// Value is the representation of this punctuation.
	Value string
}

func (w *Word) Start() token.Pos { return w.Pos }
func (w *Word) End() token.Pos   { return w.Pos + token.Pos(len(w.Value)) }