CEL Specification#
This page summarizes the canonical CEL specification. Refer to the official specification for authoritative details.
Grammar#
CEL expressions follow this grammar. Operator precedence is encoded in the production hierarchy, from lowest (conditional) to highest (primary).
Notation#
The grammar uses Extended Backus-Naur Form (EBNF):
| Notation | Meaning |
|---|---|
= |
Definition |
| |
Alternation |
[] |
Optional (zero or one) |
{} |
Repetition (zero or more) |
() |
Grouping |
"x" |
Terminal string |
UPPER |
Terminal (token) |
Lower |
Non-terminal (production) |
Expressions#
An expression is a conditional, which may include a ternary operator.
Logical operators#
Logical OR has lower precedence than logical AND.
ConditionalOr = ConditionalAnd { "||" ConditionalAnd } ;
ConditionalAnd = Relation { "&&" Relation } ;
Relational operators#
Comparison and membership operators.
Arithmetic operators#
Addition and subtraction have lower precedence than multiplication.
Addition = Multiplication { ( "+" | "-" ) Multiplication } ;
Multiplication = Unary { ( "*" | "/" | "%" ) Unary } ;
Negation#
Negation and logical NOT.
Member access#
Field access, indexing, and method calls.
Primary expressions#
Literals, identifiers, parenthesized expressions, and constructors.
Primary = [ "." ] IDENT [ "(" [ ExprList ] ")" ]
| "(" Expr ")"
| "[" [ ExprList ] [ "," ] "]"
| "{" [ MapInits ] [ "," ] "}"
| [ "." ] IDENT { "." IDENT } "{" [ FieldInits ] [ "," ] "}"
| LITERAL
;
ExprList = Expr { "," Expr } ;
FieldInits = IDENT ":" Expr { "," IDENT ":" Expr } ;
MapInits = Expr ":" Expr { "," Expr ":" Expr } ;
Terminals#
IDENT = letter { letter | digit | "_" } ;
LITERAL = int_lit | uint_lit | float_lit | string_lit | bytes_lit
| "true" | "false" | "null"
;
Reserved words#
as break const continue else false
for function if import in let
loop namespace null package return true
var void while
Literals#
int_lit = DIGIT { DIGIT } | "0x" HEXDIGIT { HEXDIGIT } ;
uint_lit = int_lit ( "u" | "U" ) ;
float_lit = DIGIT { DIGIT } "." { DIGIT } [ EXPONENT ]
| DIGIT { DIGIT } EXPONENT
| "." DIGIT { DIGIT } [ EXPONENT ]
;
EXPONENT = ( "e" | "E" ) [ "+" | "-" ] DIGIT { DIGIT } ;
string_lit = [ "r" | "R" ] ( RAW_STRING | ESCAPED_STRING ) ;
bytes_lit = ( "b" | "B" ) string_lit ;
RAW_STRING = "'" { CHAR } "'" | '"' { CHAR } '"'
| "'''" { CHAR } "'''" | '"""' { CHAR } '"""'
;
ESCAPED_STRING = "'" { CHAR | ESCAPE } "'" | '"' { CHAR | ESCAPE } '"'
| "'''" { CHAR | ESCAPE } "'''" | '"""' { CHAR | ESCAPE } '"""'
;
ESCAPE = "\" ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | "\" | "'" | '"' | "`" )
| "\" "x" HEXDIGIT HEXDIGIT
| "\" "u" HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT
| "\" "U" HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT
| "\" OCTALDIGIT OCTALDIGIT OCTALDIGIT
;
CHAR = <any Unicode code point> ;
DIGIT = "0" ... "9" ;
HEXDIGIT = "0" ... "9" | "a" ... "f" | "A" ... "F" ;
OCTALDIGIT = "0" ... "7" ;
Comments and whitespace#
CEL supports single-line comments starting with // and extending to the end of the line.
Whitespace (spaces, tabs, carriage returns, newlines) separates tokens but is otherwise ignored. Comments and whitespace may appear anywhere between tokens.
Conformance#
The conformance test suite verifies implementations against the specification.
See also#
- At a glance - Every function, macro, and operator