Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| // FIXME#1 | |
| // | |
| // We currently accept `if return { /* expr */ } { /* then */ }` but | |
| // it is unclear if we *should* do so (in fact, I would argue that we | |
| // should not, because it is inconsistent with `if Struct { ... }`) | |
| // and `if 3 .. {`. Options to resolve: | |
| // | |
| // - disallow `if return/break/continue` altogether | |
| // - I lump in `break/continue` to allow for future compat where | |
| // they take an argument, but also because they are all | |
| // unconditionall diverging control-flow expressions | |
| // - permit `if return/break/continue` but not with a block argument | |
| // - consistent, but what's the point? | |
| // - kepe things as they are today | |
| // | |
| // I opted for #1 so far. | |
| // | |
| // FIXME#2 | |
| // | |
| // I am currently disallowing things like `x as (i32) < y as (i32)`; | |
| // to fix this I have to propagate the restrictions against type | |
| // arguments into the Ty grammar. | |
| use token::Token; | |
| grammar<'input>; | |
| pub Crate: () = { | |
| Shebang? InnerAttr* ModItem*, | |
| }; | |
| Shebang: () = { | |
| "#!", | |
| }; | |
| InnerAttr: () = { | |
| "#!" "[" MetaItem "]", | |
| "//!...", | |
| }; | |
| MaybeOuterAttrs: () = { | |
| OuterAttrs?, | |
| }; | |
| OuterAttrs: () = { | |
| OuterAttr, | |
| OuterAttrs OuterAttr, | |
| }; | |
| OuterAttr: () = { | |
| "#" "[" MetaItem "]", | |
| "///...", | |
| }; | |
| MetaItem: () = { | |
| Identifier, | |
| Identifier "=" Lit, | |
| Identifier "(" Comma<MetaItem> ")", | |
| }; | |
| AttrsAndVis: () = { | |
| MaybeOuterAttrs visibility, | |
| }; | |
| ModItem: () = { | |
| AttrsAndVis item, | |
| }; | |
| item: () = { | |
| StmtItem, | |
| ItemMacro, | |
| }; | |
| StmtItem: () = { | |
| ItemStatic, | |
| ItemConst, | |
| ItemType, | |
| BlockItem, | |
| ViewItem, | |
| }; | |
| ItemStatic: () = { | |
| "static" "mut"? Identifier ":" ty "=" Expr ";", | |
| }; | |
| ItemConst: () = { | |
| "const" Identifier ":" ty "=" Expr ";", | |
| }; | |
| ItemMacro: () = { | |
| PathExpr "!" Identifier? parens_delimited_token_trees ";", | |
| PathExpr "!" Identifier? braces_delimited_token_trees, | |
| PathExpr "!" Identifier? brackets_delimited_token_trees ";", | |
| }; | |
| ViewItem: () = { | |
| ItemUse, | |
| ExternFnItem, | |
| "extern" "crate" Identifier ("as" Identifier)? ";", | |
| }; | |
| ExternFnItem: () = { | |
| "extern" Abi ItemFn, | |
| }; | |
| ItemUse: () = { | |
| "use" ViewPath ";", | |
| }; | |
| ViewPath: () = { | |
| PathNoTypes, | |
| PathNoTypes "::" "{" "}", | |
| "::" "{" "}", | |
| PathNoTypes "::" "{" IdentifiersOrSelf "}", | |
| "::" "{" IdentifiersOrSelf "}", | |
| PathNoTypes "::" "{" IdentifiersOrSelf "," "}", | |
| "::" "{" IdentifiersOrSelf "," "}", | |
| PathNoTypes "::" "*", | |
| "{" "}", | |
| "{" IdentifiersOrSelf "}", | |
| "{" IdentifiersOrSelf "," "}", | |
| PathNoTypes "as" Identifier, | |
| }; | |
| BlockItem: () = { | |
| ItemFn, | |
| ItemUnsafeFn, | |
| ItemMod, | |
| ItemForeignMod, | |
| ItemStruct, | |
| ItemEnum, | |
| ItemTrait, | |
| ItemImpl, | |
| }; | |
| MaybeTyAscription: () = { | |
| (":" TySum)? | |
| }; | |
| MaybeInitExpr: () = { | |
| ("=" Expr)? | |
| }; | |
| ItemStruct: () = { | |
| "struct" Identifier GenericParams MaybeWhereClause StructDeclArgs, | |
| "struct" Identifier GenericParams StructTupleArgs MaybeWhereClause ";", | |
| "struct" Identifier GenericParams MaybeWhereClause ";", | |
| }; | |
| StructDeclArgs: () = { | |
| "{" StructDeclFields "}" | |
| }; | |
| StructTupleArgs: () = { | |
| "(" StructTupleFields ")" | |
| }; | |
| StructDeclFields: () = { | |
| Comma<StructDeclField>, | |
| }; | |
| StructDeclField: () = { | |
| AttrsAndVis Identifier ":" TySum, | |
| }; | |
| StructTupleFields: () = { | |
| Comma<StructTupleField> | |
| }; | |
| StructTupleField: () = { | |
| AttrsAndVis TySum, | |
| }; | |
| ItemEnum: () = { | |
| "enum" Identifier GenericParams MaybeWhereClause "{" Comma1<EnumDef> "}", | |
| }; | |
| EnumDef: () = { | |
| AttrsAndVis Identifier EnumArgs | |
| }; | |
| EnumArgs: () = { | |
| "{" StructDeclFields "}", | |
| "(" MaybeTySums ")", | |
| "=" Expr, | |
| (), | |
| }; | |
| ItemMod: () = { | |
| "mod" Identifier ";", | |
| "mod" Identifier "{" InnerAttr* ModItem* "}", | |
| }; | |
| ItemForeignMod: () = { | |
| "extern" Abi "{" InnerAttr* ForeignItem* "}", | |
| }; | |
| Abi: () = { | |
| StringLiteral? | |
| }; | |
| ForeignItem: () = { | |
| AttrsAndVis "static" item_foreign_static, | |
| AttrsAndVis item_foreign_fn, | |
| AttrsAndVis "unsafe" item_foreign_fn, | |
| }; | |
| item_foreign_static: () = { | |
| "mut"? Identifier ":" ty ";", | |
| }; | |
| item_foreign_fn: () = { | |
| "fn" Identifier GenericParams fn_decl_allow_variadic MaybeWhereClause ";", | |
| }; | |
| fn_decl_allow_variadic: () = { | |
| fn_params_allow_variadic RetTy, | |
| }; | |
| fn_params_allow_variadic: () = { | |
| "(" ")", | |
| "(" Comma1NoTrail<param> ")", | |
| "(" Comma1NoTrail<param> "," ")", | |
| "(" Comma1NoTrail<param> "," "..." ")", | |
| }; | |
| visibility: () = { | |
| "pub", | |
| (), | |
| }; | |
| IdentifiersOrSelf: () = { | |
| IdentifierOrSelf, | |
| IdentifierOrSelf "as" Identifier, | |
| IdentifiersOrSelf "," IdentifierOrSelf, | |
| }; | |
| IdentifierOrSelf: () = { | |
| Identifier, | |
| "self", | |
| }; | |
| ItemType: () = { | |
| "type" Identifier GenericParams MaybeWhereClause "=" TySum ";", | |
| }; | |
| ItemTrait: () = { | |
| MaybeUnsafe "trait" Identifier GenericParams MaybeTyParamBounds MaybeWhereClause | |
| "{" | |
| TraitItem* | |
| "}", | |
| }; | |
| TraitItem: () = { | |
| TraitConst, | |
| TraitType, | |
| TraitMethod, | |
| }; | |
| TraitConst: () = { | |
| MaybeOuterAttrs "const" Identifier MaybeTyAscription MaybeConstDefault ";", | |
| }; | |
| MaybeConstDefault: () = { | |
| ("=" Expr)? | |
| }; | |
| TraitType: () = { | |
| MaybeOuterAttrs "type" TyParam ";", | |
| }; | |
| MaybeUnsafe: () = { | |
| "unsafe"? | |
| }; | |
| TraitMethod: () = { | |
| TypeMethod, | |
| Method, | |
| }; | |
| TypeMethod: () = { | |
| AttrsAndVis MaybeUnsafe "fn" Identifier GenericParams fn_decl_with_self_allow_AnonParams MaybeWhereClause ";", | |
| AttrsAndVis MaybeUnsafe "extern" Abi "fn" Identifier GenericParams fn_decl_with_self_allow_AnonParams MaybeWhereClause ";", | |
| }; | |
| Method: () = { | |
| AttrsAndVis MaybeUnsafe "fn" Identifier GenericParams fn_decl_with_self_allow_AnonParams MaybeWhereClause InnerAttrs_and_block, | |
| AttrsAndVis MaybeUnsafe "extern" Abi "fn" Identifier GenericParams fn_decl_with_self_allow_AnonParams MaybeWhereClause InnerAttrs_and_block, | |
| }; | |
| ImplMethod: () = { | |
| AttrsAndVis MaybeUnsafe "fn" Identifier GenericParams fn_decl_with_self MaybeWhereClause InnerAttrs_and_block, | |
| AttrsAndVis MaybeUnsafe "extern" Abi "fn" Identifier GenericParams fn_decl_with_self MaybeWhereClause InnerAttrs_and_block, | |
| }; | |
| ItemImpl: () = { | |
| MaybeUnsafe "impl" GenericParams TyPrimSum MaybeWhereClause "{" InnerAttr* MaybeImplItems "}", | |
| MaybeUnsafe "impl" GenericParams "(" ty ")" MaybeWhereClause "{" InnerAttr* MaybeImplItems "}", | |
| MaybeUnsafe "impl" GenericParams TraitRef "for" TySum MaybeWhereClause "{" InnerAttr* MaybeImplItems "}", | |
| MaybeUnsafe "impl" GenericParams "!" TraitRef "for" TySum MaybeWhereClause "{" InnerAttr* MaybeImplItems "}", | |
| MaybeUnsafe "impl" GenericParams TraitRef "for" ".." "{" "}", | |
| MaybeUnsafe "impl" GenericParams "!" TraitRef "for" ".." "{" "}", | |
| }; | |
| MaybeImplItems: () = { | |
| ImplItems, | |
| (), | |
| }; | |
| ImplItems: () = { | |
| ImplItem, | |
| ImplItem ImplItems, | |
| }; | |
| ImplItem: () = { | |
| ImplMethod, | |
| AttrsAndVis ItemMacro, | |
| ImplConst, | |
| ImplType, | |
| }; | |
| ImplConst: () = { | |
| AttrsAndVis ItemConst, | |
| }; | |
| ImplType: () = { | |
| AttrsAndVis "type" Identifier GenericParams "=" TySum ";", | |
| }; | |
| ItemFn: () = { | |
| "fn" Identifier GenericParams fn_decl MaybeWhereClause InnerAttrs_and_block, | |
| }; | |
| ItemUnsafeFn: () = { | |
| "unsafe" "fn" Identifier GenericParams fn_decl MaybeWhereClause InnerAttrs_and_block, | |
| "unsafe" "extern" Abi "fn" Identifier GenericParams fn_decl MaybeWhereClause InnerAttrs_and_block, | |
| }; | |
| fn_decl: () = { | |
| fn_params RetTy, | |
| }; | |
| fn_decl_with_self: () = { | |
| fn_params_with_self RetTy, | |
| }; | |
| fn_decl_with_self_allow_AnonParams: () = { | |
| fn_AnonParams_with_self RetTy, | |
| }; | |
| fn_params: () = { | |
| "(" Comma<param> ")", | |
| }; | |
| fn_AnonParams: () = { | |
| "(" AnonParam AnonParams_allow_variadic_tail ")", | |
| "(" ")", | |
| }; | |
| fn_params_with_self: () = { | |
| "(" "mut"? "self" MaybeTyAscription Maybecomma_params ")", | |
| "(" "&[]" "mut"? "self" MaybeTyAscription Maybecomma_params ")", | |
| "(" "&[]" Lifetime "mut"? "self" MaybeTyAscription Maybecomma_params ")", | |
| "(" Comma<param> ")", | |
| }; | |
| fn_AnonParams_with_self: () = { | |
| "(" "mut"? "self" MaybeTyAscription Maybecomma_AnonParams ")", | |
| "(" "&[]" "mut"? "self" MaybeTyAscription Maybecomma_AnonParams ")", | |
| "(" "&[]" Lifetime "mut"? "self" MaybeTyAscription Maybecomma_AnonParams ")", | |
| "(" MaybeAnonParams ")", | |
| }; | |
| param: () = { | |
| Pat ":" TySum, | |
| }; | |
| InferrableParam: () = { | |
| Pat MaybeTyAscription, | |
| }; | |
| Maybecomma_params: () = { | |
| "," Comma<param>, | |
| (), | |
| }; | |
| Maybecomma_AnonParams: () = { | |
| ",", | |
| "," AnonParams, | |
| "," AnonParams ",", | |
| (), | |
| }; | |
| MaybeAnonParams: () = { | |
| AnonParams, | |
| AnonParams ",", | |
| (), | |
| }; | |
| AnonParams: () = { | |
| AnonParam, | |
| AnonParams "," AnonParam, | |
| }; | |
| AnonParam: () = { | |
| NamedArg ":" ty, | |
| ty, | |
| }; | |
| AnonParams_allow_variadic_tail: () = { | |
| "," "...", | |
| "," AnonParam AnonParams_allow_variadic_tail, | |
| (), | |
| }; | |
| NamedArg: () = { | |
| Identifier, | |
| "_", | |
| "&[]" Identifier, | |
| "&[]" "_", | |
| "mut" Identifier, | |
| }; | |
| RetTy: () = { | |
| "->" "!", | |
| "->" ty, | |
| (), | |
| }; | |
| GenericParams: () = { | |
| TyLt Comma1<LifetimeAndBounds> TyGt, | |
| TyLt (LifetimeAndBounds ",")+ Comma1<TyParam> TyGt, | |
| TyLt Comma1<TyParam> TyGt, | |
| TyLt TyGt, | |
| }; | |
| MaybeWhereClause: () = { | |
| WhereClause? | |
| }; | |
| WhereClause: () = { | |
| "where" Comma<WherePredicate> | |
| }; | |
| WherePredicate: () = { | |
| ForLifetimes? Lifetime ":" bounds, | |
| ForLifetimes ty ":" TyParamBounds, | |
| }; | |
| ForLifetimes: () = { | |
| "for" TyLt Lifetimes TyGt, | |
| }; | |
| PathNoTypes: () = { | |
| Identifier, | |
| "::" Identifier, | |
| "self", | |
| "::" "self", | |
| PathNoTypes "::" Identifier, | |
| }; | |
| GenericArgs: () = { | |
| TyLt GenericValues TyGt, | |
| }; | |
| GenericValues: () = { | |
| Lifetimes? MaybeTySumsAndOrBindings, | |
| }; | |
| MaybeTySumsAndOrBindings: () = { | |
| TySums, | |
| TySums ",", | |
| TySums "," bindings, | |
| bindings, | |
| bindings ",", | |
| (), | |
| }; | |
| Maybebindings: () = { | |
| "," bindings, | |
| (), | |
| }; | |
| #[inline] | |
| Pat: () = PatWithBindingMode<BindingMode>; | |
| PatWithBindingMode<BM>: () = { | |
| "_", | |
| AnyAmp PatWithBindingMode<RefBindingMode>, | |
| AnyAmp "mut" Pat, | |
| "(" Comma<Pat> ")", | |
| "[" PatVec "]", | |
| LitOrPath, | |
| LitOrPath "..." LitOrPath, | |
| PathExpr "{" PatStruct "}", | |
| PathExpr "(" ".." ")", | |
| PathExpr "(" Comma<Pat> ")", | |
| PathExpr "!" Identifier? delimited_token_trees, | |
| BM Identifier, | |
| Identifier "@" Pat, | |
| BM Identifier "@" Pat, | |
| "box" Pat, | |
| TyLt TySum MaybeAsTraitRef TyGt "::" Identifier, | |
| }; | |
| PatsOr: () = { | |
| Delim1NoTrail<Pat, "|[]"> | |
| }; | |
| BindingMode: () = { | |
| RefBindingMode, | |
| "mut", | |
| }; | |
| RefBindingMode: () = { | |
| "ref", | |
| "ref" "mut", | |
| }; | |
| LitOrPath: () = { | |
| PathExpr, | |
| Lit, | |
| "-" Lit, | |
| }; | |
| PatField: () = { | |
| Identifier, | |
| BindingMode Identifier, | |
| "box" Identifier, | |
| "box" BindingMode Identifier, | |
| Identifier ":" Pat, | |
| BindingMode Identifier ":" Pat, | |
| }; | |
| // LALRPOP BUG: Removing the `#[inline]` causes LALRPOP to fail with | |
| // no useful output, unless you pipe through a file. Can I reduce | |
| // this? [Also, the error message is confusing.] | |
| #[inline] | |
| PatFields: () = { | |
| Comma1NoTrail<PatField> | |
| }; | |
| PatStruct: () = { | |
| PatFields, | |
| PatFields ",", | |
| PatFields "," "..", | |
| "..", | |
| }; | |
| PatVec: () = { | |
| PatVecElts, | |
| PatVecElts ",", | |
| PatVecElts "..", | |
| PatVecElts "," "..", | |
| PatVecElts ".." "," PatVecElts, | |
| PatVecElts ".." "," PatVecElts ",", | |
| PatVecElts "," ".." "," PatVecElts, | |
| PatVecElts "," ".." "," PatVecElts ",", | |
| ".." "," PatVecElts, | |
| ".." "," PatVecElts ",", | |
| "..", | |
| (), | |
| }; | |
| PatVecElts: () = { | |
| Pat, | |
| PatVecElts "," Pat, | |
| }; | |
| ty: () = { | |
| TyPrim, | |
| TyLt TySum MaybeAsTraitRef TyGt "::" Identifier, | |
| "(" TySums ")", | |
| "(" TySums "," ")", | |
| "(" ")", | |
| }; | |
| TyPrim: () = { | |
| Path<Epsilon>, | |
| "box" ty, | |
| "*" mut_or_const ty, | |
| AnyAmp ty, | |
| AnyAmp "mut" ty, | |
| AnyAmp Lifetime "mut"? ty, | |
| "[" ty "]", | |
| "[" ty "," ".." Expr "]", | |
| "[" ty ";" Expr "]", | |
| "typeof" "(" Expr ")", | |
| "_", | |
| ty_bare_fn, | |
| for_in_type, | |
| }; | |
| ty_bare_fn: () = { | |
| "fn" ty_fn_decl, | |
| "unsafe" "fn" ty_fn_decl, | |
| "extern" Abi "fn" ty_fn_decl, | |
| "unsafe" "extern" Abi "fn" ty_fn_decl, | |
| }; | |
| ty_fn_decl: () = { | |
| GenericParams fn_AnonParams RetTy, | |
| }; | |
| for_in_type: () = { | |
| "for" TyLt MaybeLifetimes TyGt for_in_type_suffix, | |
| }; | |
| for_in_type_suffix: () = { | |
| ty_bare_fn, | |
| TraitRef, | |
| }; | |
| mut_or_const: () = { | |
| "mut", | |
| "const", | |
| }; | |
| ty_qualified_path_and_GenericValues: () = { | |
| ty_qualified_path Maybebindings, | |
| ty_qualified_path "," TySums Maybebindings, | |
| }; | |
| ty_qualified_path: () = { | |
| TySum "as" TraitRef TyGt "::" Identifier, | |
| TySum "as" TraitRef TyGt "::" Identifier "+" TyParamBounds, | |
| }; | |
| MaybeTySums: () = { | |
| TySums, | |
| TySums ",", | |
| (), | |
| }; | |
| TySums: () = { | |
| TySum, | |
| TySums "," TySum, | |
| }; | |
| TySum: () = { | |
| ty, | |
| ty "+" TyParamBounds, | |
| }; | |
| TyPrimSum: () = { | |
| TyPrim, | |
| TyPrim "+" TyParamBounds, | |
| }; | |
| MaybeTyParamBounds: () = { | |
| (":" TyParamBounds)? | |
| }; | |
| TyParamBounds: () = { | |
| boundseq, | |
| (), | |
| }; | |
| boundseq: () = { | |
| polybound, | |
| boundseq "+" polybound, | |
| }; | |
| polybound: () = { | |
| "for" TyLt MaybeLifetimes TyGt bound, | |
| bound, | |
| "?" bound, | |
| }; | |
| bindings: () = { | |
| binding, | |
| bindings "," binding, | |
| }; | |
| binding: () = { | |
| Identifier "=" ty, | |
| }; | |
| TyParam: () = { | |
| Identifier MaybeTyParamBounds MaybeTyDefault, | |
| Identifier "?" Identifier MaybeTyParamBounds MaybeTyDefault, | |
| }; | |
| Maybebounds: () = { | |
| ":" bounds, | |
| (), | |
| }; | |
| bounds: () = { | |
| bound, | |
| bounds "+" bound, | |
| }; | |
| bound: () = { | |
| Lifetime, | |
| TraitRef, | |
| }; | |
| MaybeLifetimeBounds: () = { | |
| (":" LifetimeBounds)? | |
| }; | |
| LifetimeBounds: () = { | |
| Lifetime, | |
| LifetimeBounds "+" Lifetime, | |
| }; | |
| MaybeTyDefault: () = { | |
| ("=" TySum)? | |
| }; | |
| MaybeLifetimes: () = Comma<LifetimeAndBounds>; | |
| Lifetimes: () = Comma1<LifetimeAndBounds>; | |
| LifetimeAndBounds: () = { | |
| Lifetime MaybeLifetimeBounds, | |
| }; | |
| TraitRef: () = { | |
| Path<Epsilon>, | |
| }; | |
| InnerAttrs_and_block: () = { | |
| "{" InnerAttr* Maybestmts "}", | |
| }; | |
| block: () = { | |
| "{" Maybestmts "}", | |
| }; | |
| Maybestmts: () = { | |
| stmts, | |
| stmts ExprNoStmtLike, | |
| ExprNoStmtLike, | |
| (), | |
| }; | |
| stmts: () = { | |
| stmt, | |
| stmts stmt, | |
| }; | |
| stmt: () = { | |
| Let, | |
| StmtItem, | |
| "pub" StmtItem, | |
| OuterAttrs StmtItem, | |
| OuterAttrs "pub" StmtItem, | |
| ExprStmtLike, | |
| block, | |
| ExprNoStmtLike ";", | |
| ";", | |
| }; | |
| PathExpr: () = { | |
| Path<"::"> | |
| }; | |
| // Parses a path like `x::y::z`, where A is the token that separates | |
| // the generic arguments. | |
| Path<ARG_SEP>: () = { | |
| Identifier, | |
| "::" Identifier, | |
| "self" "::" Identifier, | |
| "super" "::" Identifier, | |
| Path<ARG_SEP> "::" Identifier, | |
| Path<ARG_SEP> ARG_SEP GenericArgs, | |
| }; | |
| MacroExpr: () = { | |
| PathExpr "!" Identifier? parens_delimited_token_trees, | |
| PathExpr "!" Identifier? brackets_delimited_token_trees, | |
| }; | |
| // New-style names: | |
| Expr: () = ExprRestricted<"S","B","L">; | |
| ExprNoStruct: () = ExprRestricted<"","B","L">; | |
| ExprNoStmtLike: () = ExprRestricted<"S","","">; | |
| // The parameters must be either "" or "[SBLT]". They | |
| // are used to select subsets of expressions. Not all | |
| // the parameters apply to all subsets of expressions. | |
| // | |
| // - S: if non-empty, include struct expressions | |
| // - B: if non-empty, include block expressions | |
| // - L: if non-empty, include stmt-like expressions | |
| // - T: if non-empty, include expressions ending in a type | |
| ExprRestricted<S,B,L>: () = { | |
| ExprOrOr<S,B,L>, | |
| "return" if S != "", // FIXME#1 | |
| "return" ExprOptionalRhs<S,"B","L"> if S != "", // FIXME#1 | |
| "..", | |
| LambdaExpr<S,B,L>, | |
| "move" LambdaExpr<S,B,L>, | |
| ExprOrOr<S,B,L> "=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "<-" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "..", | |
| ExprOrOr<S,B,L> ".." ExprOptionalRhs<S,"B","L">, | |
| ExprOrOr<S,B,L> "<<=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> ">>=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "-=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "&=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "|=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "+=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "*=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "/=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "^=" ExprRestricted<S,"B","L">, | |
| ExprOrOr<S,B,L> "%=" ExprRestricted<S,"B","L">, | |
| }; | |
| // When you have an optional RHS, such as in a `..` expression, we | |
| // can't allow block expressions if we are not allowed struct | |
| // expressions. So toggle B to "" if S is "". The reason is that | |
| // otherwise you get an ambiguity: | |
| // | |
| // ... if 0 .. { 22 } ... | |
| // ^~~~~~ body of the if, or RHS of the `..`? | |
| ExprOptionalRhs<S,B,L>: () = { | |
| ExprRestricted<S,"",L> if S == "", // if structs are disabled, disable blocks | |
| ExprRestricted<S,B,L> if S != "", // if structs are enabled, pass everything thru | |
| }; | |
| ExprOrOr<S,B,L>: () = { | |
| ExprAndAnd<S,B,L>, | |
| ExprOrOr<S,B,L> "|[|]" "|[]" ExprAndAnd<S,"B","L">, | |
| }; | |
| ExprAndAnd<S,B,L>: () = { | |
| ExprEq<S,B,L>, | |
| ExprAndAnd<S,B,L> "&[&]" "&[]" ExprEq<S,"B","L">, | |
| }; | |
| ExprEq<S,B,L>: () = { | |
| ExprEqOp<S,B,L>, | |
| }; | |
| ExprEqOp<S,B,L>: () = { | |
| ExprOr<S,B,L,"T">, | |
| ExprOr<S,B,L,"T"> "==" ExprOr<S,"B","L","T">, | |
| ExprOr<S,B,L,"T"> "!=" ExprOr<S,"B","L","T">, | |
| ExprOr<S,B,L,""> "<[]" ExprOr<S,"B","L","T">, | |
| ExprOr<S,B,L,"T"> ">[]" ExprOr<S,"B","L","T">, | |
| ExprOr<S,B,L,"T"> "<=" ExprOr<S,"B","L","T">, | |
| ExprOr<S,B,L,"T"> ">=" ExprOr<S,"B","L","T">, | |
| }; | |
| ExprOr<S,B,L,T>: () = { | |
| ExprXor<S,B,L,T>, | |
| ExprOr<S,B,L,"T"> "|[]" ExprXor<S,"B","L",T>, | |
| }; | |
| ExprXor<S,B,L,T>: () = { | |
| ExprAnd<S,B,L,T>, | |
| ExprXor<S,B,L,"T"> "^" ExprAnd<S,"B","L",T>, | |
| }; | |
| ExprAnd<S,B,L,T>: () = { | |
| ExprShift<S,B,L,T>, | |
| ExprAnd<S,B,L,"T"> "&[]" ExprShift<S,"B","L",T>, | |
| }; | |
| ExprShift<S,B,L,T>: () = { | |
| ExprPlusMinus<S,B,L,T>, | |
| ExprShift<S,B,L,""> "<[<]" "<[]" ExprPlusMinus<S,"B","L",T>, | |
| ExprShift<S,B,L,"T"> ">[>]" ">[]" ExprPlusMinus<S,"B","L",T>, | |
| }; | |
| ExprPlusMinus<S,B,L,T>: () = { | |
| ExprMulDiv<S,B,L,T>, | |
| ExprPlusMinus<S,B,L,"T"> "+" ExprMulDiv<S,"B","L",T>, | |
| ExprPlusMinus<S,B,L,"T"> "-" ExprMulDiv<S,"B","L",T>, | |
| }; | |
| ExprMulDiv<S,B,L,T>: () = { | |
| ExprAs<S,B,L,T>, | |
| ExprMulDiv<S,B,L,"T"> "*" ExprAs<S,"B","L",T>, | |
| ExprMulDiv<S,B,L,"T"> "/" ExprAs<S,"B","L",T>, | |
| ExprMulDiv<S,B,L,"T"> "%" ExprAs<S,"B","L",T>, | |
| }; | |
| ExprAs<S,B,L,T>: () = { | |
| ExprPrefix<S,B,L>, | |
| ExprPrefix<S,B,L> "as" ty if T != "", // FIXME#2 | |
| }; | |
| ExprPrefix<S,B,L>: () = { | |
| "box" ExprSuffix<S,"B","L">, | |
| "-" ExprSuffix<S,"B","L">, | |
| "!" ExprSuffix<S,"B","L">, | |
| "*" ExprSuffix<S,"B","L">, | |
| AnyAmp "mut"? ExprSuffix<S,"B","L">, | |
| }; | |
| ExprSuffix<S,B,L>: () = { | |
| ExprAtom<S,B,L>, | |
| ExprSuffix<S,B,L> "." Path<"::">, | |
| ExprSuffix<S,B,L> "." LiteralInteger, | |
| ExprSuffix<S,B,L> "[" Expr "]", | |
| ExprSuffix<S,B,L> "(" Comma<Expr> ")", | |
| }; | |
| ExprAtom<S,B,L>: () = { | |
| Lit, | |
| PathExpr, | |
| "self", | |
| MacroExpr, | |
| PathExpr "{" StructExprFields "}" if S != "", | |
| "(" Comma<Expr> ")", | |
| "[" Comma<Expr> "]", | |
| "[" Expr ";" Expr "]", | |
| "continue" if S != "", // FIXME#1 | |
| "continue" Identifier if S != "", // FIXME#1 | |
| "break" if S != "", // FIXME#1 | |
| "break" Identifier if S != "", // FIXME#1 | |
| Expr_qualified_path, | |
| ExprStmtLike if L != "", | |
| block if B != "", | |
| }; | |
| Expr_qualified_path: () = { | |
| TyLt TySum MaybeAsTraitRef TyGt "::" Identifier Maybeqpath_params, | |
| }; | |
| Maybeqpath_params: () = { | |
| "::" GenericArgs, | |
| (), | |
| }; | |
| MaybeAsTraitRef: () = { | |
| ("as" TraitRef)? | |
| }; | |
| LambdaExpr<S,B,L>: () = { | |
| AnyPipe Comma<InferrableParam> "|[]" ExprRestricted<S,"B","L">, | |
| AnyPipe Comma<InferrableParam> "|[]" "->" ty "{" Expr "}", | |
| }; | |
| StructExprFields: () = { | |
| FieldValues, | |
| FieldValues ",", | |
| FieldValues "," ".." Expr, | |
| ".." Expr, | |
| }; | |
| // Note: this is not the same as Comma<FieldValue>, because it does | |
| // not admit an empty list, and it also does not accept a trailing `,`. | |
| FieldValues: () = { | |
| FieldValue, | |
| FieldValues "," FieldValue, | |
| }; | |
| FieldValue: () = { | |
| Identifier ":" Expr, | |
| }; | |
| ExprStmtLike: () = { | |
| ExprMatch, | |
| ExprIf, | |
| ExprIfLet, | |
| ExprWhile, | |
| ExprWhileLet, | |
| ExprLoop, | |
| ExprFor, | |
| "unsafe" block, | |
| PathExpr "!" Identifier? braces_delimited_token_trees, | |
| }; | |
| ExprStmtLikeSuffix: () = { | |
| ExprStmtLike, | |
| ExprStmtLikeSuffix "." Path<"::">, | |
| ExprStmtLikeSuffix "." Path<"::"> "[" Expr? "]", | |
| ExprStmtLikeSuffix "." Path<"::"> "(" Comma<Expr> ")", | |
| ExprStmtLikeSuffix "." LiteralInteger, | |
| }; | |
| ExprMatch: () = { | |
| "match" ExprNoStruct "{" "}", | |
| "match" ExprNoStruct "{" MatchClauses "}", | |
| "match" ExprNoStruct "{" MatchClauses NonBlockMatchClause "}", | |
| "match" ExprNoStruct "{" NonBlockMatchClause "}", | |
| }; | |
| MatchClauses: () = { | |
| MatchClause, | |
| MatchClauses MatchClause, | |
| }; | |
| MatchClause: () = { | |
| NonBlockMatchClause ",", | |
| BlockMatchClause, | |
| BlockMatchClause ",", | |
| }; | |
| NonBlockMatchClause: () = { | |
| MaybeOuterAttrs PatsOr MaybeGuard "=>" ExprNoStmtLike, | |
| MaybeOuterAttrs PatsOr MaybeGuard "=>" ExprStmtLikeSuffix, | |
| }; | |
| BlockMatchClause: () = { | |
| MaybeOuterAttrs PatsOr MaybeGuard "=>" block, | |
| }; | |
| MaybeGuard: () = { | |
| "if" ExprNoStruct, | |
| (), | |
| }; | |
| ExprIf: () = { | |
| "if" ExprNoStruct block, | |
| "if" ExprNoStruct block "else" BlockOrIf, | |
| }; | |
| ExprIfLet: () = { | |
| "if" "let" Pat "=" ExprNoStruct block, | |
| "if" "let" Pat "=" ExprNoStruct block "else" BlockOrIf, | |
| }; | |
| BlockOrIf: () = { | |
| block, | |
| ExprIf, | |
| ExprIfLet, | |
| }; | |
| ExprWhile: () = { | |
| MaybeLabel "while" ExprNoStruct block, | |
| }; | |
| ExprWhileLet: () = { | |
| MaybeLabel "while" "let" Pat "=" ExprNoStruct block, | |
| }; | |
| ExprLoop: () = { | |
| MaybeLabel "loop" block, | |
| }; | |
| ExprFor: () = { | |
| MaybeLabel "for" Pat "in" ExprNoStruct block, | |
| }; | |
| MaybeLabel: () = { | |
| (Lifetime ":")? | |
| }; | |
| Let: () = { | |
| "let" Pat MaybeTyAscription MaybeInitExpr ";", | |
| }; | |
| Lit: () = { | |
| LiteralByte, | |
| LiteralChar, | |
| LiteralInteger, | |
| LiteralFloat, | |
| "true", | |
| "false", | |
| StringLiteral, | |
| }; | |
| StringLiteral: () = { | |
| LiteralString, | |
| LiteralStringRaw, | |
| LiteralByteString, | |
| LiteralByteStringRaw, | |
| }; | |
| unpaired_token: () = { | |
| "==", | |
| "!=", | |
| "-=", | |
| "&=", | |
| "|=", | |
| "+=", | |
| "*=", | |
| "/=", | |
| "^=", | |
| "%=", | |
| "..", | |
| "...", | |
| "::", | |
| "->", | |
| LiteralByte, | |
| LiteralChar, | |
| LiteralInteger, | |
| LiteralFloat, | |
| LiteralString, | |
| LiteralStringRaw, | |
| LiteralByteString, | |
| LiteralByteStringRaw, | |
| Identifier, | |
| "_", | |
| Lifetime, | |
| "self", | |
| "super", | |
| "static", | |
| "as", | |
| "break", | |
| "crate", | |
| "else", | |
| "enum", | |
| "extern", | |
| "false", | |
| "fn", | |
| "for", | |
| "if", | |
| "impl", | |
| "in", | |
| "let", | |
| "loop", | |
| "match", | |
| "mod", | |
| "move", | |
| "mut", | |
| "priv", | |
| "pub", | |
| "ref", | |
| "return", | |
| "struct", | |
| "true", | |
| "trait", | |
| "type", | |
| "unsafe", | |
| "use", | |
| "while", | |
| "continue", | |
| "box", | |
| "const", | |
| "where", | |
| "typeof", | |
| "//!...", | |
| "///...", | |
| "#!", | |
| ";", | |
| ",", | |
| ".", | |
| "@", | |
| "#", | |
| "~", | |
| ":", | |
| "$", | |
| "=", | |
| "?", | |
| "!", | |
| "<<=", | |
| ">>=", | |
| "<-", | |
| "<=", | |
| ">=", | |
| "<[<]", | |
| "<[]", | |
| ">[>]", | |
| ">[]", | |
| "-", | |
| "|[|]", | |
| "|[]", | |
| "&[&]", | |
| "&[]", | |
| "+", | |
| "*", | |
| "/", | |
| "^", | |
| "%", | |
| }; | |
| token_trees: () = { | |
| (), | |
| token_trees token_tree, | |
| }; | |
| token_tree: () = { | |
| delimited_token_trees, | |
| unpaired_token, | |
| }; | |
| delimited_token_trees: () = { | |
| parens_delimited_token_trees, | |
| braces_delimited_token_trees, | |
| brackets_delimited_token_trees, | |
| }; | |
| parens_delimited_token_trees: () = { | |
| "(" token_trees ")", | |
| }; | |
| braces_delimited_token_trees: () = { | |
| "{" token_trees "}", | |
| }; | |
| brackets_delimited_token_trees: () = { | |
| "[" token_trees "]", | |
| }; | |
| MaybeIdentifier: () = { | |
| (), | |
| Identifier, | |
| }; | |
| // Comma-separated list with optional trailing comma. Potentially | |
| // empty. | |
| #[inline] | |
| Comma<E>: () = | |
| Delim<E,",">; | |
| // Delimeted list of E with optional trailing delimeter. Potentially | |
| // empty. | |
| #[inline] | |
| Delim<E,D>: () = | |
| (E D)* E?; | |
| // Comma-separated list of length at least 1. Trailing comma accepted. | |
| #[inline] | |
| Comma1<E>: () = | |
| Delim1<E,",">; | |
| // Comma-separated list of length at least 1. No trailing comma accepted. | |
| #[inline] | |
| Comma1NoTrail<E>: () = | |
| Delim1NoTrail<E,",">; | |
| // Delimited list of length at least 1. Trailing delimeter accepted. | |
| #[inline] | |
| Delim1<E,D>: () = { | |
| (E D)+, | |
| Delim1NoTrail<E, D>, | |
| }; | |
| // Delimited list of length at least 1. No trailing delimeter accepted. | |
| #[inline] | |
| Delim1NoTrail<E,D>: () = { | |
| (E D)* E, | |
| }; | |
| #[inline] | |
| AnyPipe: () = { | |
| "|[|]", | |
| "|[]", | |
| }; | |
| #[inline] | |
| AnyAmp: () = { | |
| "&[&]", | |
| "&[]", | |
| }; | |
| // Extract one `<` when used as part of a series of `<` in a row, like | |
| // `<<` or `<<<` or `<<<<<`. Intended for use in types. | |
| #[inline] | |
| TyLt: () = { | |
| "<[<]", | |
| "<[]", | |
| }; | |
| // Extract one `>` when used as part of a series of `>` in a row, like | |
| // `>>` or `>>>` or `>>>>>`. Intended for use in types. | |
| #[inline] | |
| TyGt: () = { | |
| ">[>]", | |
| ">[]", | |
| }; | |
| #[inline] | |
| Epsilon: () = { | |
| (), | |
| }; | |
| extern { | |
| enum Token { | |
| "!" => Token::Bang, | |
| "#" => Token::Pound, | |
| "$" => Token::Dollar, | |
| "%" => Token::Percent, | |
| "(" => Token::ParenOpen, | |
| ")" => Token::ParenClose, | |
| "*" => Token::Star, | |
| "+" => Token::Plus, | |
| "," => Token::Comma, | |
| "-" => Token::Dash, | |
| "." => Token::Dot, | |
| "/" => Token::Slash, | |
| ":" => Token::Colon, | |
| ";" => Token::Semi, | |
| "=" => Token::Equals, | |
| "?" => Token::QuestionMark, | |
| "@" => Token::At, | |
| "[" => Token::SquareBracketOpen, | |
| "]" => Token::SquareBracketClose, | |
| "^" => Token::Hat, | |
| "{" => Token::CurlyBraceOpen, | |
| "}" => Token::CurlyBraceClose, | |
| "~" => Token::Twiddle, | |
| "==" => Token::EqualsEquals, | |
| "!=" => Token::BangEquals, | |
| "-=" => Token::DashEquals, | |
| "&=" => Token::AmpersandEquals, | |
| "|=" => Token::PipeEquals, | |
| "+=" => Token::PlusEquals, | |
| "*=" => Token::StarEquals, | |
| "/=" => Token::SlashEquals, | |
| "^=" => Token::HatEquals, | |
| "%=" => Token::PercentEquals, | |
| ".." => Token::DotDot, | |
| "..." => Token::DotDotDot, | |
| "::" => Token::ColonColon, | |
| "->" => Token::ThinArrow, | |
| "=>" => Token::FatArrow, | |
| "<<=" => Token::LessLessEqual, | |
| ">>=" => Token::RightRightEqual, | |
| "<-" => Token::LeftThinArrow, | |
| "<=" => Token::LessEqual, | |
| ">=" => Token::RightEqual, | |
| "_" => Token::Underscore, | |
| "|[|]" => Token::PipeFollowedByPipe, | |
| "|[]" => Token::PipeFollowedByOther, | |
| "&[&]" => Token::AmpersandFollowedByAmpersand, | |
| "&[]" => Token::AmpersandFollowedByOther, | |
| "<[<]" => Token::LessFollowedByLess, | |
| "<[]" => Token::LessFollowedByOther, | |
| ">[>]" => Token::GreaterFollowedByGreater, | |
| ">[]" => Token::GreaterFollowedByOther, | |
| "self" => Token::KeywordSelf, | |
| "super" => Token::KeywordSuper, | |
| "static" => Token::KeywordStatic, | |
| "as" => Token::KeywordAs, | |
| "break" => Token::KeywordBreak, | |
| "crate" => Token::KeywordCrate, | |
| "else" => Token::KeywordElse, | |
| "enum" => Token::KeywordEnum, | |
| "extern" => Token::KeywordExtern, | |
| "false" => Token::KeywordFalse, | |
| "fn" => Token::KeywordFn, | |
| "for" => Token::KeywordFor, | |
| "if" => Token::KeywordIf, | |
| "impl" => Token::KeywordImpl, | |
| "in" => Token::KeywordIn, | |
| "let" => Token::KeywordLet, | |
| "loop" => Token::KeywordLoop, | |
| "match" => Token::KeywordMatch, | |
| "mod" => Token::KeywordMod, | |
| "move" => Token::KeywordMove, | |
| "mut" => Token::KeywordMut, | |
| "priv" => Token::KeywordPriv, | |
| "pub" => Token::KeywordPub, | |
| "ref" => Token::KeywordRef, | |
| "return" => Token::KeywordReturn, | |
| "struct" => Token::KeywordStruct, | |
| "true" => Token::KeywordTrue, | |
| "trait" => Token::KeywordTrait, | |
| "type" => Token::KeywordType, | |
| "unsafe" => Token::KeywordUnsafe, | |
| "use" => Token::KeywordUse, | |
| "while" => Token::KeywordWhile, | |
| "continue" => Token::KeywordContinue, | |
| "box" => Token::KeywordBox, | |
| "const" => Token::KeywordConst, | |
| "where" => Token::KeywordWhere, | |
| "typeof" => Token::KeywordTypeof, | |
| LiteralByte => Token::LiteralByte, | |
| LiteralChar => Token::LiteralChar, | |
| LiteralInteger => Token::LiteralInteger, | |
| LiteralFloat => Token::LiteralFloat, | |
| LiteralString => Token::LiteralString, | |
| LiteralStringRaw => Token::LiteralStringRaw, | |
| LiteralByteString => Token::LiteralByteString, | |
| LiteralByteStringRaw => Token::LiteralByteStringRaw, | |
| Identifier => Token::Identifier, | |
| Lifetime => Token::Lifetime, | |
| "//!..." => Token::InnerDocComment, | |
| "///..." => Token::OuterDocComment, | |
| "#!" => Token::Shebang, | |
| "#!..." => Token::ShebangLine, | |
| } | |
| } |