hel 0.2.0

HEL — Heuristic Expression Language: a deterministic, auditable expression language & parser, AST, builtin registry and evaluator.
Documentation
WHITESPACE      = _{ " " | "\t" | "\n" | "\r" }

condition       =  { logical_or }

logical_or      =  { logical_and ~ (or_op ~ logical_and)* }
logical_and     =  { term ~ (and_op ~ term)* }
term            =  { comparison_term | primary }

comparison_term = { comparison | primary }

primary         = { parenthesized | literal | function_call | attribute_access | symbolic | variable | identifier }

parenthesized   = { "(" ~ condition ~ ")" }

literal         = { list_literal | map_literal | string_literal | float_literal | number_literal | boolean_literal }

// List literal: [1, 2, 3] or ["a", "b", "c"]
list_literal    = { "[" ~ (primary ~ ("," ~ primary)*)? ~ "]" }

// Map literal: {"key": value, "key2": value2}
map_literal     = { "{" ~ (map_entry ~ ("," ~ map_entry)*)? ~ "}" }
map_entry       = { string_literal ~ ":" ~ primary }

string_literal  = { "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
float_literal   = @{ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT+ }
number_literal  = { ("0x" ~ ASCII_HEX_DIGIT+) | ASCII_DIGIT+ }
boolean_literal = { "true" | "false" }

identifier      = @{ (ASCII_ALPHANUMERIC | "_")+ }
variable        = @{ "$" ~ (ASCII_ALPHANUMERIC | "_")+ }
symbolic        = @{ "%" ~ (ASCII_ALPHANUMERIC | "_")+ }

// Function call: func(args) or namespace.func(args)
function_call   = { identifier ~ ("." ~ identifier)? ~ "(" ~ (primary ~ ("," ~ primary)*)? ~ ")" }

// Attribute access: object.field (but not followed by parentheses)
attribute_access = { identifier ~ ("." ~ identifier)+ ~ !("(") }

comparison      = { primary ~ comparator ~ primary }
comparator      = { "==" | "!=" | ">=" | "<=" | ">" | "<" | "CONTAINS" | "IN" }

or_op           = _{ "||" | "OR" | "or" }
and_op          = _{ "&&" | "AND" | "and" }