Skip to content
Grammar · v0.9.0

Formal grammar (EBNF)

The portal subset grammar in Extended Backus–Naur Form. This does not include all Python runtime features. Use the complete UTF 101 manual for released syntax.

thirsty-lang.ebnf
program     = { statement } ;

statement   = module
            | context
            | drink
            | glass
            | pour
            | return
            | policy
            | exprStmt ;

module      = "module" IDENT ":" ( "core" | "governed" ) [ ";" ] ;
context     = "context" "{" { field } "}" ;
field       = IDENT ":" expr [ "," ] ;
drink       = "drink" IDENT [ ":" IDENT ] "=" expr [ ";" ] ;
glass       = "glass" IDENT "(" [ params ] ")"
              [ "requires" expr ] [ "ensures" expr ] block ;
params      = IDENT [ ":" IDENT ] { "," IDENT [ ":" IDENT ] } ;
pour        = "pour" expr [ ";" ] ;
return      = "return" expr [ ";" ] ;
policy      = "policy" IDENT { context | rule } ;
context     = "context" "{" { field } "}" ;
rule        = "when" expr "=>" ( "ALLOW" | "DENY" | "ESCALATE" ) [ ";" ] ;
block       = "{" { statement } "}" ;
exprStmt    = expr [ ";" ] ;

expr        = orExpr ;
orExpr      = andExpr  { ( "or"  | "||" ) andExpr } ;
andExpr     = eqExpr   { ( "and" | "&&" ) eqExpr } ;
eqExpr      = cmpExpr  { ( "==" | "!=" ) cmpExpr } ;
cmpExpr     = addExpr  { ( "<" | ">" | "<=" | ">=" | "in" ) addExpr } ;
addExpr     = mulExpr  { ( "+" | "-" ) mulExpr } ;
mulExpr     = unary    { ( "*" | "/" | "%" ) unary } ;
unary       = ( "not" | "!" | "-" ) unary | postfix ;
postfix     = primary { "." IDENT } ;
primary     = NUMBER | STRING | "true" | "false" | "null"
            | list | object | call | IDENT | "(" expr ")" ;
list        = "[" [ expr { "," expr } ] "]" ;
object      = "{" [ field { field } ] "}" ;
call        = IDENT "(" [ expr { "," expr } ] ")" ;

(* Lexical *)
IDENT       = LETTER { LETTER | DIGIT | "_" } ;
NUMBER      = DIGIT { DIGIT | "_" } [ "." DIGIT { DIGIT } ] ;
STRING      = '"' { CHAR } '"' | "'" { CHAR } "'" ;
COMMENT     = ( "//" | "#" ) { CHAR } NEWLINE ;
Precedence (low → high)
  1. or (||)
  2. and (&&)
  3. == !=
  4. < > <= >=
  5. + -
  6. * / %
  7. unary not ! -
  8. member access .
Lexical notes
  • Line comments start with //.
  • Numeric literals may use _ as a digit separator (e.g. 12_000).
  • Strings are double-quoted and support \n, \t escapes.
  • Statement terminators (;) are optional.
  • and/or/not are word-aliases for && || !.