(* Conlang Expression Grammar *) Start = File EOI ; Mutability = "mut"? ; Visibility = "pub"? ; File = Item* ; Attrs = ('#' '[' (Meta ',')* Meta? ']')* ; Meta = Identifier ('=' Literal | '(' (Literal ',')* Literal? ')')? ; Item = Attrs Visibility ItemKind ; ItemKind = Const | Static | Module | Function | Struct | Enum | Alias | Impl | Use ; (* item *) Const = "const" Identifier ':' Ty '=' Expr ';' ; Static = "static" Mutability Identifier ':' Ty '=' Expr ';' ; Module = "mod" Identifier ModuleKind ; ModuleKind = '{' Item* '}' | ';' ; Function = "fn" Identifier '(' (Param ',')* Param? ')' ('->' Ty)? Block? ; Param = Mutability Identifier ':' Ty ; Struct = "struct" Identifier (StructTuple | StructBody)?; StructBody = '{' (StructMember ',')* StructMember? '}' ; StructTuple = TyTuple ; StructMember = Visibility Identifier ':' Ty ; Enum = "enum" Identifier '{' (Variant ',')* Variant? '}' ; Variant = Identifier (VarStruct | VarTuple | VarCLike)? ; VarStruct = '{' (StructMember ',')* StructMember? '}' ; VarTuple = TyTuple ; VarCLike = '=' INTEGER ; Alias = "type" Identifier ('=' Ty)? ';' ; Impl = "impl" Path '{' Item* '}' ; (* TODO: Impl Trait for Target*) Use = "use" '::'? UseTree ';' ; UseTree = '*' | '{' (UseTree ',')* UseTree? '}' | PathPart ('::' UseTree | "as" Identifier)? ; (* type *) Ty = Never | Empty | Path | TyArray | TySlice | TyTuple | TyRef | TyFn ; Never = '!' ; Empty = '(' ')' ; TyTuple = '(' (Ty ',')* Ty? ')' ; TyArray = '[' Ty ';' INTEGER ']' ; TySlice = '[' Ty ']' ; TyRef = Amps* Path ; Amps = '&' | '&&' ; TyFn = "fn" TyTuple ('->' Ty)? ; (* path *) Path = PathPart ('::' PathPart)* | '::' (PathPart ('::' PathPart)*)? ; PathPart = "super" | "self" | "Self" | Identifier ; Identifier = IDENTIFIER ; (* statement *) Stmt = ';' | (Let | Item | Expr) Semi ; Semi = ';'? ; Let = "let" Mutability Identifier (':' Ty)? ('=' Expr)? ; (* TODO: Closure syntax *) (* Closure = "cl" '(' Param* ')' Block ; *) (* literal *) Bool = "true" | "false" ; (* expr *) Expr = Assign ; Assign = Path (AssignKind Assign ) | Modify ; Modify = Path (ModifyKind Assign ) | Compare ; (* Binary = Compare | Range | Logic | Bitwise | Shift | Factor | Term ; *) Compare = Range (CompareOp Range )* ; Range = Logic (RangeOp Logic )* ; Logic = Bitwise (LogicOp Bitwise)* ; Bitwise = Shift (BitwiseOp Shift )* ; Shift = Factor (ShiftOp Factor )* ; Factor = Term (FactorOp Term )* ; Term = Unary (TermOp Unary )* ; Unary = (UnaryKind)* Cast ; Cast = Member ("as" Ty)? ; Member = Call (Access)* ; Access = '.' (Identifier ('(' Tuple? ')')? | Literal) ; Call = Index ('(' Tuple? ')')* ; Index = Primary ('[' Indices ']')* ; Indices = (Expr ',')* Expr? ; Primary = Literal | PathLike | Array | ArrayRep | AddrOf | Block | Group | Loop | If | While | For | Break | Return | Continue; Literal = STRING | CHARACTER | FLOAT | INTEGER | Bool ; PathLike = Path | Structor ; Structor = Path ':' '{' (Fielder ',')* Fielder? '}' ; Fielder = Identifier ('=' Expr)? ; Array = '[' (Expr ',')* Expr? ']' ; ArrayRep = '[' Expr ';' Expr ']' ; AddrOf = Amps Amps* Mutability Expr ; Block = '{' Stmt* '}'; Group = Empty | '(' (Expr | Tuple) ')' ; Tuple = (Expr ',')* Expr? ; Loop = "loop" Block ; While = "while" Expr Block Else ; If = "if" Expr Block Else ; For = "for" Identifier "in" Expr Block Else ; Else = ("else" Expr)? ; Break = "break" Expr ; Return = "return" Expr ; Continue = "continue" ; AssignKind = '=' ; ModifyKind = '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' |'<<=' |'>>=' ; CompareOp = '<' | '<=' | '==' | '!=' | '>=' | '>' ; RangeOp = '..' | '..=' ; LogicOp = '&&' | '||' | '^^' ; BitwiseOp = '&' | '|' | '^' ; ShiftOp = '<<' | '>>'; TermOp = '+' | '-' ; FactorOp = '*' | '/' | '%' ; UnaryKind = '*' | '-' | '!' | '@' | '~' ;