Skip to content

Grammar (EBNF)

Generated from grammar/sema.ebnf, the single source of truth kept in sync with the spec by grammar/check-drift.sh.

file = { statement } ;
statement = import_stmt | ported_import | native_import | def | ported_def
| agent_decl | circuit_decl
| operator_decl | bridge_decl | template_decl | context_decl
| args_decl | config_decl | container_decl | component_decl | provide_decl
| collector_decl | worker_decl | struct | enum_decl | trait_decl | impl_decl
| model_decl | policy_decl | policy_attach | service_decl
| monitor_decl | protocol_decl | supervise | event_decl | subscriber_decl
| sem_decl | assure_decl | test_decl
| match_stmt | with_stmt | expect_stmt | scope_block | yield_stmt
| breakpoint_stmt | simple_stmt ;
import_stmt = [ "pub"? ] ( "import" qualified_name [ "as" IDENT ]
| "from" qualified_name "import" IDENT [ "as" IDENT ]
{ "," IDENT [ "as" IDENT ] } ) NEWLINE ;
struct = [ "pub"? ] "struct" IDENT [ type_params ] [ "(" trait_list ")" ] ":" NEWLINE INDENT
{ field_decl | contract_clause | sem_decl | def | const_bind } DEDENT ;
enum_decl = [ "pub"? ] "enum" IDENT [ type_params ] [ "(" trait_list ")" ] ":" NEWLINE INDENT
{ variant_decl | sem_decl | def } DEDENT
| "enum" IDENT ":" IDENT { "|" IDENT } ; (* inline sugar *)
type_params = "[" type_param { "," type_param } "]" ; (* generics, erased §5.29 *)
type_param = IDENT [ ":" IDENT { "+" IDENT } ] ; (* optional trait bounds §3.9 *)
variant_decl = IDENT [ "(" params ")" ] NEWLINE ;
trait_decl = [ "pub"? ] "trait" IDENT [ "(" trait_list ")" ] ":" NEWLINE INDENT
{ def_sig | def | law_clause | sem_decl | "sem"? STRING NEWLINE } DEDENT ;
(* "(" trait_list ")" = supertraits; `def_sig` = required method,
`def` (with a block) = default (provided) method, §3.9 *)
law_clause = "law" IDENT ":" expr NEWLINE ;
impl_decl = "impl" IDENT "for" type ":" NEWLINE INDENT { def } DEDENT ;
trait_list = IDENT { "," IDENT } ;
const_bind = IDENT "=" expr NEWLINE ;
field_decl = IDENT ":" type [ "sem" STRING ] [ "where" expr ]
[ "coerce" "by" qualified_name ] NEWLINE ;
def = { decorator } [ "pub"? ] [ "simulate" ] [ "stream"? ] [ "mut"? ]
"def" IDENT [ type_params ] "(" [ params ] ")" [ "->" type ] [ "!" effect_row ]
[ "by" expr ] ":" block ;
agent_decl = { decorator } [ "pub"? ] "agent" IDENT [ type_params ]
"(" [ params ] ")" [ "->" type ] [ "!" effect_row ]
[ "by" expr ] ":" block ;
circuit_decl = { decorator } [ "pub"? ] "circuit" IDENT [ type_params ]
"(" [ params ] ")" [ "->" type ] [ "!" effect_row ]
":" block ;
params = param { "," param } ;
param = [ "*" | "**" ] IDENT [ ":" type ] [ "=" expr ] ; (* *args / **kwargs §5.29 *)
operator_decl = { decorator } [ "simulate" ] "operator" operator_head
"(" [ params ] ")" [ "->" type ] [ "!" effect_row ]
[ "by" expr ] ":" block ;
operator_head = operator_token
| "infix" STRING "precedence" precedence_class ;
operator_token = "+" | "-" | "*" | "/" | "%" | "&" | "|" | "^" | "<<"
| ">>" | "==" | "~=" ;
precedence_class= "additive" | "multiplicative" | "comparison" | "logical" ;
block = simple_stmt { ";" simple_stmt } NEWLINE (* inline suite *)
| NEWLINE INDENT { contract_clause | statement } DEDENT ;
contract_clause = ( "require" | "ensure" | "invariant" ) expr NEWLINE
| "check" expr NEWLINE
| "sem"? STRING NEWLINE
| "budget" kwargs NEWLINE
| "repair" kwargs NEWLINE (* simulate def bodies only, §5.22 *)
| "use" ( "template" call_expr | "context" call_expr
| "protocol" qualified_name
| "tools" "[" [ expr { "," expr } ] "]" ) NEWLINE ;
effect_row = "{" [ effect { "," effect } ] "}" ;
(* "*" is the all-effects wildcard (top); §3.6. An OMITTED row
is inferred/fail-closed, not a wildcard, and is required
explicitly at `assure silver`+. *)
effect = "*"
| ("model" | "fs" | "net" | "proc" | "code" | "memory" | "db"
| "env" | "config" | "observe" | "event" | "policy" | "package"
| "ui" | "human" | "agent") "." IDENT [ "(" [ args ] ")" ]
| "clock" | "random" | "ffi.call" ;
match_stmt = "match" expr ":" NEWLINE INDENT { case_clause } DEDENT ;
case_clause = "case" pattern [ "if" expr ] ":" block ;
pattern = or_pattern ;
or_pattern = base_pattern { "|" base_pattern } ;
base_pattern = "_" | literal_pattern | regex_pattern | struct_pattern | enum_pattern
| tuple_pattern | bind_pattern ;
literal_pattern = NUMBER | STRING | "true" | "false" ;
struct_pattern = qualified_name "(" [ IDENT "=" pattern { "," IDENT "=" pattern } ] ")" ;
enum_pattern = qualified_name [ "(" pattern { "," pattern } ")" ] ;
tuple_pattern = "(" pattern { "," pattern } ")" ;
bind_pattern = IDENT ;
regex_pattern = "re" STRING ;
destructure = pattern "=" expr NEWLINE ; (* irrefutable patterns only *)
template_expr = ( "f" | "sql" ) STRING ;
validate_expr = "validate" expr ":" block ;
with_stmt = "with" ( "policy" "(" expr ")"
| qualified_name "=" expr
| expr [ "as" IDENT ] ) ":" block ;
expect_stmt = "expect" ( semantics_pred | IDENT "=" expr | expr ) ":" block
{ "except" IDENT [ "as" IDENT ] ":" block } ;
try_expr = expr "?" ;
comprehension = "[" expr "for" pattern "in" expr [ "if" expr ] "]"
| "{" expr ":" expr "for" pattern "in" expr [ "if" expr ] "}"
| "{" expr "for" pattern "in" expr [ "if" expr ] "}" ;
list_comp = "[" expr "for" pattern "in" expr [ "if" expr ] "]" ;
mut_bind = "mut" IDENT [ ":" type ] "=" expr NEWLINE ;
(* plain bindings admit the same optional ":" type annotation *)
template_decl = "template" IDENT "(" [ params ] ")" "->" prompt_type ":"
template_block ;
template_block = NEWLINE INDENT { template_item | contract_clause | statement } DEDENT ;
template_item = "role" role_name ":" template_block | "text" text_expr NEWLINE
| "use" "template" call_expr NEWLINE ;
text_expr = STRING | "f" STRING ;
role_name = "system" | "developer" | "user" | "assistant" | "tool" | "data"
| IDENT ;
prompt_type = "Prompt" "[" type "]" ;
context_decl = "context" IDENT ":" NEWLINE INDENT { context_item } DEDENT ;
context_item = "model" expr NEWLINE
| "state" IDENT { "|" IDENT } NEWLINE
| "slot" IDENT "role" role_name [ "retention" expr ]
[ "budget" kwargs ] "=" expr NEWLINE
| "transition" IDENT "->" IDENT "on" call_sig ":"
context_block ;
context_block = NEWLINE INDENT { context_action | contract_clause | statement } DEDENT ;
context_action = ( "replace" | "append" | "drop" ) "slot" IDENT
[ "role" role_name ] [ "=" expr ] NEWLINE ;
sem_decl = "sem"? qualified_name "=" STRING NEWLINE ;
model_decl = "model"? IDENT "=" "model" "(" args ")" NEWLINE ;
args_decl = "args" IDENT ":" NEWLINE INDENT { arg_item } DEDENT ;
arg_item = IDENT ":" type "=" ( "option" | "flag" ) "(" args ")" NEWLINE ;
config_decl = "config" IDENT ":" NEWLINE INDENT { config_item } DEDENT ;
config_item = "source" config_source NEWLINE
| config_field | contract_clause ;
config_field = IDENT ":" ( config_leaf | config_block ) ;
config_leaf = type [ "=" expr ] [ "sem" STRING ] [ "where" expr ] NEWLINE ;
config_block = NEWLINE INDENT { config_item } DEDENT ;
config_source = ( "yaml" | "json" | "toml" ) expr [ "optional" ]
| "env" "prefix" STRING
| "cli" expr ;
container_decl = "container" IDENT ":" NEWLINE INDENT { container_item } DEDENT ;
container_item = "args" IDENT NEWLINE
| "config" IDENT NEWLINE
| "bind" type [ "named" STRING ] [ "=" expr ] [ "lifetime" lifetime ] NEWLINE
| "expose" IDENT NEWLINE ;
component_decl = "component" IDENT ":" NEWLINE INDENT { component_item } DEDENT ;
component_item = "lifetime" lifetime NEWLINE
| "inject" ":" NEWLINE INDENT { inject_field } DEDENT
| sem_decl | def ;
inject_field = IDENT ":" type [ "named" STRING ] [ "=" expr ] NEWLINE ;
provide_decl = "provide" IDENT "(" [ params ] ")" "->" type
[ "lifetime" lifetime ] ":" block ;
lifetime = "transient" | "singleton" | "scoped" "(" IDENT ")" ;
inject_expr = "inject" type [ "named" STRING ] ;
collector_decl = "collector" IDENT ":" NEWLINE INDENT { collector_item } DEDENT ;
collector_item = IDENT ":" type [ "mode" collector_mode ] [ "retention" expr ] NEWLINE
| "export" qualified_name kwargs NEWLINE
| "strict" NEWLINE ;
collector_mode = "series" | "histogram" | "stack" | "set" | "counts" | "bag"
| "last" ;
tap_expr = expr "|>" collector_sink ;
collector_sink = qualified_name [ "(" [ args ] ")" ] ;
worker_decl = "worker" IDENT ":" NEWLINE INDENT { worker_item } DEDENT ;
worker_item = "lane" IDENT NEWLINE
| "workers" ( "auto" | expr ) NEWLINE
| "batch" kwargs NEWLINE
| queue_clause
| "merge" parallel_merge NEWLINE
| "on_error" parallel_error NEWLINE
| "budget" kwargs NEWLINE ;
parallel_expr = "parallel" expr parallel_op lambda_expr [ parallel_opts ]
| "parallel" expr "reduce" expr "with" lambda_expr [ parallel_opts ]
| "parallel" "stream" expr "map" lambda_expr [ parallel_opts ]
| "parallel" list_comp ;
parallel_op = "map" | "filter" | "find" | "any" | "all" ;
parallel_opts = [ "by" expr ] [ parallel_merge ] [ "limit" expr ]
[ "chunk" expr ] [ "on_error" parallel_error ] ;
parallel_merge = "ordered" | "unordered" | "stable" ;
parallel_error = "fail_fast" | "collect" | "skip" ;
lambda_expr = IDENT "=>" expr | "(" [ params ] ")" "=>" expr
| "lambda" [ IDENT { "," IDENT } ] ":" expr ; (* §5.29 *)
conditional_expr= expr "if" expr "else" expr ; (* §3.1; lower
precedence than binary ops, higher than lambda; the `else`
branch is right-associative so it chains *)
list_expr = "[" [ list_elem { "," list_elem } ] "]" ;
list_elem = "..." expr | expr ; (* spread §5.29 *)
index_expr = expr "[" expr "]" ; (* subscript *)
slice_expr = expr "[" [ expr ] ":" [ expr ] [ ":" [ expr ] ] "]" ; (* §3.1 slice *)
is_expr = expr "is" [ "not" ] IDENT ; (* §3.9 type/trait
conformance test; the right side is a concrete type or a
trait name, and the result is `bool` *)
sim_expr = expr "~=" expr [ "with" kwargs ] ; (* semantic equality *)
sem_binop = expr sem_op expr | expr "~" "[" expr "]" ; (* §5.30 *)
sem_op = "~<" | "~>" | "~<=" | "~>=" | "~!=" (* ordering / inequality *)
| "~+" | "~-" (* combine / remove *)
| "~" "in" (* semantic membership *)
| "~" "and" | "~" "or" | "~" "xor" ; (* semantic logic gates *)
sem_unop = "~" "not" expr ; (* semantic negation *)
logic_op = expr ( "and" | "or" | "xor" ) expr | "not" expr ; (* strict boolean *)
bit_op = expr ( "&" | "|" | "^" | "<<" | ">>" ) expr | "bitnot" expr ;
arith_op = expr ( "+" | "-" | "*" | "/" | "%" ) expr (* §5.29 *)
| expr "**" expr ; (* power, right-assoc, tighter than * *)
semantics_pred = "semantics" "(" STRING { "," expr } [ "," kwargs ] ")" ;
(* `~` is the semantic sigil: `xs ~[q]`, `a ~< b`, `a ~+ b`, `a ~in b`, `a ~and
b`, `~not a`, etc. all derive `model.invoke`. Bitwise NOT is `bitnot` (since
`~` is reserved for semantics); strict boolean xor is `xor`. Semantic
primitives are the `semantic.<verb>(subject, query, ...)` namespace
(filter/rank/map/extract/summarize/translate/choose/query/combine/correct/
unique/similar/select). A type controls its semantic representation via the
coercion protocol — methods `sem_text(self) -> str` and/or `embed(self) ->
Embedding` (§5.30); pipelines attach via `with pipeline(pre=[..], post=[..])`. *)
policy_decl = "policy" IDENT ":" NEWLINE INDENT { policy_rule } DEDENT ;
policy_attach = "policy" "attach" IDENT NEWLINE ; (* module-level attachment, §5.8 *)
policy_rule = policy_single | policy_group | example_single | example_group
| "budget" IDENT comparator expr NEWLINE
| "justification" STRING NEWLINE ;
policy_single = "allow" effect_list [ "except" except_list ] [ "where" expr ] NEWLINE
| "forbid" [ "cap" ] effect_list [ "except" except_list ]
[ "where" expr ] NEWLINE ;
policy_group = "allow" ":" NEWLINE INDENT
{ effect_list [ "except" except_list ] [ "where" expr ] NEWLINE } DEDENT
| "forbid" [ "cap" ] ":" NEWLINE INDENT
{ effect_list [ "except" except_list ] [ "where" expr ] NEWLINE } DEDENT ;
effect_list = effect { "," effect } ;
except_list = ( effect | STRING ) { "," ( effect | STRING ) } ;
comparator = "<=" | "<" | "==" ;
example_single = "example" ( "allow" | "deny" ) ":" expr NEWLINE ;
example_group = "examples" ":" NEWLINE INDENT { example_case } DEDENT ;
example_case = ( "allow" | "deny" ) ":" NEWLINE INDENT { expr NEWLINE } DEDENT ;
monitor_decl = "monitor"? IDENT "on" qualified_name ":" NEWLINE INDENT
"capture" expr_list NEWLINE
"baseline" ( "from" IDENT | STRING ) NEWLINE
"test" expr NEWLINE
{ "on" IDENT ":" block } DEDENT ;
supervise = "supervise"? IDENT ":" NEWLINE INDENT
[ "restart" kwargs NEWLINE ] [ "fallback" expr NEWLINE ]
[ "heal" kwargs ":" heal_block ] { statement } DEDENT ;
heal_block = NEWLINE INDENT { "require" expr NEWLINE }
[ "rollout" IDENT { "->" IDENT } NEWLINE ] DEDENT ;
event_decl = [ "pub"? ] "event"? IDENT ":" NEWLINE INDENT
{ field_decl | sem_decl | contract_clause
| "key" qualified_name NEWLINE } DEDENT ;
emit_stmt = "emit" qualified_name "(" [ args ] ")" NEWLINE ;
subscriber_decl = "subscriber"? IDENT "on" qualified_name ":" NEWLINE INDENT
[ "sem"? STRING NEWLINE ] [ "where" expr NEWLINE ]
[ queue_clause ]
"handle" IDENT [ "!" effect_row ] ":" block DEDENT ;
queue_clause = "queue" expr [ "," "on_full" "=" IDENT ] NEWLINE ;
ported_def = "ported"? "def" IDENT "(" [ params ] ")" [ "->" type ]
"from" STRING ":" ported_block ;
ported_block = NEWLINE INDENT { contract_clause
| "differential" "against" IDENT NEWLINE } DEDENT ;
ported_import = "ported"? "import" STRING "as" IDENT NEWLINE ;
native_import = "native"? "import" ( qualified_name | STRING ) [ "as" IDENT ] NEWLINE ;
bridge_decl = "bridge" bridge_mode IDENT [ "from" STRING ] ":" NEWLINE
INDENT { bridge_expose | foreign_block | bridge_meta } DEDENT ;
bridge_mode = "python.inline" | "python.isolated" | "js.component"
| "js.host" | "node.host" | "c.abi" | "cpp.abi" ;
bridge_expose = "expose" def
| "expose" ":" NEWLINE INDENT { def } DEDENT ;
foreign_block = "begin" IDENT NEWLINE foreign_text "end" IDENT NEWLINE ;
bridge_meta = ( "deps" STRING | "link" STRING kwargs | "checksum" STRING
| "symbol" STRING ) NEWLINE ;
scope_block = "scope" ":" block ;
spawn_expr = "spawn" call_expr ;
protocol_decl = "protocol"? IDENT ":" NEWLINE INDENT { proto_transition } DEDENT ;
proto_transition= IDENT ":" type "->" IDENT { "|" IDENT } NEWLINE ;
assure_decl = "assure"? ( "bronze" | "silver" | "gold" ) NEWLINE ;
test_decl = "test"? STRING ":" block ; (* verification entry point, §5.7 *)
service_decl = [ "pub"? ] "service"? IDENT "at" expr ":" NEWLINE INDENT
{ def_sig | sem_decl | "sem"? STRING NEWLINE
| "budget" kwargs NEWLINE
| "use" "protocol" qualified_name NEWLINE } DEDENT ;
yield_stmt = "yield" expr NEWLINE ; (* stream def bodies only, §5.25 *)
breakpoint_stmt = "breakpoint"? [ "when" ( semantics_pred | expr ) ] NEWLINE ; (* §5.26 *)
equation_decl = "equation"? IDENT "(" [ params ] ")" [ "->" type ] ":" eq_block ;
equation_stmt = "equation"? ":" eq_block ; (* bindings flow outward, §5.28 *)
eq_block = NEWLINE INDENT { eq_item } DEDENT ;
eq_item = IDENT [ "(" [ params ] ")" ] ":=" math_expr NEWLINE
| "return" math_expr NEWLINE
| math_expr NEWLINE ;
(* math_expr is the §5.28 notation: quantifiers ∀/∃/∃! with `x ∈ D :` binders,
big operators Σ Π ⋃ ⋂ ∫ with _{binder} and ^{bound}, ∇/∂/d-dx/∇²/Δ,
min/max/argmin/argmax/sup/inf with binder subscripts and `s.t.` constraint
lists, ‖·‖_p, ⟨·,·⟩, |·|, set builder { x ∈ D : P }, ∪ ∩ \ ∈ ⊆, ¬ ∧ ∨ ⊕ ⇒ ⇔,
`^` as power, postfix `!` and `^T`, `:=` definitions, ranges a..b. ASCII
spellings (forall, exists, sum, prod, integral, grad, norm, inner, ...) are
token-equivalent. Machine-readable sub-grammar: grammar/math.ebnf. *)