Skip to content

Grammar Reference

The complete BNF grammar for Ceramic, organized by chapter.

  • Regular expressions use /slashes/ with Perl /x syntax (whitespace inside is insignificant).
  • Literal strings are written in "quotation marks".

Tokenization

Whitespace

→ context in tokenization.md

ws -> /[ \t\r\n\f]+/

Comments

→ context in tokenization.md

Comment -> "/*" /.*?/ "*/"
         | "//" /.*$/

Identifiers

→ context in tokenization.md

Identifier -> !Keyword, /[A-Za-z_?][A-Za-z_0-9?]*/

Integer Literals

→ context in tokenization.md

IntToken      -> "0x" HexDigits | DecimalDigits
HexDigits     -> /([0-9A-Fa-f]_*)+/
DecimalDigits -> /([0-9]_*)+/

Floating-Point Literals

→ context in tokenization.md

FloatToken -> "0x" HexDigits ("." HexDigits?)? /[pP] [+-]?/ DecimalDigits
            | DecimalDigits ("." DecimalDigits?)? (/[eE] [+-]?/ DecimalDigits)?

Character Literals

→ context in tokenization.md

CharToken  -> "'" CharChar "'"
CharChar   -> /[^\\']/
           | EscapeCode
EscapeCode -> /\\ ([nrtf\\'"0] | x [0-9A-Fa-f]{2})/

String Literals

→ context in tokenization.md

StringToken      -> "\"" StringChar* "\""
                  | "\"\"\"" TripleStringChar* "\"\"\""
StringChar       -> /[^\\"]/  | EscapeCode
TripleStringChar -> /(?!=""" ([^"]|$)) [^\\]/ | EscapeCode

Compilation Strategy

Pattern Matching

→ context in compilation.md

Pattern        -> AtomicPattern PatternSuffix?
AtomicPattern  -> Literal | PatternNameRef
PatternNameRef -> DottedName
PatternSuffix  -> "[" comma_list(Pattern) "]"

Modules & Source Layout

Source File Layout

→ context in modules.md

Module -> Import* ModuleDeclaration? TopLevelLLVM? TopLevelItem*

List Syntactic Forms

→ context in modules.md

comma_list(Rule) -> (Rule ("," Rule)* ","?)?

variadic_list(Rule, LastRule) -> Rule ("," Rule)* ("," (LastRule)?)?
                               | LastRule
                               | nil

Conflict Resolution

→ context in modules.md

Import       -> Visibility? "import" DottedName ImportSpec? ";"
ImportSpec   -> "as" Identifier
              | "." "(" comma_list(ImportedItem) ")"
              | "." "*"
DottedName   -> Identifier ("." Identifier)*
ImportedItem -> Visibility? Identifier ("as" Identifier)?

Module Declaration

→ context in modules.md

ModuleDeclaration -> "in" DottedName AttributeList? ";"
AttributeList     -> "(" ExprList ")"

Top-Level LLVM

→ context in modules.md

TopLevelLLVM -> LLVMBlock
LLVMBlock    -> "__llvm__" "{" /.*/ "}"

Pattern Guards

→ context in modules.md

PatternGuard -> "[" comma_list(PatternVar) ("|" Expression)? "]"
PatternVar   -> Identifier | ".." Identifier

Visibility Modifiers

→ context in modules.md

Visibility -> "public" | "private"

Type Definitions

Computed Layouts

→ context in types.md

Record             -> PatternGuard? Visibility? "record" TypeDefinitionName RecordBody
TypeDefinitionName -> Identifier PatternVars?
PatternVars        -> "[" comma_list(PatternVar) "]"
NormalRecordBody   -> "(" comma_list(RecordField) ")" ";"
ComputedRecordBody -> "=" comma_list(Expression) ";"
RecordField        -> Identifier TypeSpec
TypeSpec           -> ":" Pattern

Extending Variants

→ context in types.md

Variant  -> PatternGuard? Visibility? "variant" TypeDefinitionName ("(" ExprList ")")? ";"
Instance -> PatternGuard? "instance" Pattern "(" ExprList ")" ";"

Enumerations

→ context in types.md

Enumeration -> Visibility? "enum" Identifier "(" comma_list(Identifier) ")" ";"

Function Definitions

Simple Function Definitions

→ context in functions.md

Function -> PatternGuard? Visibility? CodegenAttribute?
            Identifier Arguments ReturnSpec? FunctionBody

Universal Overloads

→ context in functions.md

Define   -> PatternGuard? "define" Identifier (Arguments ReturnSpec?)? ";"
Overload -> PatternGuard? CodegenAttribute? "overload"
            Pattern Arguments ReturnSpec? FunctionBody

Static Arguments

→ context in functions.md

Arguments          -> "(" ArgumentList ")"
ArgumentList       -> variadic_list(Argument, VarArgument)
Argument           -> NamedArgument | StaticArgument
NamedArgument      -> ReferenceQualifier? Identifier TypeSpec?
VarArgument        -> ReferenceQualifier? ".." Identifier TypeSpec?
StaticArgument     -> "static" Pattern
ReferenceQualifier -> "ref" | "rvalue" | "forward"

Named Return Values

→ context in functions.md

ReturnSpec      -> ReturnTypeSpec | NamedReturnSpec
ReturnTypeSpec  -> ":" ExprList
NamedReturnSpec -> "-->" comma_list(NamedReturn)
NamedReturn     -> ".."? Identifier ":" Expression

Inline LLVM Functions

→ context in functions.md

FunctionBody -> Block | "=" ReturnExpression ";" | LLVMBlock
LLVMBlock    -> "__llvm__" "{" /.*/ "}"

Diagnostic Attributes

→ context in functions.md

Attributes -> "[[" Identifier ("," Identifier)* "]]"

External Attributes

→ context in functions.md

ExternalFunction -> Visibility? "external" AttributeList?
                    Identifier "(" ExternalArgs ")"
                    ":" Type? (FunctionBody | ";")
ExternalArgs     -> variadic_list(ExternalArg, "..")
ExternalArg      -> Identifier TypeSpec

Global Aliases

→ context in functions.md

GlobalAlias -> PatternGuard? Visibility?
               "alias" Identifier PatternVars? "=" Expression ";"

Global Variables

→ context in functions.md

GlobalVariable -> PatternGuard? Visibility?
                  "var" Identifier PatternVars? "=" Expression ";"

External Variables

→ context in functions.md

ExternalVariable -> Visibility? "external" AttributeList? Identifier TypeSpec ";"

Statements

Blocks

→ context in statements.md

Block    -> "{" (Statement | Binding | LabelDef)* "}"
LabelDef -> Identifier ":"

Return by Reference

→ context in statements.md

ReturnStatement  -> "return" ReturnExpression? ";"
ReturnExpression -> ReturnKind? ExprList
ReturnKind       -> "ref" | "forward"

alias: call-by-name binding

→ context in statements.md

Binding     -> BindingKind comma_list(Identifier) "=" ExprList ";"
BindingKind -> "var" | "ref" | "forward" | "alias"

Initialization Statements

→ context in statements.md

Assignment   -> ExprList AssignmentOp ExprList ";"
AssignmentOp -> "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<--"

switch

→ context in statements.md

IfStatement     -> "if" "(" Expression ")" Statement ("else" Statement)?
SwitchStatement -> "switch" "(" Expression ")"
                   ("case" "(" ExprList ")" Statement)*
                   ("else" Statement)?

..for: Multiple-Value For

→ context in statements.md

WhileStatement         -> "while" "(" Expression ")" Statement
ForStatement           -> "for" "(" comma_list(Identifier) "in" Expression ")" Statement
MultiValueForStatement -> ".." "for" "(" Identifier "in" ExprList ")" Statement

goto

→ context in statements.md

BreakStatement    -> "break" ";"
ContinueStatement -> "continue" ";"
GotoStatement     -> "goto" Identifier ";"

finally and onerror

→ context in statements.md

ThrowStatement      -> "throw" Expression ";"
TryStatement        -> "try" Block ("catch" "(" (Identifier (":" Type)?) ")" Block)+
ScopeGuardStatement -> ScopeGuardKind Statement
ScopeGuardKind      -> "finally" | "onerror"

Eval Statements

→ context in statements.md

EvalStatement -> "eval" ExprList ";"

Expressions

Lambda Expressions

→ context in expressions.md

Lambda          -> LambdaArguments LambdaArrow LambdaBody
LambdaArguments -> ".."? Identifier | Arguments
LambdaArrow     -> "=>" | "->"
LambdaBody      -> Block | ReturnExpression