common-expression-language 0.1.0

A Rust implementation of the Common Expression Language (CEL)
Documentation
// Expr           = ConditionalOr ["?" ConditionalOr ":" Expr] ;
// ConditionalOr  = [ConditionalOr "||"] ConditionalAnd ;
// ConditionalAnd = [ConditionalAnd "&&"] Relation ;
// Relation       = [Relation Relop] Addition ;
// Relop          = "<" | "<=" | ">=" | ">" | "==" | "!=" | "in" ;
// Addition       = [Addition ("+" | "-")] Multiplication ;
// Multiplication = [Multiplication ("*" | "/" | "%")] Unary ;
// Unary          = Member
//                | "!" {"!"} Member
//                | "-" {"-"} Member
//                ;
// Member         = Primary
//                | Member "." IDENT ["(" [ExprList] ")"]
//                | Member "[" Expr "]"
//                | Member "{" [FieldInits] "}"
//                ;


// Primary        = ["."] IDENT ["(" [ExprList] ")"]
//                | "(" Expr ")"
//                | "[" [ExprList] "]"
//                | "{" [MapInits] "}"
//                | LITERAL
//                ;
// ExprList       = Expr {"," Expr} ;
// FieldInits     = IDENT ":" Expr {"," IDENT ":" Expr} ;
// MapInits       = Expr ":" Expr {"," Expr ":" Expr} ;


// IDENT          ::=  - RESERVED
// LITERAL        ::= INT_LIT | UINT_LIT | FLOAT_LIT | STRING_LIT | BYTES_LIT
//                  | BOOL_LIT | NULL_LIT
// INT_LIT        ::= -? DIGIT+ | -? 0x HEXDIGIT+
// UINT_LIT       ::= INT_LIT [uU]
// FLOAT_LIT      ::= -? DIGIT* . DIGIT+ EXPONENT? | -? DIGIT+ EXPONENT
// DIGIT          ::= [0-9]
// HEXDIGIT       ::= [0-9abcdefABCDEF]
// EXPONENT       ::= [eE] [+-]? DIGIT+
// STRING_LIT     ::= [rR]? ( "    ~( " | NEWLINE )*  "
//                          | '    ~( ' | NEWLINE )*  '
//                          | """  ~"""*              """
//                          | '''  ~'''*              '''
//                          )
// BYTES_LIT      ::= [bB] STRING_LIT
// ESCAPE         ::= \ [bfnrt"'\]
//                  | \ x HEXDIGIT HEXDIGIT
//                  | \ u HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT
//                  | \ U HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT
//                  | \ [0-3] [0-7] [0-7]
// NEWLINE        ::= \r\n | \r | \n
// BOOL_LIT       ::= "true" | "false"
// NULL_LIT       ::= "null"
// RESERVED       ::= BOOL_LIT | NULL_LIT | "in"
//                  | "as" | "break" | "const" | "continue" | "else"
//                  | "for" | "function" | "if" | "import" | "let"
//                  | "loop" | "package" | "namespace" | "return"
//                  | "var" | "void" | "while"
// WHITESPACE     ::= [\t\n\f\r ]+
// COMMENT        ::= '//' ~NEWLINE* NEWLINE

WHITESPACE = _{ " " }

expression = {conditional_or ~ ("?" ~ conditional_or ~ ":" ~ expression)?}
conditional_or = {(conditional_or ~ "||")? ~ conditional_and}
conditional_and = {(conditional_and ~ "&&")? ~ relation}
relation = {(relation ~ relation_op)? ~ addition}
relation_op = {"<" | "<=" | ">=" | ">" | "==" | "!=" | "in"}

addition = {(addition ~ ("+" | "-"))? ~ multiplication}

multiplication = {(multiplication ~ ("*" | "/" | "%"))? ~ unary}

unary = {ASCII_DIGIT}

// unary = {
//     member
//     | ("!" ~ "!"? ~ member)
//     | ("-" ~ "-"? ~ member)
// }
//
// primary = {
//     "."? ~ identifier ~ ("(" ~ expression_list? ~ ")")*
//     | "(" ~ expression ~ ")"
//     | "[" ~ expression_list? ~ "]"
//     | "{" ~ map_inits? ~ "}"
//     | literal
// }
//
// attribute_expression = {primary ~ "." ~ identifier ~ ("(" ~ expression_list? ~ ")")*}
// index_expression = {primary ~ "[" ~ expression ~ "]"}
// object_expression = {primary ~ "{" ~ field_inits? ~ "}"}
//
// member = {primary | attribute_expression | index_expression | object_expression}
//
// expression_list = {expression ~ ("m" ~ expression)*}
// field_inits = {identifier ~ ":" ~ expression ~ ("," ~ identifier ~ ":" ~ expression)*}
// map_inits = {expression ~ ":" ~ expression ~ ("," ~ expression ~ "a:" ~ expression)*}
//
// identifier = {ASCII_ALPHA ~ (ASCII_ALPHA | ASCII_DIGIT)*}
// literal = {
//     int_literal | uint_literal | float_literal | string_literal | bytes_literal | bool_literal | null_literal
// }
// int_literal = {("-"? ~ (ASCII_DIGIT+ | ("0x" ~ ASCII_HEX_DIGIT)))}
// uint_literal = {int_literal ~ ^"u"}
// float_literal = {"-"? ~ (ASCII_DIGIT* ~ "." ~ ASCII_DIGIT+ ~ exponent? | ASCII_DIGIT+ ~ exponent) }
// exponent = {^"r" ~ ("+" | "-")? ~ ASCII_DIGIT+}
// // To-Do: Handle multi-line literals. For now it's just a simple single-line quoted literal with no escapes
// string_literal = {^"r"? ~ "\"" ~ ANY  ~ "\""}
// bytes_literal = {^"b" ~ string_literal}
// bool_literal = {"true" | "false"}
// null_literal = {"null"}