Add ParenExpr.
parent
143f8a0fd5
commit
4992a006e4
|
@ -46,6 +46,7 @@ func (_ *BooleanLiteral) node() {}
|
|||
func (_ *TimeLiteral) node() {}
|
||||
func (_ *DurationLiteral) node() {}
|
||||
func (_ *BinaryExpr) node() {}
|
||||
func (_ *ParenExpr) node() {}
|
||||
|
||||
// Query represents a collection of order statements.
|
||||
type Query struct {
|
||||
|
@ -83,6 +84,7 @@ func (_ *BooleanLiteral) expr() {}
|
|||
func (_ *TimeLiteral) expr() {}
|
||||
func (_ *DurationLiteral) expr() {}
|
||||
func (_ *BinaryExpr) expr() {}
|
||||
func (_ *ParenExpr) expr() {}
|
||||
|
||||
// Source represents a source of data for a statement.
|
||||
type Source interface {
|
||||
|
@ -227,6 +229,11 @@ type BinaryExpr struct {
|
|||
RHS Expr
|
||||
}
|
||||
|
||||
// ParenExpr represents a parenthesized expression.
|
||||
type ParenExpr struct {
|
||||
Expr Expr
|
||||
}
|
||||
|
||||
// Visitor can be called by Walk to traverse an AST hierarchy.
|
||||
// The Visit() function is called once per node.
|
||||
type Visitor interface {
|
||||
|
@ -274,6 +281,9 @@ func Walk(v Visitor, node Node) {
|
|||
Walk(v, n.LHS)
|
||||
Walk(v, n.RHS)
|
||||
|
||||
case *ParenExpr:
|
||||
Walk(v, n.Expr)
|
||||
|
||||
case *Call:
|
||||
for _, expr := range n.Args {
|
||||
Walk(v, expr)
|
||||
|
|
|
@ -487,6 +487,22 @@ func (p *Parser) ParseExpr() (Expr, error) {
|
|||
|
||||
// parseUnaryExpr parses an non-binary expression.
|
||||
func (p *Parser) parseUnaryExpr() (Expr, error) {
|
||||
// If the first token is a LPAREN then parse it as its own grouped expression.
|
||||
if tok, _, _ := p.scanIgnoreWhitespace(); tok == LPAREN {
|
||||
expr, err := p.ParseExpr()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Expect an RPAREN at the end.
|
||||
if tok, pos, lit := p.scanIgnoreWhitespace(); tok != RPAREN {
|
||||
return nil, newParseError(tokstr(tok, lit), []string{")"}, pos)
|
||||
}
|
||||
|
||||
return &ParenExpr{Expr: expr}, nil
|
||||
}
|
||||
p.unscan()
|
||||
|
||||
// Read next token.
|
||||
tok, pos, lit := p.scanIgnoreWhitespace()
|
||||
switch tok {
|
||||
|
|
|
@ -216,7 +216,23 @@ func TestParser_ParseExpr(t *testing.T) {
|
|||
},
|
||||
},
|
||||
|
||||
// 8. Complex binary expression.
|
||||
// 8. Binary expression with LHS paren group.
|
||||
{
|
||||
s: `(1 + 2) * 3`,
|
||||
expr: &influxql.BinaryExpr{
|
||||
Op: influxql.MUL,
|
||||
LHS: &influxql.ParenExpr{
|
||||
Expr: &influxql.BinaryExpr{
|
||||
Op: influxql.ADD,
|
||||
LHS: &influxql.NumberLiteral{Val: 1},
|
||||
RHS: &influxql.NumberLiteral{Val: 2},
|
||||
},
|
||||
},
|
||||
RHS: &influxql.NumberLiteral{Val: 3},
|
||||
},
|
||||
},
|
||||
|
||||
// 9. Complex binary expression.
|
||||
{
|
||||
s: `value + 3 < 30 AND 1 + 2 OR true`,
|
||||
expr: &influxql.BinaryExpr{
|
||||
|
@ -242,7 +258,7 @@ func TestParser_ParseExpr(t *testing.T) {
|
|||
},
|
||||
},
|
||||
|
||||
// 9. Function call (empty)
|
||||
// 10. Function call (empty)
|
||||
{
|
||||
s: `my_func()`,
|
||||
expr: &influxql.Call{
|
||||
|
@ -250,7 +266,7 @@ func TestParser_ParseExpr(t *testing.T) {
|
|||
},
|
||||
},
|
||||
|
||||
// 10. Function call (multi-arg)
|
||||
// 11. Function call (multi-arg)
|
||||
{
|
||||
s: `my_func(1, 2 + 3)`,
|
||||
expr: &influxql.Call{
|
||||
|
|
Loading…
Reference in New Issue