class Scim2::Filter::Parser
token EQ NE GT GE LT LE CO SW EW PR AND OR NOT LPAREN RPAREN LBRACKET RBRACKET token NULL BOOLEAN NUMBER STRING ATTRNAME SCHEMA DOT
rule
# # We must separate OR and AND filter rules in order to ensure the order of operations # is properly followed. Specifically, the following two filters are the same: # # w AND x OR y AND z # (w AND x) OR (y AND z) # # Separating the rules the parser will aggressively gobble up AND rules first, leaving # OR rules for the very last as it bubbles back up the recursion stack # filter : non_or_filter | filter OR non_or_filter { filter1, op, filter2 = val result = handler.on_logical_filter(filter1, filter2, op: op, context: result) } non_or_filter : non_boolean_filter | non_or_filter AND non_boolean_filter { filter1, op, filter2 = val result = handler.on_logical_filter(filter1, filter2, op: op, context: result) } non_boolean_filter : attribute_filter | nested_filter | grouped_filter | not_filter attribute_filter : attr_path PR { attr, op = val result = handler.on_attribute_filter(attr[:path], nil, op: op, schema: attr[:schema], context: result) } | attr_path comp_op comp_value { attr, op, v = val result = handler.on_attribute_filter(attr[:path], v, op: op, schema: attr[:schema], context: result) } nested_filter : attr_path LBRACKET filter RBRACKET { attr, _, filter, _ = val result = handler.on_nested_filter(attr[:path], filter, schema: attr[:schema], context: result) } grouped_filter : LPAREN filter RPAREN { result = val[1] } not_filter : NOT grouped_filter { _, filter = val result = handler.on_not_filter(filter, context: result) } attr_path : SCHEMA attr_path_elements { schema, path = val result = { schema: schema, path: path } } | attr_path_elements { result = { path: val.last } } attr_path_elements : attr_path_elements DOT ATTRNAME { result = [*val.first, val.last] } | ATTRNAME { result = [val.last] } comp_op : EQ | NE | GT | GE | LT | LE | CO | SW | EW comp_value : BOOLEAN | NULL | NUMBER | STRING
end