rust/crates/syntax/rust.ungram
2023-11-12 11:20:14 +08:00

698 lines
10 KiB
Plaintext

// 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
| 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?
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')? 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