mirror of
https://github.com/neilotoole/sq.git
synced 2024-12-18 21:52:28 +03:00
116 lines
1.9 KiB
Go
116 lines
1.9 KiB
Go
package ast
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/neilotoole/go-lg/lg"
|
|
"github.com/neilotoole/sq/libsq/slq"
|
|
"github.com/pboyer/antlr4/runtime/Go/antlr"
|
|
)
|
|
|
|
// AST is sq's Abstract Syntax Tree.
|
|
type AST struct {
|
|
ctx *slq.QueryContext
|
|
Datasource string
|
|
segs []*Segment
|
|
}
|
|
|
|
func (a *AST) Parent() Node {
|
|
return nil
|
|
}
|
|
|
|
func (a *AST) SetParent(parent Node) error {
|
|
return errorf("root node (%T) cannot have parent: tried to add parent %T", a, parent)
|
|
}
|
|
|
|
func (a *AST) Children() []Node {
|
|
nodes := make([]Node, len(a.segs))
|
|
|
|
for i, seg := range a.segs {
|
|
nodes[i] = seg
|
|
}
|
|
|
|
return nodes
|
|
}
|
|
|
|
func (a *AST) Segments() []*Segment {
|
|
return a.segs
|
|
}
|
|
|
|
func (a *AST) AddChild(node Node) error {
|
|
|
|
seg, ok := node.(*Segment)
|
|
if !ok {
|
|
return errorf("expected *Segment but got: %T", node)
|
|
}
|
|
|
|
a.AddSegment(seg)
|
|
return nil
|
|
}
|
|
|
|
func (a *AST) SetChildren(children []Node) error {
|
|
|
|
segs := make([]*Segment, len(children))
|
|
|
|
for i, child := range children {
|
|
seg, ok := child.(*Segment)
|
|
if !ok {
|
|
return errorf("expected child of type %s, but got: %T", TypeSegment, child)
|
|
}
|
|
|
|
segs[i] = seg
|
|
}
|
|
|
|
a.segs = segs
|
|
return nil
|
|
}
|
|
|
|
func (a *AST) Context() antlr.ParseTree {
|
|
return a.ctx
|
|
}
|
|
|
|
func (a *AST) SetContext(ctx antlr.ParseTree) error {
|
|
|
|
qCtx, ok := ctx.(*slq.QueryContext)
|
|
if !ok {
|
|
return errorf("expected *parser.QueryContext, but got %T", ctx)
|
|
}
|
|
|
|
a.ctx = qCtx
|
|
return nil
|
|
}
|
|
|
|
func (a *AST) String() string {
|
|
|
|
return nodeString(a)
|
|
|
|
}
|
|
|
|
func (a *AST) Text() string {
|
|
return a.ctx.GetText()
|
|
}
|
|
|
|
// AddSegment appends seg to the IR.
|
|
func (a *AST) AddSegment(seg *Segment) {
|
|
seg.SetParent(a)
|
|
|
|
//a.bn.AddChild(seg)
|
|
|
|
a.segs = append(a.segs, seg)
|
|
}
|
|
|
|
// Error is an error generated within the ast package.
|
|
type Error struct {
|
|
msg string
|
|
}
|
|
|
|
func (e *Error) Error() string {
|
|
return e.msg
|
|
}
|
|
|
|
func errorf(format string, v ...interface{}) *Error {
|
|
err := &Error{msg: fmt.Sprintf(format, v...)}
|
|
lg.Depth(1).Warnf("error created: %s", err.msg)
|
|
return err
|
|
}
|