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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
|
package logql
import (
"github.com/humanlogio/api/go/types/v1"
"time"
)
type logQL Peg {
// the query being built
LogQuery *typesv1.LogQuery
// stack for recursive generic structures
Exprs []*typesv1.Expr
// accumulate statements
Stmts []*typesv1.Statement
RenderStmt *typesv1.RenderStatement
// scratch space for table operators
FilterOp *typesv1.FilterOperator
SummarizeOp *typesv1.SummarizeOperator
ProjectOp *typesv1.ProjectOperator
ProjectAwayOp *typesv1.ProjectAwayOperator
ProjectKeepOp *typesv1.ProjectKeepOperator
ExtendOp *typesv1.ExtendOperator
CountOp *typesv1.CountOperator
DistinctOp *typesv1.DistinctOperator
SampleOp *typesv1.SampleOperator
SearchOp *typesv1.SearchOperator
SortOp *typesv1.SortOperator
TakeOp *typesv1.TakeOperator
TopOp *typesv1.TopOperator
// scratch space for search predicates
identifier string
// scratch space for render statements
SplitByOp *typesv1.SplitOperator
// scratch space, not needed but `Literal` being a type is convenient
Literal *typesv1.Val
// scalars
String string
F64 float64
I64 int64
Bool bool
Timestamp time.Time
Duration time.Duration
// stack for non-expr recursive structures
Arrs [][]*typesv1.Val
ObjsKVs [][]*typesv1.KV
FuncCalls []*typesv1.FuncCall
// errors seen along the way
err error
}
Grammar
<- Space ( Statements { p.SetQuery(p.Stmts) }
/ (QueryContext MustSpace )? Statements { p.SetQuery(p.Stmts) }
/ QueryContext
)? RenderStatement? EOF
QueryContext
<- L_SQUIGGLY Space QueryContextItem+ R_SQUIGGLY
QueryContextItem <- ( QueryMachineContext
/ QuerySessionContext
/ QueryFrom
/ QueryTo
) Space
QueryFrom <- 'from' Space CMP_EQ Space Expr { p.SetFrom(p.popExpr()) }
QueryTo <- 'to' Space CMP_EQ Space Expr { p.SetTo(p.popExpr()) }
QueryMachineContext <- 'machine' Space ( CMP_EQ Space Expr { p.SetContextMachine(typesv1.BinaryOp_CMP_EQ, p.popExpr()) }
/ CMP_NOTEQ Space Expr { p.SetContextMachine(typesv1.BinaryOp_CMP_NOTEQ, p.popExpr()) }
/ SET_IN Space Expr { p.SetContextMachine(typesv1.BinaryOp_SET_IN, p.popExpr()) }
/ SET_NOTIN Space Expr { p.SetContextMachine(typesv1.BinaryOp_SET_NOTIN, p.popExpr()) }
)
QuerySessionContext <- 'session' Space ( CMP_EQ Space Expr { p.SetContextSession(typesv1.BinaryOp_CMP_EQ, p.popExpr()) }
/ CMP_NOTEQ Space Expr { p.SetContextSession(typesv1.BinaryOp_CMP_NOTEQ, p.popExpr()) }
/ SET_IN Space Expr { p.SetContextSession(typesv1.BinaryOp_SET_IN, p.popExpr()) }
/ SET_NOTIN Space Expr { p.SetContextSession(typesv1.BinaryOp_SET_NOTIN, p.popExpr()) }
)
Statements <- Statement ( Space PIPE Space Statement )*
Statement <- ('filter' / 'where') FilterOperator { p.addFilterStatement(p.FilterOp) }
/ 'summarize' SummarizeOperator { p.addSummarizeStatement(p.SummarizeOp) }
/ 'project' ProjectOperator { p.addProjectStatement(p.ProjectOp) }
/ 'project-away' ProjectAwayOperator { p.addProjectAwayStatement(p.ProjectAwayOp) }
/ 'project-keep' ProjectKeepOperator { p.addProjectKeepStatement(p.ProjectKeepOp) }
/ 'extend' ExtendOperator { p.addExtendStatement(p.ExtendOp) }
/ 'count' CountOperator { p.addCountStatement(p.CountOp) }
/ 'distinct' DistinctOperator { p.addDistinctStatement(p.DistinctOp) }
/ 'sample' SampleOperator { p.addSampleStatement(p.SampleOp) }
/ 'search' SearchOperator { p.addSearchStatement(p.SearchOp) }
/ 'sort' SortOperator { p.addSortStatement(p.SortOp) }
/ 'take' TakeOperator { p.addTakeStatement(p.TakeOp) }
/ 'top' TopOperator { p.addTopStatement(p.TopOp) }
RenderStatement <- Space PIPE Space 'render' MustSpace RenderSplitOperator { p.setRenderSplitByStatement(p.SplitByOp) }
FilterOperator <- MustSpace Expr { p.setFilterOp(p.popExpr()) }
SummarizeOperator <- MustSpace { p.startSummarizeOp() }
SummarizeParameters ( SummarizeByGroupExpressions )?
SummarizeParameters <- SummarizeParameter ( Space ',' Space SummarizeParameter)* Space
SummarizeParameter <- Identifier { p.startSummarizeParameterNamedFunc(text) }
(Space '=' Space FuncCall) { p.endSummarizeParameterNamedFunc(p.popFunc()) }
/ FuncCall { p.addSummarizeParameterUnnamedFunc(p.popFunc()) }
SummarizeByGroupExpressions <- 'by' MustSpace SummarizeByGroupExpression ( Space ',' Space SummarizeByGroupExpression )* Space
SummarizeByGroupExpression <- Identifier { p.startSummarizeByUnnamedGroupExpression(text) }
(
Space '=' Space Expr { p.endSummarizeByUnnamedGroupExpression(p.popExpr()) }
)
/ Expr { p.addSummarizeByUnnamedGroupExpression(p.popExpr()) }
ProjectOperator <- MustSpace { p.startProjectOp() }
ProjectArg (Space ',' Space ProjectArg)* Space
ProjectArg <- Identifier { p.startProjectOpArg(text) }
(
Space '=' Space Expr { p.setProjectOpArgValue(p.popExpr()) }
)?
ProjectAwayOperator <- MustSpace { p.startProjectAwayOp() }
ProjectAwayArg (Space ',' Space ProjectAwayArg)* Space
ProjectAwayArg <- Identifier { p.addProjectAwayOpArg(text) }
ProjectKeepOperator <- MustSpace { p.startProjectKeepOp() }
ProjectKeepArg (Space ',' Space ProjectKeepArg)* Space
ProjectKeepArg <- Identifier { p.addProjectKeepOpArg(text) }
ExtendOperator <- MustSpace { p.startExtendOp() }
ExtendArg (Space ',' Space ExtendArg)* Space
ExtendArg <- Identifier { p.setExtendOpArgColumnName(text) }
Space '=' Space
Expr { p.setExtendOpArgValue(p.popExpr()) }
CountOperator <- { p.startCountOp() }
DistinctOperator <- { p.startDistinctOp() }
MustSpace DistinctOperatorArg (Space ',' Space DistinctOperatorArg)*
DistinctOperatorArg <- Identifier { p.addDistinctOpArg(text) }
SampleOperator <- MustSpace { p.startSampleOp() }
I64 Space { p.setSampleOpCount(p.I64) }
SearchOperator <- MustSpace { p.startSearchOp() }
('kind' Space '=' Space SearchOperatorCaseSensitivity MustSpace)?
SearchOperatorPredicate
SearchOperatorCaseSensitivity <- 'default' { p.setSearchOpKindDefault() }
/ 'case_insensitive' { p.setSearchOpKindCaseInsensitive() }
/ 'case_sensitive' { p.setSearchOpKindCaseSensitive() }
SearchOperatorPredicate <- Literal { p.setSearchOpPredicateLiteral(text) }
/ Identifier { p.identifier = text }
(
':' String { p.setSearchOpPredicateFieldSearch(p.identifier, p.String) }
/ '==' String { p.setSearchOpPredicateExactSearch(p.identifier, p.String) }
/ MustSpace 'matches regex' MustSpace String { p.setSearchOpPredicateRegexSearch(p.identifier, p.String) }
)
SortOperator <- MustSpace { p.startSortOp() }
'by' MustSpace SortOperatorArg ( Space ',' Space SortOperatorArg)* Space
SortOperatorArg <- Identifier { p.startSortOpArg(text) }
(MustSpace (
'asc' { p.setSortOpArgOrderAsc() }
/ 'desc' { p.setSortOpArgOrderDesc() }
))?
TakeOperator <- MustSpace { p.startTakeOp() }
I64 { p.setTakeOpCount(p.I64) }
TopOperator <- MustSpace { p.startTopOp() }
I64 MustSpace { p.setTopOpCount(p.I64) }
'by' MustSpace Expr { p.setTopOpByColumnScalar(p.popExpr()) }
(MustSpace (
'asc' { p.setTopOpByColumnOrderAsc() }
/ 'desc' { p.setTopOpByColumnOrderDesc() }
))?
RenderSplitOperator <- 'split' {p.startRenderSplitOp()} MustSpace RenderSplitByOperator
RenderSplitByOperator <- 'by' MustSpace RenderSplitByOperatorArg ( Space ',' Space RenderSplitByOperatorArg )* Space
RenderSplitByOperatorArg <- Expr { p.addRenderSplitByOp(p.popExpr()) }
Expr <- Expr1 ( Space NUM_ADD Expr1 Space { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_NUM_ADD, rhs)) }
/ Space NUM_SUB Expr1 Space { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_NUM_SUB, rhs)) }
)*
Expr1 <- Expr2 ( Space NUM_MUL Expr2 Space { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_NUM_MUL, rhs)) }
/ Space NUM_DIV Expr2 Space { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_NUM_DIV, rhs)) }
/ Space NUM_MOD Expr2 Space { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_NUM_MOD, rhs)) }
)*
Expr2 <- Expr3 ( Space LOG_AND Expr3 Space { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_LOG_AND, rhs)) }
/ Space LOG_OR Expr3 Space { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_LOG_OR, rhs)) }
)*
Expr3 <- Expr4 ( Space CMP_EQ Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_CMP_EQ, rhs)) }
/ Space CMP_NOTEQ Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_CMP_NOTEQ, rhs)) }
/ Space CMP_GT Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_CMP_GT, rhs)) }
/ Space CMP_GTE Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_CMP_GTE, rhs)) }
/ Space CMP_LT Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_CMP_LT, rhs)) }
/ Space CMP_LTE Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_CMP_LTE, rhs)) }
/ Space SET_IN Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_SET_IN, rhs)) }
/ Space SET_NOTIN Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_SET_NOTIN, rhs)) }
/ Space STR_EQ_NOCS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_EQ_NOCS, rhs)) }
/ Space STR_NOTEQ_NOCS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOTEQ_NOCS, rhs)) }
/ Space STR_CONTAINS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_CONTAINS, rhs)) }
/ Space STR_NOT_CONTAINS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_CONTAINS, rhs)) }
/ Space STR_CONTAINS_CS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_CONTAINS_CS, rhs)) }
/ Space STR_NOT_CONTAINS_CS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_CONTAINS_CS, rhs)) }
/ Space STR_STARTSWITH Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_STARTSWITH, rhs)) }
/ Space STR_NOT_STARTSWITH Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_STARTSWITH, rhs)) }
/ Space STR_STARTSWITH_CS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_STARTSWITH_CS, rhs)) }
/ Space STR_NOT_STARTSWITH_CS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_STARTSWITH_CS, rhs)) }
/ Space STR_ENDSWITH Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_ENDSWITH, rhs)) }
/ Space STR_NOT_ENDSWITH Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_ENDSWITH, rhs)) }
/ Space STR_ENDSWITH_CS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_ENDSWITH_CS, rhs)) }
/ Space STR_NOT_ENDSWITH_CS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_ENDSWITH_CS, rhs)) }
/ Space STR_IN_NOCS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_IN_NOCS, rhs)) }
/ Space STR_NOT_IN_NOCS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_IN_NOCS, rhs)) }
/ Space STR_NOT_MATCHES_REGEX Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_NOT_MATCHES_REGEX, rhs)) }
/ Space STR_MATCHES_REGEX Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_MATCHES_REGEX, rhs)) }
/ Space STR_HAS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_HAS, rhs)) }
/ Space STR_HAS_CS Expr4 { rhs, lhs := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprBinary(lhs, typesv1.BinaryOp_STR_HAS_CS, rhs)) }
)*
Expr4 <- Expr5 ( Space L_BRACKET Expr5 R_BRACKET { index, x := p.popExpr(), p.popExpr(); p.pushExpr(typesv1.ExprIndexor(x, index)) }
)*
Expr5 <- L_PARENS Expr R_PARENS Space
/ NOT Literal Space { p.pushExpr(typesv1.ExprUnary(typesv1.UnaryOp_NOT, typesv1.ExprLiteral(p.Literal))); p.Literal = nil }
/ NOT L_PARENS Expr R_PARENS Space { arg := p.popExpr(); p.pushExpr(typesv1.ExprUnary(typesv1.UnaryOp_NOT, arg)) }
/ NEG Literal Space { p.pushExpr(typesv1.ExprUnary(typesv1.UnaryOp_NEG, typesv1.ExprLiteral(p.Literal))); p.Literal = nil }
/ NEG L_PARENS Expr R_PARENS Space { arg := p.popExpr(); p.pushExpr(typesv1.ExprUnary(typesv1.UnaryOp_NEG, arg)) }
/ Literal Space { p.pushExpr(typesv1.ExprLiteral(p.Literal)); p.Literal = nil }
/ FuncCall Space { fn := p.popFunc(); p.pushExpr(typesv1.ExprFuncCall(fn.Name, fn.Args...)) }
/ Identifier
Literal
<- String { p.Literal = typesv1.ValStr(p.String) }
/ 'dur:'? Duration { p.Literal = typesv1.ValDuration(p.Duration) }
/ 'ts:'? Timestamp { p.Literal = typesv1.ValTime(p.Timestamp) }
/ F64 { p.Literal = typesv1.ValF64(p.F64) }
/ I64 { p.Literal = typesv1.ValI64(p.I64) }
/ Bool { p.Literal = typesv1.ValBool(p.Bool) }
/ 'dynamic(' Array ')' { p.Literal = typesv1.ValArr(p.popArray()...) }
/ 'dynamic(' Object ')' { p.Literal = typesv1.ValObj(p.popObj()...) }
FuncCall <- { p.pushFunc() }
FuncName '(' FuncArgs? ')' Space
FuncName <- !ReservedKeyword < [[a-z_]] ([[a-z_]] / [0-9])* > { p.setFuncName(text) }
FuncArgs <- FuncArg ( Space ',' Space FuncArg )* Space
FuncArg <- Expr { p.addFuncArg(p.popExpr()) }
Identifier
<- <[a-zA-Z_][a-zA-Z0-9_]*> { p.pushExpr(typesv1.ExprIdentifier(text)) }
/ '[\'' <([a-zA-Z0-9_]/[-]/[.]/[ ])*> '\']' { p.pushExpr(typesv1.ExprIdentifier(text)) }
/ '[\"' <([a-zA-Z0-9_]/[-]/[.]/[ ])*> '\"]' { p.pushExpr(typesv1.ExprIdentifier(text)) }
String
<- <'"' DoubleQuoteStringChar* '"'> { p.String = p.parseDoubleQuoteString(text) }
F64
<- <Digits '.' Digits? Exponent?> { p.F64 = p.parseFloat64(text) }
/ <'.' Digits Exponent?> { p.F64 = p.parseFloat64(text) }
/ <Digits Exponent> { p.F64 = p.parseFloat64(text) }
I64
<- '0' { p.I64 = 0 }
/ <[1-9] ([_]* [0-9])* > { p.I64 = p.parseInt64(text) }
Bool
<- 'true' { p.Bool = true }
/ 'false' { p.Bool = false }
ReservedKeyword <- ('lvl' / 'msg' / 'kv' / Bool)
Array <- L_BRACKET { p.pushArray() }
( ArrayItem ( COMMA ArrayItem )* )?
R_BRACKET
ArrayItem <- Literal { p.addArrItem(p.Literal); p.Literal = nil }
Object <- L_SQUIGGLY { p.pushObj() }
( ObjectItem ( COMMA ObjectItem )* )?
R_SQUIGGLY
ObjectItem <- ObjectKey COLON Literal { p.closeObjItem(p.Literal); p.Literal = nil }
ObjectKey <- String { p.startObjItem(p.String) }
Duration <- F64 <('us'/'µs'/'ms'/'s'/'m'/'h'/'d'/'w')> { p.Duration = p.parseDurationF64(p.F64, text) }
/ I64 <('ns'/'us'/'µs'/'ms'/'s'/'m'/'h'/'d'/'w')> { p.Duration = p.parseDurationI64(p.I64, text) }
Timestamp <- <RFC3339Nano> { p.Timestamp = p.parseTime(time.RFC3339Nano, text) }
DoubleQuoteStringChar <- '\\' ['\"?\\%abfnrtv] / ![\"\n\\] .
Exponent <- [eE] [+\-]? Digits
Digits <- [0-9]([_]*[0-9])*
// "2006-01-02T15:04:05.999999999Z07:00"
RFC3339Nano <- RFC3339NanoDate 'T' RFC3339NanoTime RFC3339NanoTimezone
RFC3339NanoDate <- Number '-' Number '-' Number
RFC3339NanoTime <- Number ':' Number ':' Number ('.' Number)?
RFC3339NanoTimezone <- 'Z' / '+' Number ':' Number
Number <- < [0-9]+ >
NOT <- '!' Space
NEG <- '-' Space
NUM_ADD <- '+' Space
NUM_SUB <- '-' Space
NUM_DIV <- '/' Space
NUM_MUL <- '*' Space
NUM_MOD <- '%' Space
LOG_AND <- 'and' MustSpace
LOG_OR <- 'or' MustSpace
CMP_EQ <- '==' Space
CMP_NOTEQ <- '!=' Space
CMP_GT <- '>' Space
CMP_GTE <- '>=' Space
CMP_LT <- '<' Space
CMP_LTE <- '<=' Space
SET_IN <- 'in' MustSpace
SET_NOTIN <- '!in' MustSpace
STR_EQ_NOCS <- '=~' Space
STR_NOTEQ_NOCS <- '!~' Space
STR_CONTAINS <- 'contains' MustSpace
STR_NOT_CONTAINS <- '!contains' MustSpace
STR_CONTAINS_CS <- 'contains_cs' MustSpace
STR_NOT_CONTAINS_CS <- '!contains_cs' MustSpace
STR_STARTSWITH <- 'startswith' MustSpace
STR_NOT_STARTSWITH <- '!startswith' MustSpace
STR_STARTSWITH_CS <- 'startswith_cs' MustSpace
STR_NOT_STARTSWITH_CS <- '!startswith_cs' MustSpace
STR_ENDSWITH <- 'endswith' MustSpace
STR_NOT_ENDSWITH <- '!endswith' MustSpace
STR_ENDSWITH_CS <- 'endswith_cs' MustSpace
STR_NOT_ENDSWITH_CS <- '!endswith_cs' MustSpace
STR_IN_NOCS <- 'in~' MustSpace
STR_NOT_IN_NOCS <- '!in~' MustSpace
STR_NOT_MATCHES_REGEX <- '!matches regex' MustSpace
STR_MATCHES_REGEX <- 'matches regex' MustSpace
STR_HAS <- 'has' MustSpace
STR_HAS_CS <- 'has_cs' MustSpace
PIPE <- '|' Space
L_PARENS <- '(' Space
R_PARENS <- ')' Space
L_BRACKET <- '[' Space
R_BRACKET <- ']' Space
L_SQUIGGLY <- '{' Space
R_SQUIGGLY <- '}'
COLON <- ':' Space
COMMA <- ',' Space
Space <- Whitespace*
MustSpace <- Whitespace+
Whitespace <- ' ' / '\t' / EOL
EOL <- '\r\n' / '\n' / '\r'
EOF <- !.
|