forked from redpanda-data/connect
-
Notifications
You must be signed in to change notification settings - Fork 0
/
query_arithmetic_parser.go
132 lines (122 loc) · 2.68 KB
/
query_arithmetic_parser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package parser
import (
"fmt"
"github.com/dafanshu/benthos/v4/internal/bloblang/query"
)
//------------------------------------------------------------------------------
func arithmeticOpParser() Func {
opParser := OneOf(
Char('+'),
Char('-'),
Char('/'),
Char('*'),
Char('%'),
Term("&&"),
Term("||"),
Term("=="),
Term("!="),
Term(">="),
Term("<="),
Char('>'),
Char('<'),
Char('|'),
)
return func(input []rune) Result {
res := opParser(input)
if res.Err != nil {
return res
}
switch res.Payload.(string) {
case "+":
res.Payload = query.ArithmeticAdd
case "-":
res.Payload = query.ArithmeticSub
case "/":
res.Payload = query.ArithmeticDiv
case "*":
res.Payload = query.ArithmeticMul
case "%":
res.Payload = query.ArithmeticMod
case "==":
res.Payload = query.ArithmeticEq
case "!=":
res.Payload = query.ArithmeticNeq
case "&&":
res.Payload = query.ArithmeticAnd
case "||":
res.Payload = query.ArithmeticOr
case ">":
res.Payload = query.ArithmeticGt
case "<":
res.Payload = query.ArithmeticLt
case ">=":
res.Payload = query.ArithmeticGte
case "<=":
res.Payload = query.ArithmeticLte
case "|":
res.Payload = query.ArithmeticPipe
default:
return Fail(
NewFatalError(input, fmt.Errorf("operator not recognized: %v", res.Payload)),
input,
)
}
return res
}
}
func arithmeticParser(fnParser Func) Func {
whitespace := DiscardAll(
OneOf(
SpacesAndTabs(),
NewlineAllowComment(),
),
)
p := Delimited(
Sequence(
Optional(Sequence(Char('-'), whitespace)),
fnParser,
),
Sequence(
DiscardAll(SpacesAndTabs()),
arithmeticOpParser(),
whitespace,
),
)
return func(input []rune) Result {
var fns []query.Function
var ops []query.ArithmeticOperator
res := p(input)
if res.Err != nil {
return res
}
delimRes := res.Payload.(DelimitedResult)
for _, primaryRes := range delimRes.Primary {
fnSeq := primaryRes.([]any)
fn := fnSeq[1].(query.Function)
if fnSeq[0] != nil {
var err error
if fn, err = query.NewArithmeticExpression(
[]query.Function{
query.NewLiteralFunction("", int64(0)),
fn,
},
[]query.ArithmeticOperator{
query.ArithmeticSub,
},
); err != nil {
return Fail(NewFatalError(input, err), input)
}
}
fns = append(fns, fn)
}
for _, op := range delimRes.Delimiter {
ops = append(ops, op.([]any)[1].(query.ArithmeticOperator))
}
fn, err := query.NewArithmeticExpression(fns, ops)
if err != nil {
return Fail(NewFatalError(input, err), input)
}
return Success(fn, res.Remaining)
}
}
//------------------------------------------------------------------------------