// Rust Un-Grammar. // // This grammar specifies the structure of Rust's concrete syntax tree. // It does not specify parsing rules (ambiguities, precedence, etc are out of scope). // Tokens are processed -- contextual keywords are recognised, compound operators glued. // // Legend: // // // -- comment // Name = -- non-terminal definition // 'ident' -- token (terminal) // A B -- sequence // A | B -- alternation // A* -- zero or more repetition // A? -- zero or one repetition // (A) -- same as A // label:A -- suggested name for field of AST node //*************************// // Names, Paths and Macros // //*************************// Name = 'ident' | 'self' NameRef = 'ident' | 'int_number' | 'self' | 'super' | 'crate' | 'Self' Lifetime = 'lifetime_ident' Path = (qualifier:Path '::')? segment:PathSegment PathSegment = '::'? NameRef | NameRef GenericArgList? | NameRef ParamList RetType? | '<' Type ('as' PathType)? '>' GenericArgList = '::'? '<' (GenericArg (',' GenericArg)* ','?)? '>' GenericArg = TypeArg | AssocTypeArg | LifetimeArg | ConstArg TypeArg = Type AssocTypeArg = NameRef (GenericArgList | ParamList RetType?)? (':' TypeBoundList | ('=' Type | ConstArg)) LifetimeArg = Lifetime ConstArg = Expr MacroCall = Attr* Path '!' TokenTree ';'? TokenTree = '(' ')' | '{' '}' | '[' ']' MacroItems = Item* MacroEagerInput = '(' (Expr (',' Expr)* ','?)? ')' | '{' (Expr (',' Expr)* ','?)? '}' | '[' (Expr (',' Expr)* ','?)? ']' MacroStmts = statements:Stmt* Expr? //*************************// // Items // //*************************// SourceFile = 'shebang'? Attr* Item* Item = Const | Enum | ExternBlock | ExternCrate | Fn | Impl | MacroCall | MacroRules | MacroDef | Module | Static | Struct | Trait | TraitAlias | TypeAlias | Union | Use MacroRules = Attr* Visibility? 'macro_rules' '!' Name TokenTree MacroDef = Attr* Visibility? 'macro' Name args:TokenTree? body:TokenTree Module = Attr* Visibility? 'mod' Name (ItemList | ';') ItemList = '{' Attr* Item* '}' ExternCrate = Attr* Visibility? 'extern' 'crate' NameRef Rename? ';' Rename = 'as' (Name | '_') Use = Attr* Visibility? 'use' UseTree ';' UseTree = (Path? '::')? ('*' | UseTreeList) | Path Rename? UseTreeList = '{' (UseTree (',' UseTree)* ','?)? '}' Fn = Attr* Visibility? 'default'? 'const'? 'async'? 'unsafe'? Abi? 'fn' Name GenericParamList? ParamList RetType? WhereClause? (body:BlockExpr | ';') Abi = 'extern' 'string'? ParamList = '('( SelfParam | (SelfParam ',')? (Param (',' Param)* ','?)? )')' | '|' (Param (',' Param)* ','?)? '|' SelfParam = Attr* ( ('&' Lifetime?)? 'mut'? Name | 'mut'? Name ':' Type ) Param = Attr* ( Pat (':' Type)? | Type | '...' ) RetType = '->' Type TypeAlias = Attr* Visibility? 'default'? 'type' Name GenericParamList? (':' TypeBoundList?)? WhereClause? ('=' Type)? ';' Struct = Attr* Visibility? 'struct' Name GenericParamList? ( WhereClause? (RecordFieldList | ';') | TupleFieldList WhereClause? ';' ) RecordFieldList = '{' fields:(RecordField (',' RecordField)* ','?)? '}' RecordField = Attr* Visibility? Name ':' Type TupleFieldList = '(' fields:(TupleField (',' TupleField)* ','?)? ')' TupleField = Attr* Visibility? Type FieldList = RecordFieldList | TupleFieldList Enum = Attr* Visibility? 'enum' Name GenericParamList? WhereClause? VariantList VariantList = '{' (Variant (',' Variant)* ','?)? '}' Variant = Attr* Visibility? Name FieldList? ('=' Expr)? Union = Attr* Visibility? 'union' Name GenericParamList? WhereClause? RecordFieldList // A Data Type. // // Not used directly in the grammar, but handy to have anyway. Adt = Enum | Struct | Union Const = Attr* Visibility? 'default'? 'const' (Name | '_') ':' Type ('=' body:Expr)? ';' Static = Attr* Visibility? 'static' 'mut'? Name ':' Type ('=' body:Expr)? ';' Trait = Attr* Visibility? 'unsafe'? 'auto'? 'trait' Name GenericParamList? (':' TypeBoundList?)? WhereClause? AssocItemList TraitAlias = Attr* Visibility? 'trait' Name GenericParamList? '=' TypeBoundList? WhereClause? ';' AssocItemList = '{' Attr* AssocItem* '}' AssocItem = Const | Fn | MacroCall | TypeAlias Impl = Attr* Visibility? 'default'? 'unsafe'? 'impl' GenericParamList? ('const'? '!'? trait:Type 'for')? self_ty:Type WhereClause? AssocItemList ExternBlock = Attr* 'unsafe'? Abi ExternItemList ExternItemList = '{' Attr* ExternItem* '}' ExternItem = Fn | MacroCall | Static | TypeAlias GenericParamList = '<' (GenericParam (',' GenericParam)* ','?)? '>' GenericParam = ConstParam | LifetimeParam | TypeParam TypeParam = Attr* Name (':' TypeBoundList?)? ('=' default_type:Type)? ConstParam = Attr* 'const' Name ':' Type ('=' default_val:ConstArg)? LifetimeParam = Attr* Lifetime (':' TypeBoundList?)? WhereClause = 'where' predicates:(WherePred (',' WherePred)* ','?) WherePred = ('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList? Visibility = 'pub' ('(' 'in'? Path ')')? Attr = '#' '!'? '[' Meta ']' Meta = Path ('=' Expr | TokenTree)? //****************************// // Statements and Expressions // //****************************// Stmt = ';' | ExprStmt | Item | LetStmt LetStmt = Attr* 'let' Pat (':' Type)? '=' initializer:Expr LetElse? ';' LetElse = 'else' BlockExpr ExprStmt = Expr ';'? Expr = ArrayExpr | AsmExpr | AwaitExpr | BinExpr | BlockExpr | BreakExpr | CallExpr | CastExpr | ClosureExpr | ContinueExpr | FieldExpr | ForExpr | FormatArgsExpr | IfExpr | IndexExpr | Literal | LoopExpr | MacroExpr | MatchExpr | MethodCallExpr | OffsetOfExpr | ParenExpr | PathExpr | PrefixExpr | RangeExpr | RecordExpr | RefExpr | ReturnExpr | BecomeExpr | TryExpr | TupleExpr | WhileExpr | YieldExpr | YeetExpr | LetExpr | UnderscoreExpr OffsetOfExpr = Attr* 'builtin' '#' 'offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')' AsmExpr = Attr* 'builtin' '#' 'asm' '(' Expr ')' FormatArgsExpr = Attr* 'builtin' '#' 'format_args' '(' template:Expr (',' args:(FormatArgsArg (',' FormatArgsArg)* ','?)? )? ')' FormatArgsArg = (Name '=')? Expr MacroExpr = MacroCall Literal = Attr* value:( 'int_number' | 'float_number' | 'string' | 'raw_string' | 'byte_string' | 'raw_byte_string' | 'true' | 'false' | 'char' | 'byte' ) PathExpr = Attr* Path StmtList = '{' Attr* statements:Stmt* tail_expr:Expr? '}' RefExpr = Attr* '&' ('raw' | 'mut' | 'const') Expr TryExpr = Attr* Expr '?' BlockExpr = Attr* Label? ('try' | 'unsafe' | 'async' | 'const') StmtList PrefixExpr = Attr* op:('-' | '!' | '*') Expr BinExpr = Attr* lhs:Expr op:( '||' | '&&' | '==' | '!=' | '<=' | '>=' | '<' | '>' | '+' | '*' | '-' | '/' | '%' | '<<' | '>>' | '^' | '|' | '&' | '=' | '+=' | '/=' | '*=' | '%=' | '>>=' | '<<=' | '-=' | '|=' | '&=' | '^=' ) rhs:Expr CastExpr = Attr* Expr 'as' Type ParenExpr = Attr* '(' Attr* Expr ')' ArrayExpr = Attr* '[' Attr* ( (Expr (',' Expr)* ','?)? | Expr ';' Expr ) ']' IndexExpr = Attr* base:Expr '[' index:Expr ']' TupleExpr = Attr* '(' Attr* fields:(Expr (',' Expr)* ','?)? ')' RecordExpr = Path RecordExprFieldList RecordExprFieldList = '{' Attr* fields:(RecordExprField (',' RecordExprField)* ','?)? ('..' spread:Expr?)? '}' RecordExprField = Attr* (NameRef ':')? Expr CallExpr = Attr* Expr ArgList ArgList = '(' args:(Expr (',' Expr)* ','?)? ')' MethodCallExpr = Attr* receiver:Expr '.' NameRef GenericArgList? ArgList FieldExpr = Attr* Expr '.' NameRef ClosureExpr = Attr* ('for' GenericParamList)? 'const'? 'static'? 'async'? 'move'? ParamList RetType? body:Expr IfExpr = Attr* 'if' condition:Expr then_branch:BlockExpr ('else' else_branch:(IfExpr | BlockExpr))? LoopExpr = Attr* Label? 'loop' loop_body:BlockExpr ForExpr = Attr* Label? 'for' Pat 'in' iterable:Expr loop_body:BlockExpr WhileExpr = Attr* Label? 'while' condition:Expr loop_body:BlockExpr Label = Lifetime ':' BreakExpr = Attr* 'break' Lifetime? Expr? ContinueExpr = Attr* 'continue' Lifetime? RangeExpr = Attr* start:Expr? op:('..' | '..=') end:Expr? MatchExpr = Attr* 'match' Expr MatchArmList MatchArmList = '{' Attr* arms:MatchArm* '}' MatchArm = Attr* Pat guard:MatchGuard? '=>' Expr ','? MatchGuard = 'if' condition:Expr ReturnExpr = Attr* 'return' Expr? BecomeExpr = Attr* 'become' Expr YieldExpr = Attr* 'yield' Expr? YeetExpr = Attr* 'do' 'yeet' Expr? LetExpr = Attr* 'let' Pat '=' Expr UnderscoreExpr = Attr* '_' AwaitExpr = Attr* Expr '.' 'await' //*************************// // Types // //*************************// Type = ArrayType | DynTraitType | FnPtrType | ForType | ImplTraitType | InferType | MacroType | NeverType | ParenType | PathType | PtrType | RefType | SliceType | TupleType ParenType = '(' Type ')' NeverType = '!' MacroType = MacroCall PathType = Path TupleType = '(' fields:(Type (',' Type)* ','?)? ')' PtrType = '*' ('const' | 'mut') Type RefType = '&' Lifetime? 'mut'? Type ArrayType = '[' Type ';' ConstArg ']' SliceType = '[' Type ']' InferType = '_' FnPtrType = 'const'? 'async'? 'unsafe'? Abi? 'fn' ParamList RetType? ForType = 'for' GenericParamList Type ImplTraitType = 'impl' TypeBoundList DynTraitType = 'dyn'? TypeBoundList TypeBoundList = bounds:(TypeBound ('+' TypeBound)* '+'?) TypeBound = Lifetime | ('~' 'const' | 'const')? 'async'? '?'? Type //************************// // Patterns // //************************// Pat = IdentPat | BoxPat | RestPat | LiteralPat | MacroPat | OrPat | ParenPat | PathPat | WildcardPat | RangePat | RecordPat | RefPat | SlicePat | TuplePat | TupleStructPat | ConstBlockPat LiteralPat = '-'? Literal IdentPat = Attr* 'ref'? 'mut'? Name ('@' Pat)? WildcardPat = '_' RangePat = // 1.. start:Pat op:('..' | '..=') // 1..2 | start:Pat op:('..' | '..=') end:Pat // ..2 | op:('..' | '..=') end:Pat RefPat = '&' 'mut'? Pat RecordPat = Path RecordPatFieldList RecordPatFieldList = '{' fields:(RecordPatField (',' RecordPatField)* ','?)? RestPat? '}' RecordPatField = Attr* (NameRef ':')? Pat TupleStructPat = Path '(' fields:(Pat (',' Pat)* ','?)? ')' TuplePat = '(' fields:(Pat (',' Pat)* ','?)? ')' ParenPat = '(' Pat ')' SlicePat = '[' (Pat (',' Pat)* ','?)? ']' PathPat = Path OrPat = (Pat ('|' Pat)* '|'?) BoxPat = 'box' Pat RestPat = Attr* '..' MacroPat = MacroCall ConstBlockPat = 'const' BlockExpr