Add ParenExpr.

pull/1159/head
Ben Johnson 2014-11-24 23:12:32 -07:00
parent 143f8a0fd5
commit 4992a006e4
3 changed files with 45 additions and 3 deletions

View File

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

View File

@ -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 {

View File

@ -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{