httpql 0.8.0

Parser for the HTTPQL language
Documentation
HTTPQL = { SOI ~ Query? ~ EOI }

// Tokens
// Delimiters
LeftParen  = _{ "(" }
RightParen = _{ ")" }
Dot        = _{ "." }
Colon      = _{ ":" }

// Logical operators
And = { "AND" | "and" }
Or  = { "OR" | "or" }

// Namespaces
RowNamespace      = _{ "row" }
RequestNamespace  = _{ "req" }
ResponseNamespace = _{ "resp" }
PresetNamespace   = _{ "preset" }
SourceNamespace   = _{ "source" }

// Row field names
RowIntFieldName = { "id" }

// Request field names
RequestStringFieldName = { "ext" | "host" | "method" | "path" | "query" | "raw" }
RequestIntFieldName    = { "len" | "port" }
RequestDateFieldName   = { "created_at" }
RequestBoolFieldName   = { "tls" }

// Response field names
ResponseStringFieldName = { "raw" }
ResponseIntFieldName    = { "code" | "len" | "roundtrip" }

// Operators for string and integer types
StringOperator = { "cont" | "ncont" | "eq" | "ne" | "like" | "nlike" }
RegexOperator  = { "regex" | "nregex" }
IntOperator    = { "eq" | "gte" | "gt" | "lte" | "lt" | "ne" }
DateOperator   = { "lt" | "gt" }
BoolOperator   = { "eq" | "ne" }

// Value types
SymbolValue   = @{ ('a'..'z' | '0'..'9' | "-" | "_")+ }
IntValue      = @{ ASCII_DIGIT+ }
StringValue   = @{ "\"" ~ StringContent ~ "\"" }
StringContent =  { StringChar* }
StringChar    =  {
    !("\"" | "\\") ~ ANY
  | "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
  | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
RegexValue    = ${ "/" ~ RegexContent ~ "/" }
RegexContent  = @{ RegexChar* }
RegexChar     =  {
    "\\" ~ ANY
  | !"/" ~ ANY
}
BoolValue     =  { "true" | "false" }

// Define non-token rules for constructing expressions
WHITESPACE     = _{ " " | "\t" | LineTerminator }
COMMENT        = _{ LineComment | BlockComment }
BlockComment   = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" }
LineComment    = _{ "//" ~ (!LineTerminator ~ ANY)* }
LineTerminator = @{ "\r\n" | "\r" | "\n" }

// Expression
IntExpression         = ${ IntOperator ~ Colon ~ IntValue }
StringExpression      = ${ StringOperator ~ Colon ~ StringValue | RegexOperator ~ Colon ~ (RegexValue | StringValue) }
DateExpression        = ${ DateOperator ~ Colon ~ StringValue }
BoolExpression        = ${ BoolOperator ~ Colon ~ BoolValue }
PresetNameExpression  =  { StringValue }
PresetAliasExpression =  { SymbolValue }
SourceNameExpression  =  { StringValue }

// Clause
StringClause = { StringValue }

RowClause = ${ RowNamespace ~ Dot ~ RowIntFieldName ~ Dot ~ IntExpression }

RequestClause = ${
    RequestNamespace ~ Dot ~ RequestIntFieldName ~ Dot ~ IntExpression
  | RequestNamespace ~ Dot ~ RequestStringFieldName ~ Dot ~ StringExpression
  | RequestNamespace ~ Dot ~ RequestDateFieldName ~ Dot ~ DateExpression
  | RequestNamespace ~ Dot ~ RequestBoolFieldName ~ Dot ~ BoolExpression
}

ResponseClause = ${
    ResponseNamespace ~ Dot ~ ResponseIntFieldName ~ Dot ~ IntExpression
  | ResponseNamespace ~ Dot ~ ResponseStringFieldName ~ Dot ~ StringExpression
}

PresetClause = ${
    PresetNamespace ~ Colon ~ (PresetNameExpression | PresetAliasExpression)
}

SourceClause = ${
    SourceNamespace ~ Colon ~ SourceNameExpression
}

// Query
Clause          = _{ StringClause | RowClause | RequestClause | ResponseClause | PresetClause | SourceClause | LeftParen ~ Query ~ RightParen }
LogicalOperator = _{ And | Or }
Query           =  { (Clause ~ (LogicalOperator ~ Clause)*)? }