grammar FilterLexer
# Complex combinations rule expression space? (expression_compound / body) space? <Expression> end rule expression_compound body space? combine_operator space? expression <Expression> end rule body group / filter end rule group '(' expression ')' <Group> end # Filters rule filter filter_equality / filter_comparison / filter_like end rule filter_equality identifier space? equality_operator space? value <Filter> end rule filter_comparison identifier space? comparison_operator space? (number / datetime) <Filter> end rule filter_like identifier space? like_operator space? string <Filter> end # Logic rule combine_operator or_operator / and_operator end rule or_operator '' ('||' / 'OR' / 'or') <OrOperator> end rule and_operator '' ('&&' / 'AND' / 'and') <AndOperator> end # Operators rule equality_operator eq_operator / neq_operator end rule comparison_operator le_operator / lt_operator / ge_operator / gt_operator end rule like_operator yes_like_operator / not_like_operator end rule eq_operator '' ('==' / 'eq' / 'EQ' / 'is' / 'IS') <EQOperator> end rule neq_operator '' ('!=' / '<>' / 'neq' / 'NEQ' / 'not is' / 'NOT IS' / 'is not' / 'IS NOT') <NEQOperator> end rule lt_operator '' ('<' / 'lt' / 'LT') <LTOperator> end rule le_operator '' ('<=' / 'le' / 'LE') <LEOperator> end rule gt_operator '' ('>' / 'gt' / 'GT') <GTOperator> end rule ge_operator '' ('>=' / 'ge' / 'GE') <GEOperator> end rule yes_like_operator '' ('=~' / 'like' / 'LIKE') <LikeOperator> end rule not_like_operator '' ('!=~' / 'not like' / 'NOT LIKE') <NotLikeOperator> end # Literals rule value null / boolean / number / datetime / string end rule number number_sign? (number_float / number_integer) number_exponent? <NumberLiteral> end rule number_integer number_base end rule number_float number_base '.' number_base end rule number_sign '+' / '-' end rule number_exponent 'e' number_base end rule number_base [0-9]+ end rule boolean boolean_true / boolean_false end rule boolean_true '' ('true' / 'TRUE' / 'on' / 'ON' / 'yes' / 'YES') <BooleanLiteral> { def data return true end } end rule boolean_false '' ('false' / 'FALSE' / 'off' / 'OFF' / 'no' / 'NO') <BooleanLiteral> { def data return false end } end rule null '' ('null' / 'NULL' / 'nil' / 'NIL' / 'nul' / 'NUL') <NullLiteral> end rule datetime string &{ |s| begin DateTime.parse(s.first.data) return true rescue return false end } <DatetimeLiteral> end rule string '' (string_single / string_double) <StringLiteral> end rule string_single "'" ([^'\\] / "\\" . )* "'" end rule string_double '"' ([^"\\] / "\\" . )* '"' end rule identifier [a-zA-Z] [a-zA-Z0-9_.]* <Identifier> end # Whitespace rule space [\s]+ end
end