Skip to content

Commit 8a68e74

Browse files
committed
MB-35091 - Reorganized AND/OR parsing EBNF to capture all cases correctly
1 parent afd5881 commit 8a68e74

File tree

2 files changed

+412
-276
lines changed

2 files changed

+412
-276
lines changed

filterExprParser.go

Lines changed: 89 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import (
1111

1212
// EBNF Grammar describing the parser
1313

14-
// FilterExpression = ( "(" FilterExpression ")" { "AND" FilterExpression } { "OR" FilterExpression } ) | InnerExpression { "AND" FilterExpression }
15-
// InnerExpression = AndCondition { "OR" AndCondition }
16-
// AndCondition = Condition { "AND" Condition }
14+
// FilterExpression = InnerExpression
15+
// InnerExpression = InnerAndExpression { "OR" InnerAndExpression }
16+
// InnerAndExpression = SubExprOrTerm { "AND" SubExprOrTerm }
17+
// SubExprOrTerm = "(" InnerExpression ")" | Condition
1718
// Condition = ( [ "NOT" ] Condition ) | Operand
1819
// Operand = BooleanExpr | ( LHS ( CheckOp | ( CompareOp RHS) ) )
1920
// BooleanExpr = Boolean | BooleanFuncExpr
@@ -49,189 +50,137 @@ import (
4950
// ExistsClause = ( "EXISTS" "(" Field ")" )
5051

5152
type FilterExpression struct {
52-
OpenParen *FEOpenParen `( @@ `
53-
SubFilterExpr *FilterExpression `@@`
54-
CloseParen *FECloseParen ` @@`
55-
AndContinuation *FilterExpression `{ "AND" @@ }`
56-
OrContinuation *FilterExpression `{ "OR" @@ }) |`
57-
FilterExpr *FEInnerExpression `@@`
58-
FilterExprContinuation *FilterExpression `{ "AND" @@ }`
53+
FilterExpr *FEInnerExpression `@@`
5954
}
6055

6156
func (f *FilterExpression) String() string {
62-
var output []string
6357
if f.FilterExpr != nil {
64-
output = append(output, f.FilterExpr.String())
65-
if f.FilterExprContinuation != nil {
66-
output = append(output, OperatorAnd)
67-
output = append(output, f.FilterExprContinuation.String())
68-
}
69-
} else {
70-
if f.OpenParen != nil {
71-
output = append(output, f.OpenParen.String())
72-
}
73-
if f.SubFilterExpr != nil {
74-
output = append(output, f.SubFilterExpr.String())
75-
}
76-
if f.CloseParen != nil {
77-
output = append(output, f.CloseParen.String())
78-
}
79-
if f.AndContinuation != nil {
80-
output = append(output, OperatorAnd)
81-
output = append(output, f.AndContinuation.String())
82-
} else if f.OrContinuation != nil {
83-
output = append(output, OperatorOr)
84-
output = append(output, f.OrContinuation.String())
85-
}
86-
87-
}
88-
if len(output) == 0 {
89-
return "?? (FilterExpression)"
58+
return f.FilterExpr.String()
9059
} else {
91-
return strings.Join(output, " ")
60+
return "Invalid FilterExpression"
9261
}
93-
9462
}
9563

96-
func (f *FilterExpression) outputExpressionNoParenCheck() (Expression, error) {
64+
func (f *FilterExpression) OutputExpression() (Expression, error) {
9765
if f.FilterExpr != nil {
98-
if f.FilterExprContinuation != nil {
99-
continuation, err := f.FilterExprContinuation.OutputExpression()
100-
if err != nil {
101-
return nil, err
102-
}
103-
filterExpr, err := f.FilterExpr.OutputExpression()
104-
if err != nil {
105-
return nil, err
106-
}
107-
var outExpr AndExpr
108-
outExpr = append(outExpr, filterExpr)
109-
outExpr = append(outExpr, continuation)
110-
return outExpr, nil
111-
} else {
112-
return f.FilterExpr.OutputExpression()
113-
}
114-
} else if f.SubFilterExpr != nil {
115-
subExprOut, err := f.SubFilterExpr.OutputExpression()
116-
if err != nil {
117-
return nil, err
118-
}
119-
if f.AndContinuation != nil {
120-
var outExpr AndExpr
121-
outExpr = append(outExpr, subExprOut)
122-
andContinuation, err := f.AndContinuation.OutputExpression()
123-
if err != nil {
124-
return nil, err
125-
}
126-
outExpr = append(outExpr, andContinuation)
127-
return outExpr, nil
128-
} else if f.OrContinuation != nil {
129-
var outExpr OrExpr
130-
outExpr = append(outExpr, subExprOut)
131-
orContinuation, err := f.OrContinuation.OutputExpression()
132-
if err != nil {
133-
return nil, err
134-
}
135-
outExpr = append(outExpr, orContinuation)
136-
return outExpr, nil
137-
} else {
138-
return subExprOut, err
139-
}
66+
return f.FilterExpr.OutputExpression()
14067
} else {
141-
return nil, fmt.Errorf("Invalid FilterExpression %v", f.String())
68+
return nil, fmt.Errorf("Invalid FilterExpression")
14269
}
14370
}
14471

145-
func (f *FilterExpression) OutputExpression() (Expression, error) {
146-
openParens := f.GetTotalOpenParens()
147-
closeParens := f.GetTotalCloseParens()
148-
if openParens != closeParens {
149-
return nil, fmt.Errorf("%s: found %v open parentheses and %v close parentheses", ErrorMalformedParenthesis, openParens, closeParens)
150-
}
151-
152-
return f.outputExpressionNoParenCheck()
72+
type FEInnerExpression struct {
73+
Expr []*FEInnerAndExpression `@@ { "OR" @@ }`
15374
}
15475

155-
func (f *FilterExpression) GetTotalOpenParens() (count int) {
156-
if f.OpenParen != nil {
157-
count++
76+
func (f *FEInnerExpression) String() string {
77+
var output []string
78+
if f.Expr == nil {
79+
return ""
15880
}
159-
if f.SubFilterExpr != nil {
160-
count += f.SubFilterExpr.GetTotalOpenParens()
161-
} else if f.FilterExpr != nil {
162-
if f.FilterExprContinuation != nil {
163-
count += f.FilterExprContinuation.GetTotalOpenParens()
164-
}
81+
for _, expr := range f.Expr {
82+
output = append(output, expr.String())
16583
}
166-
return
84+
return strings.Join(output, " OR ")
16785
}
16886

169-
func (f *FilterExpression) GetTotalCloseParens() (count int) {
170-
if f.CloseParen != nil {
171-
count++
87+
func (f *FEInnerExpression) OutputExpression() (Expression, error) {
88+
var outExpr OrExpr
89+
if f.Expr == nil {
90+
return nil, fmt.Errorf("Invalid FEInnerExpression")
17291
}
173-
if f.SubFilterExpr != nil {
174-
count += f.SubFilterExpr.GetTotalCloseParens()
175-
} else if f.FilterExpr != nil {
176-
if f.FilterExprContinuation != nil {
177-
count += f.FilterExprContinuation.GetTotalCloseParens()
92+
for _, exprWrapper := range f.Expr {
93+
expr, err := exprWrapper.OutputExpression()
94+
if err != nil {
95+
return nil, err
17896
}
97+
outExpr = append(outExpr, expr)
17998
}
180-
return
99+
return outExpr, nil
181100
}
182101

183-
type FEInnerExpression struct {
184-
AndConditions []*FEAndCondition `( @@ { "OR" @@ } )`
102+
type FEInnerAndExpression struct {
103+
Expr []*FESubExprOrTerm `@@ { "AND" @@ }`
185104
}
186105

187-
func (fe *FEInnerExpression) String() string {
188-
output := []string{}
189-
190-
first := true
191-
for _, expr := range fe.AndConditions {
192-
if first {
193-
first = false
194-
} else {
195-
output = append(output, OperatorOr)
196-
}
106+
func (f *FEInnerAndExpression) String() string {
107+
var output []string
108+
if f.Expr == nil {
109+
return ""
110+
}
111+
for _, expr := range f.Expr {
197112
output = append(output, expr.String())
198113
}
199-
200-
return strings.Join(output, " ")
114+
return strings.Join(output, " AND ")
201115
}
202116

203-
func (f *FEInnerExpression) OutputExpression() (Expression, error) {
204-
var outExpr OrExpr
205-
206-
for _, oneExpr := range f.AndConditions {
207-
andExpr, err := oneExpr.OutputExpression()
117+
func (f *FEInnerAndExpression) OutputExpression() (Expression, error) {
118+
var outExpr AndExpr
119+
if f.Expr == nil {
120+
return nil, fmt.Errorf("Invalid FEInnerAndExpression")
121+
}
122+
for _, exprWrapper := range f.Expr {
123+
expr, err := exprWrapper.OutputExpression()
208124
if err != nil {
209125
return nil, err
210126
}
211-
outExpr = append(outExpr, andExpr)
127+
outExpr = append(outExpr, expr)
212128
}
213-
214129
return outExpr, nil
215130
}
216131

217-
type FEOpenParen struct {
218-
Parens string `@"("`
132+
type FESubExprOrTerm struct {
133+
SubExpr *FEInnerExpression `( "(" @@ ")" |`
134+
Expr *FECondition `@@ )`
219135
}
220136

221-
func (feop *FEOpenParen) String() string {
222-
return "("
137+
func (f *FESubExprOrTerm) String() string {
138+
if f.SubExpr != nil {
139+
return fmt.Sprintf("%v %v %v", "(", f.SubExpr.String(), ")")
140+
} else if f.Expr != nil {
141+
return f.Expr.String()
142+
} else {
143+
return "?? (FESubExprOrTerm)"
144+
}
223145
}
224146

225-
type FECloseParen struct {
226-
Parens string `@")"`
147+
func (f *FESubExprOrTerm) OutputExpression() (Expression, error) {
148+
if f.SubExpr != nil {
149+
return f.SubExpr.OutputExpression()
150+
} else if f.Expr != nil {
151+
return f.Expr.OutputExpression()
152+
} else {
153+
return nil, fmt.Errorf("Invalid FESubExprOrTerm")
154+
}
155+
}
156+
157+
type FEAndConditionWrapper struct {
158+
SubExpr *FEAndCondition `( "(" @@ ")" |`
159+
Expr *FEAndCondition `@@ )`
227160
}
228161

229-
func (fecp *FECloseParen) String() string {
230-
return ")"
162+
func (f *FEAndConditionWrapper) String() string {
163+
if f.SubExpr != nil {
164+
return fmt.Sprintf("%v %v %v", "(", f.SubExpr.String(), ")")
165+
} else if f.Expr != nil {
166+
return f.Expr.String()
167+
} else {
168+
return "?? (FEAndConditionWrapper)"
169+
}
170+
}
171+
172+
func (f *FEAndConditionWrapper) OutputExpression() (Expression, error) {
173+
if f.SubExpr != nil {
174+
return f.SubExpr.OutputExpression()
175+
} else if f.Expr != nil {
176+
return f.Expr.OutputExpression()
177+
} else {
178+
return nil, fmt.Errorf("Invalid FEAndConditionWrapper")
179+
}
231180
}
232181

233182
type FEAndCondition struct {
234-
OrConditions []*FECondition `@@ { "AND" @@ }`
183+
OrConditions []*FESubExprOrTerm `@@ { "AND" @@ }`
235184
}
236185

237186
func (ac *FEAndCondition) String() string {

0 commit comments

Comments
 (0)