@@ 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)) }