Skip to content

Commit b9c573b

Browse files
committed
Parse all attributes
The file 'sample-sources/attributes.rs' now has a test case for all types of attributes. The parser was again tweaked a bit.
1 parent 934bc6e commit b9c573b

File tree

3 files changed

+131
-61
lines changed

3 files changed

+131
-61
lines changed

sample-sources/attributes.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,92 @@ fn expressions() {
117117

118118
}
119119

120+
fn foreign_items() {
121+
extern "C" {
122+
#[static_outer]
123+
static ext: u8;
124+
125+
#[fn_outer]
126+
fn foo(x: i32, ...);
127+
}
128+
}
129+
130+
#[trait_outer]
131+
trait Trait {
132+
133+
#[const_outer]
134+
const x: i32;
135+
136+
#[method_outer]
137+
fn area(&self) -> f64;
138+
139+
#[type_outer]
140+
type N;
141+
142+
#[macro_outer]
143+
foo!();
144+
}
145+
146+
147+
#[impl_outer]
148+
impl Impls {
149+
#![impl_inner]
150+
151+
#[const_outer]
152+
const x: i32 = 1;
153+
154+
#[method_outer]
155+
fn area(&self) -> f64 {
156+
#![method_inner]
157+
1f64
158+
}
159+
160+
#[type_outer]
161+
type N = i32;
162+
163+
#[macro_outer]
164+
foo!();
165+
}
166+
167+
fn items() {
168+
#[use_outer]
169+
use foo::bar as FooBar;
170+
171+
#[static_outer]
172+
static FOO: i32 = 42;
173+
174+
#[const_outer]
175+
const FOO: i32 = 42;
176+
177+
#[fn_outer]
178+
fn foo(bar: usize) -> usize {
179+
#![fn_inner]
180+
1
181+
}
182+
183+
#[mod_outer]
184+
mod foo { #![mod_inner] }
185+
186+
#[type_outer]
187+
type Foo = Bar<u8>;
188+
189+
#[enum_outer]
190+
enum Foo<A, B> { #[variant_outer] C(A), D(B) }
191+
192+
#[struct_outer]
193+
struct Foo<A> { #[field_outer] x: A }
194+
195+
#[union_outer]
196+
union Foo<A, B> { x: A, y: B }
197+
198+
#[macro_outer]
199+
foo!{ .. }
200+
201+
// #[macrodef_outer]
202+
// macro_rules! foo { .. }
203+
204+
}
205+
206+
fn foo<
207+
#[lifetimedef_outer] 'a: 'b,
208+
>() { }

src/Language/Rust/Parser/Internal.y

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,9 @@ import Text.Read (readMaybe)
269269
-- * 'FIELD' for field access expressions (which bind less tightly than '.' for method calls)
270270
-- * 'VIS' for adjusting the precedence of 'pub' compared to other visbility modifiers (see 'vis')
271271
-- * 'PATH' boosts the precedences of paths in types and expressions
272-
-- * 'DOLLAR' is for a single '$' token not in sequence expression
273272
-- * 'WHERE' is for non-empty where clauses
274273
--
275-
%nonassoc FIELD VIS PATH DOLLAR WHERE
274+
%nonassoc FIELD VIS PATH WHERE
276275

277276
-- These are postfix operators.
278277
%nonassoc '?' '.'
@@ -1190,10 +1189,14 @@ generics :: { Generics Span }
11901189
11911190
-- TODO: Attributes? The AST has them, so the parser should produce them
11921191
ty_param :: { TyParam Span }
1193-
: ident { TyParam [] (unspan $1) [] Nothing (spanOf $1) }
1194-
| ident ':' sep_by1T(ty_param_bound_mod,'+') { TyParam [] (unspan $1) (toList $3) Nothing ($1 # $3) }
1195-
| ident '=' ty { TyParam [] (unspan $1) [] (Just $>) (spanOf $1) }
1196-
| ident ':' sep_by1T(ty_param_bound_mod,'+') '=' ty { TyParam [] (unspan $1) (toList $3) (Just $>) ($1 # $>) }
1192+
: ident { TyParam [] (unspan $1) [] Nothing (spanOf $1) }
1193+
| inner_attrs ident { TyParam (toList $1) (unspan $2) [] Nothing ($1 # $>) }
1194+
| ident ':' sep_by1T(ty_param_bound_mod,'+') { TyParam [] (unspan $1) (toList $3) Nothing ($1 # $>) }
1195+
| inner_attrs ident ':' sep_by1T(ty_param_bound_mod,'+') { TyParam (toList $1) (unspan $2) (toList $4) Nothing ($1 # $>) }
1196+
| ident '=' ty { TyParam [] (unspan $1) [] (Just $>) (spanOf $1) }
1197+
| inner_attrs ident '=' ty { TyParam (toList $1) (unspan $2) [] (Just $>) ($1 # $>) }
1198+
| ident ':' sep_by1T(ty_param_bound_mod,'+') '=' ty { TyParam [] (unspan $1) (toList $3) (Just $>) ($1 # $>) }
1199+
| inner_attrs ident ':' sep_by1T(ty_param_bound_mod,'+') '=' ty { TyParam (toList $1) (unspan $2) (toList $4) (Just $>) ($1 # $>) }
11971200
11981201
stmt_item :: { Item Span }
11991202
: static ident ':' ty '=' expr ';' { Item (unspan $2) [] (Static $4 Immutable $6) InheritedV ($1 # $>) }
@@ -1203,10 +1206,10 @@ stmt_item :: { Item Span }
12031206
| use view_path ';' { Item "" [] (Use $2) InheritedV ($1 # $>) }
12041207
| extern crate ident ';' { Item (unspan $3) [] (ExternCrate Nothing) InheritedV ($1 # $>) }
12051208
| extern crate ident as ident ';' { Item (unspan $5) [] (ExternCrate (Just (unspan $3))) InheritedV ($1 # $>) }
1206-
| const safety fn ident generics fn_decl where_clause inner_attrs_block
1207-
{ Item (unspan $4) (fst $>) (Fn $6 $2 Const Rust $5{ whereClause = $7 } (snd $>)) InheritedV ($1 # snd $>) }
1209+
| const safety fn ident generics fn_decl where_clause inner_attrs_block
1210+
{ Item (unspan $4) (fst $>) (Fn $6 (unspan $2) Const Rust $5{ whereClause = $7 } (snd $>)) InheritedV ($1 # snd $>) }
12081211
| unsafe ext_abi fn ident generics fn_decl where_clause inner_attrs_block
1209-
{ Item (unspan $4) (fst $>) (Fn $6 Unsafe NotConst $2 $5{ whereClause = $7 } (snd $>)) InheritedV ($1 # snd $>) }
1212+
{ Item (unspan $4) (fst $>) (Fn $6 Unsafe NotConst (unspan $2) $5{ whereClause = $7 } (snd $>)) InheritedV ($1 # snd $>) }
12101213
| extern abi fn ident generics fn_decl where_clause inner_attrs_block
12111214
{ Item (unspan $4) (fst $>) (Fn $6 Normal NotConst $2 $5{ whereClause = $7 } (snd $>)) InheritedV ($1 # snd $>) }
12121215
| fn ident generics fn_decl where_clause inner_attrs_block
@@ -1224,14 +1227,10 @@ stmt_item :: { Item Span }
12241227
| item_trait { $1 }
12251228
12261229
item_trait :: { Item Span }
1227-
: safety_trait ident generics ':' sep_by1T(ty_param_bound,'+') where_clause '{' many(trait_item) '}'
1228-
{ Item (unspan $2) [] (Trait (unspan $1) $3{ whereClause = $6 } (toList $5) $8) InheritedV ($1 # $>) }
1229-
| safety_trait ident generics where_clause '{' many(trait_item) '}'
1230-
{ Item (unspan $2) [] (Trait (unspan $1) $3{ whereClause = $4 } [] $6) InheritedV ($1 # $>) }
1231-
1232-
safety_trait :: { Spanned Unsafety }
1233-
: trait { Spanned Normal (spanOf $1) }
1234-
| unsafe trait { Spanned Unsafe ($1 # $2) }
1230+
: safety trait ident generics ':' sep_by1T(ty_param_bound,'+') where_clause '{' many(trait_item) '}'
1231+
{ Item (unspan $3) [] (Trait (unspan $1) $4{ whereClause = $7 } (toList $6) $9) InheritedV ($1 # $2 # $>) }
1232+
| safety trait ident generics where_clause '{' many(trait_item) '}'
1233+
{ Item (unspan $3) [] (Trait (unspan $1) $4{ whereClause = $5 } [] $7) InheritedV ($1 # $2 # $>) }
12351234
12361235
struct_decl_args :: { (WhereClause Span, VariantData Span) }
12371236
: where_clause ';' { ($1, UnitD ($1 # $>)) }
@@ -1268,62 +1267,50 @@ where_predicate :: { WherePredicate Span }
12681267
12691268
12701269
item_impl :: { Item Span }
1271-
: safety_impl generics ty_prim where_clause '{' impl_items '}'
1272-
{ Item (mkIdent "") (fst $6) (Impl (unspan $1) Positive $2{ whereClause = $4 } Nothing $3 (snd $6)) InheritedV ($1 # $>) }
1273-
| safety_impl generics '(' ty_no_plus ')' where_clause '{' impl_items '}'
1274-
{ Item (mkIdent "") (fst $8) (Impl (unspan $1) Positive $2{ whereClause = $6 } Nothing (ParenTy $4 ($3 # $5)) (snd $8)) InheritedV ($1 # $>) }
1275-
| safety_impl generics '!' trait_ref for ty where_clause '{' impl_items '}'
1276-
{ Item (mkIdent "") (fst $9) (Impl (unspan $1) Negative $2{ whereClause = $7 } (Just $4) $6 (snd $9)) InheritedV ($1 # $>) }
1277-
| safety_impl generics trait_ref for ty where_clause '{' impl_items '}'
1278-
{ Item (mkIdent "") (fst $8) (Impl (unspan $1) Positive $2{ whereClause = $6 } (Just $3) $5 (snd $8)) InheritedV ($1 # $>) }
1279-
| safety_impl generics trait_ref for '..' '{' '}'
1280-
{% case $2 of
1281-
Generics [] [] _ _ -> pure $ Item (mkIdent "") [] (DefaultImpl (unspan $1) $3) InheritedV ($1 # $>)
1270+
: safety impl generics ty_prim where_clause '{' impl_items '}'
1271+
{ Item (mkIdent "") (fst $7) (Impl (unspan $1) Positive $3{ whereClause = $5 } Nothing $4 (snd $7)) InheritedV ($1 # $2 # $>) }
1272+
| safety impl generics '(' ty_no_plus ')' where_clause '{' impl_items '}'
1273+
{ Item (mkIdent "") (fst $9) (Impl (unspan $1) Positive $3{ whereClause = $7 } Nothing (ParenTy $5 ($4 # $6)) (snd $9)) InheritedV ($1 # $2 # $>) }
1274+
| safety impl generics '!' trait_ref for ty where_clause '{' impl_items '}'
1275+
{ Item (mkIdent "") (fst $10) (Impl (unspan $1) Negative $3{ whereClause = $8 } (Just $5) $7 (snd $10)) InheritedV ($1 # $2 # $>) }
1276+
| safety impl generics trait_ref for ty where_clause '{' impl_items '}'
1277+
{ Item (mkIdent "") (fst $9) (Impl (unspan $1) Positive $3{ whereClause = $7 } (Just $4) $6 (snd $9)) InheritedV ($1 # $2 # $>) }
1278+
| safety impl generics trait_ref for '..' '{' '}'
1279+
{% case $3 of
1280+
Generics [] [] _ _ -> pure $ Item (mkIdent "") [] (DefaultImpl (unspan $1) $4) InheritedV ($1 # $2 # $>)
12821281
_ -> fail "non-empty generics are no allowed on default implementations"
12831282
}
12841283
1285-
safety_impl :: { Spanned Unsafety }
1286-
: impl { Spanned Normal (spanOf $1) }
1287-
| unsafe impl { Spanned Unsafe ($1 # $2) }
1288-
12891284
impl_items :: { ([Attribute Span], [ImplItem Span]) }
12901285
: many(impl_item) { ([], $1) }
12911286
| inner_attrs many(impl_item) { (toList $1, $2) }
12921287
12931288
impl_item :: { ImplItem Span }
12941289
: ntImplItem { $1 }
1295-
| many(outer_attribute) vis def type ident '=' ty ';' { ImplItem (unspan $5) (unspan $2) $3 $1 (TypeI $7) ($1 # $2 # $>) }
1296-
| many(outer_attribute) vis def const ident ':' ty '=' expr ';' { ImplItem (unspan $5) (unspan $2) $3 $1 (ConstI $7 $9) ($1 # $2 # $>) }
1297-
| many(outer_attribute) vis def mod_mac { ImplItem (mkIdent "") (unspan $2) $3 $1 (MacroI $4) ($1 # $2 # $>) }
1290+
| many(outer_attribute) vis def type ident '=' ty ';' { ImplItem (unspan $5) (unspan $2) (unspan $3) $1 (TypeI $7) ($1 # $2 # $>) }
1291+
| many(outer_attribute) vis def const ident ':' ty '=' expr ';' { ImplItem (unspan $5) (unspan $2) (unspan $3) $1 (ConstI $7 $9) ($1 # $2 # $>) }
1292+
| many(outer_attribute) vis def mod_mac { ImplItem (mkIdent "") (unspan $2) (unspan $3) $1 (MacroI $4) ($1 # $2 # $>) }
12981293
| many(outer_attribute) vis def const safety fn ident generics fn_decl_with_self where_clause inner_attrs_block
1299-
{ ImplItem (unspan $7) (unspan $2) $3 ($1 ++ fst $>) (MethodI (MethodSig $5 Const Rust $9 $8{ whereClause = $10 }) (snd $>)) ($1 # $2 # snd $>) }
1294+
{ ImplItem (unspan $7) (unspan $2) (unspan $3) ($1 ++ fst $>) (MethodI (MethodSig (unspan $5) Const Rust $9 $8{ whereClause = $10 }) (snd $>)) ($1 # $2 # snd $>) }
13001295
| many(outer_attribute) vis def safety ext_abi fn ident generics fn_decl_with_self where_clause inner_attrs_block
1301-
{ ImplItem (unspan $7) (unspan $2) $3 ($1 ++ fst $>) (MethodI (MethodSig $4 NotConst $5 $9 $8{ whereClause = $10 }) (snd $>)) ($1 # $2 # snd $>) }
1296+
{ ImplItem (unspan $7) (unspan $2) (unspan $3) ($1 ++ fst $>) (MethodI (MethodSig (unspan $4) NotConst (unspan $5) $9 $8{ whereClause = $10 }) (snd $>)) ($1 # $2 # snd $>) }
13021297
13031298
trait_item :: { TraitItem Span }
13041299
: ntTraitItem { $1 }
13051300
| many(outer_attribute) const ident ':' ty initializer ';' { TraitItem (unspan $3) $1 (ConstT $5 $6) ($1 # $2 # $>) }
13061301
| many(outer_attribute) mod_mac { TraitItem (mkIdent "") $1 (MacroT $2) ($1 # $>) }
13071302
| many(outer_attribute) type ty_param ';' { let TyParam _ i b d _ = $3 in TraitItem i $1 (TypeT b d) ($1 # $2 # $>) }
1308-
| many(outer_attribute) safetyS ext_abiS fn ident generics fn_decl_with_self where_clause ';'
1303+
| many(outer_attribute) safety ext_abi fn ident generics fn_decl_with_self where_clause ';'
13091304
{ TraitItem (unspan $5) $1 (MethodT (MethodSig (unspan $2) NotConst (unspan $3) $7 $6{ whereClause = $8 }) Nothing) ($1 # $2 # $3 # $4 # $>) }
1310-
| many(outer_attribute) safetyS ext_abiS fn ident generics fn_decl_with_self where_clause block
1305+
| many(outer_attribute) safety ext_abi fn ident generics fn_decl_with_self where_clause block
13111306
{ TraitItem (unspan $5) $1 (MethodT (MethodSig (unspan $2) NotConst (unspan $3) $7 $6{ whereClause = $8 }) (Just $>)) ($1 # $2 # $3 # $4 # $>) }
13121307
13131308
1314-
safety :: { Unsafety }
1315-
: {- empty -} { Normal }
1316-
| unsafe { Unsafe }
1317-
1318-
ext_abi :: { Abi }
1319-
: {- empty -} { Rust }
1320-
| extern abi { $2 }
1321-
1322-
safetyS :: { Spanned Unsafety }
1309+
safety :: { Spanned Unsafety }
13231310
: {- empty -} { pure Normal }
13241311
| unsafe { Spanned Unsafe (spanOf $1) }
13251312
1326-
ext_abiS :: { Spanned Abi }
1313+
ext_abi :: { Spanned Abi }
13271314
: {- empty -} { pure Rust }
13281315
| extern abi { Spanned $2 (spanOf $1) }
13291316
@@ -1333,9 +1320,9 @@ vis :: { Spanned (Visibility Span) }
13331320
| pub '(' crate ')' { Spanned CrateV ($1 # $4) }
13341321
| pub '(' mod_path ')' { Spanned (RestrictedV $3) ($1 # $4) }
13351322
1336-
def :: { Defaultness }
1337-
: {- empty -} %prec mut { Final }
1338-
| default { Default }
1323+
def :: { Spanned Defaultness }
1324+
: {- empty -} %prec mut { pure Final }
1325+
| default { Spanned Default (spanOf $1) }
13391326
13401327
view_path :: { ViewPath Span }
13411328
: '::' sep_by1(self_or_ident,'::') { let n = fmap unspan $2 in ViewPathSimple True (N.init n) (PathListItem (N.last n) Nothing mempty) ($1 # $>) }
@@ -1435,7 +1422,7 @@ token :: { Spanned Token }
14351422
| '<-' { $1 }
14361423
| '=>' { $1 }
14371424
| '#' { $1 }
1438-
| '$' %prec DOLLAR { $1 }
1425+
| '$' { $1 }
14391426
| '?' { $1 }
14401427
| '#!' { $1 }
14411428
-- Literals.

src/Language/Rust/Syntax/AST.hs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ module Language.Rust.Syntax.AST (
3939
-- ** Blocks
4040
Block(..),
4141
-- ** Token trees
42-
TokenTree(..), Nonterminal(..), KleeneOp(..), Mac(..), MacStmtStyle(..),
42+
TokenTree(..), Nonterminal(..), Mac(..), MacStmtStyle(..),
4343
) where
4444

4545
import {-# SOURCE #-} Language.Rust.Syntax.Token (Token, Delim)
@@ -563,7 +563,7 @@ data ItemKind a
563563
-- Example: @type Foo = Bar\<u8\>;@
564564
| TyAlias (Ty a) (Generics a)
565565
-- | enum definition (@enum@ or @pub enum@) (@syntax::ast::EnumDef@).
566-
-- Example: @enum Foo\<A, B\> { C\<A\>, D\<B\> }@
566+
-- Example: @enum Foo\<A, B\> { C(A), D(B) }@
567567
| Enum [Variant a] (Generics a)
568568
-- | struct definition (@struct@ or @pub struct@).
569569
-- Example: @struct Foo\<A\> { x: A }@
@@ -590,12 +590,6 @@ data ItemKind a
590590
| MacroDef [TokenTree]
591591
deriving (Eq, Functor, Show, Typeable, Data, Generic)
592592

593-
-- | A Kleene-style repetition operator for token sequences (@syntax::ast::KleeneOp@). This refers
594-
-- to the @*@ or @+@ suffix on a 'Sequence' token tree.
595-
--
596-
-- Examples: @+@ as in @$($inits:expr),+@
597-
data KleeneOp = ZeroOrMore | OneOrMore deriving (Eq, Enum, Bounded, Show, Typeable, Data, Generic)
598-
599593
-- | A lifetime is a name for a scope in a program (@syntax::ast::Lifetime@). One of the novel
600594
-- features of Rust is that code can be parametrized over lifetimes. Syntactically, they are like
601595
-- regular identifiers, but start with a tick @\'@ mark.

0 commit comments

Comments
 (0)