Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Lexical conventions

The lexer divides source characters into tokens. It uses Rust token trees and inherits many behaviors from the Rust lexical structure. For the full CEL expression grammar, see the Reference Manual.

Syntax

compound_token = "&&" | "||" | "==" | "!=" | "<=" | ">="
               | "<<" | ">>" | ".." | "..=" .
identifier = identifier_start { identifier_continue } .

Whitespace and compound tokens

Spaces, tabs, and line breaks separate tokens. They do not otherwise change the meaning of an expression.

x + 1
x+1
if flag {
    1
} else {
    2
}

Adjacent punctuation characters combine into single tokens: &&, ||, ==, !=, <=, >=, <<, >>, .., and ..=.

a&&b
x<=y
1..=5

Comments and trivia

Comments may appear between tokens wherever whitespace is allowed.

x /* midpoint */ + 1
if ready { 1 } // done
else { 0 }

Line comments use // .... Block comments use /* ... */.

Identifiers and reserved words

An identifier is a non-empty name made from Unicode identifier characters. The first character may be a Unicode letter or _; later characters may also include Unicode digits. CEL follows the Rust identifier rules for the spellings that its lexer accepts.

x
user_name
value2
π
_temporary

These words are reserved for fixed roles in CEL source and cannot name user-defined values:

  • if
  • else
  • as
  • true
  • false

true and false are boolean literals. if and else introduce conditional expressions. as introduces an explicit cast. This restriction applies to value references and closure parameters. Member labels, record field labels, and type names have separate namespaces; CEL does not apply the value-name restriction to them. Boolean tokens remain literals in every namespace.

Literal tokens

The lexer recognizes these literal token categories:

  • integer literals
  • floating-point literals
  • string literals
  • boolean literals
  • character literals
  • byte literals
  • byte-string literals
  • C-string literals
42
3.5
"hello"
true
'a'
b'A'
b"bytes"
c"header"

The grammar defines the unit value (); it is not a literal token.

Delimiters and punctuation

CEL uses three delimiter pairs:

  • ( ) for grouping, unit, tuples, calls, and closure parameter types
  • [ ] for arrays
  • { } for if branches

It uses these structural punctuation marks inside expressions:

  • , between tuple elements, array elements, and call arguments
  • : in typed closure parameters
  • . before an unsuffixed tuple index
(1, 2)
[0, 1, 2]
|x: i32| x + 1
point.0

Operators

Operator tokens carry arithmetic, comparison, logical, bitwise, cast, and range syntax.

+ - * / %
== != < <= > >=
! && ||
& | ^ << >>
as
.. ..=

The grammar determines where each operator may appear and how tightly it binds. See Reference Manual for the full expression grammar.