MCPcopy Create free account
hub / github.com/rabbitstack/fibratus / ParseExpr

Method ParseExpr

pkg/filter/ql/parser.go:216–306  ·  view source on GitHub ↗

ParseExpr parses an expression by building the binary expression tree.

()

Source from the content-addressed store, hash-verified

214
215// ParseExpr parses an expression by building the binary expression tree.
216func (p *Parser) ParseExpr() (Expr, error) {
217 var err error
218 root := &BinaryExpr{}
219 // parse a non-binary expression type to start. This variable will always be
220 // the root of the expression tree.
221 root.RHS, err = p.parseUnaryExpr()
222 if err != nil {
223 return nil, err
224 }
225
226 // loop over operations and unary exprs and build a tree based on precedence.
227 for {
228 // if the next token is NOT an operator then return the expression.
229 op, pos, lit := p.scanIgnoreWhitespace()
230 if !op.isOperator() {
231 p.unscan()
232 if op != EOF && op != Rparen && op != Comma && op != Pipe {
233 return nil, newParseError(tokstr(op, lit), []string{"operator", "')'", "','", "'|'"}, pos, p.expr)
234 }
235 return root.RHS, nil
236 }
237
238 if op == In || op == IIn {
239 // expect LPAREN after in
240 tok, pos, lit := p.scanIgnoreWhitespace()
241 p.unscan()
242 if tok != Lparen && (p.c != nil && !p.c.IsMacroList(lit)) {
243 return nil, newParseError(tokstr(op, lit), []string{"'('"}, pos, p.expr)
244 }
245 }
246
247 var rhs Expr
248 switch op {
249 case Not:
250 // the first variant of the negation operator.
251 // The operator that is negated appears immediately
252 // after the `not` operator, e.g. ps.name not in ('cmd.exe')
253 op1, pos, lit := p.scanIgnoreWhitespace()
254 if !op1.isOperator() {
255 return nil, newParseError(tokstr(op, lit), []string{"operator"}, pos, p.expr)
256 }
257 // parse the next expression after operator
258 rhs1, err := p.parseUnaryExpr()
259 if err != nil {
260 return nil, err
261 }
262 rhs = &BinaryExpr{RHS: rhs1, Op: op1}
263 default:
264 op1, _, _ := p.scanIgnoreWhitespace()
265 // if the negation appears after the operator
266 // try to parse an entire binary expr and wrap
267 // it inside the `not` expression. This is the
268 // second variant of the negating expressions, e.g.
269 // ps.name = 'cmd.exe' and not (ps.name in ('powershell.exe'))
270 if op1 == Not {
271 binaryExpr, err := p.ParseExpr()
272 if err != nil {
273 return nil, err

Callers 8

TestParserFunction · 0.95
ParseSequenceMethod · 0.95
parseUnaryExprMethod · 0.95
parseFunctionMethod · 0.95
TestParseFunctionFunction · 0.95
CompileMethod · 0.80
TestExpandMacrosFunction · 0.80

Calls 8

parseUnaryExprMethod · 0.95
scanIgnoreWhitespaceMethod · 0.95
unscanMethod · 0.95
newParseErrorFunction · 0.85
tokstrFunction · 0.85
isOperatorMethod · 0.80
IsMacroListMethod · 0.80
precedenceMethod · 0.80

Tested by 4

TestParserFunction · 0.76
TestParseFunctionFunction · 0.76
TestExpandMacrosFunction · 0.64