aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/ast/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/ast/parser.go')
-rw-r--r--pkg/ast/parser.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/pkg/ast/parser.go b/pkg/ast/parser.go
index c87d43f5e..2f2e62055 100644
--- a/pkg/ast/parser.go
+++ b/pkg/ast/parser.go
@@ -433,7 +433,58 @@ func (p *parser) parseField(parseAttrs bool) *Field {
return field
}
+type operatorInfo struct {
+ op Operator
+ prio int
+}
+
+const maxOperatorPrio = 1
+
+// The highest priority is 0.
+var binaryOperators = map[token]operatorInfo{
+ tokCmpEq: {op: OperatorCompareEq, prio: 0},
+ tokCmpNeq: {op: OperatorCompareNeq, prio: 0},
+ tokBinAnd: {op: OperatorBinaryAnd, prio: 1},
+}
+
+// Parse out a single Type object, which can either be a plain object or an expression.
+// For now, only expressions constructed via '(', ')', "==", "!=", '&' are supported.
func (p *parser) parseType() *Type {
+ return p.parseBinaryExpr(0)
+}
+
+func (p *parser) parseBinaryExpr(expectPrio int) *Type {
+ if expectPrio > maxOperatorPrio {
+ return p.parseExprFactor()
+ }
+ lastPos := p.pos
+ curr := p.parseBinaryExpr(expectPrio + 1)
+ for {
+ info, ok := binaryOperators[p.tok]
+ if !ok || info.prio != expectPrio {
+ return curr
+ }
+ p.consume(p.tok)
+ curr = &Type{
+ Pos: lastPos,
+ Expression: &BinaryExpression{
+ Pos: p.pos,
+ Operator: info.op,
+ Left: curr,
+ Right: p.parseBinaryExpr(expectPrio + 1),
+ },
+ }
+ lastPos = p.pos
+ }
+}
+
+func (p *parser) parseExprFactor() *Type {
+ if p.tok == tokLParen {
+ p.consume(tokLParen)
+ ret := p.parseBinaryExpr(0)
+ p.consume(tokRParen)
+ return ret
+ }
arg := &Type{
Pos: p.pos,
}