11use crate :: {
22 markmap:: { Entry , MarkMap } ,
3- yacc:: { ParserError , YaccKind , YaccOriginalActionKind } ,
3+ yacc:: {
4+ parser:: SpansKind , YaccGrammarError , YaccGrammarErrorKind , YaccKind , YaccOriginalActionKind ,
5+ } ,
46 Location , Span ,
57} ;
68use lazy_static:: lazy_static;
@@ -14,21 +16,37 @@ use std::{error::Error, fmt};
1416/// * An error during parsing the section.
1517/// * An error resulting from a value in the section having an invalid value.
1618#[ derive( Debug , Clone ) ]
17- pub struct HeaderError {
19+ #[ doc( hidden) ]
20+ pub struct HeaderError < T > {
1821 pub kind : HeaderErrorKind ,
19- pub locations : Vec < Location > ,
22+ pub locations : Vec < T > ,
2023}
2124
22- impl Error for HeaderError { }
23- impl fmt:: Display for HeaderError {
25+ impl < T : fmt :: Debug > Error for HeaderError < T > { }
26+ impl < T > fmt:: Display for HeaderError < T > {
2427 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2528 write ! ( f, "{}" , self . kind)
2629 }
2730}
2831
29- impl From < HeaderError > for ParserError {
30- fn from ( e : HeaderError ) -> ParserError {
31- ParserError :: HeaderError ( e)
32+ impl From < HeaderError < Span > > for YaccGrammarError {
33+ fn from ( e : HeaderError < Span > ) -> YaccGrammarError {
34+ YaccGrammarError {
35+ kind : YaccGrammarErrorKind :: Header ( e. kind , e. spanskind ( ) ) ,
36+ spans : e. locations ,
37+ }
38+ }
39+ }
40+
41+ // This is essentially a tuple that needs a newtype so we can implement `From` for it.
42+ // Thus we aren't worried about it being `pub`.
43+ #[ derive( Debug , PartialEq ) ]
44+ #[ doc( hidden) ]
45+ pub struct HeaderValue < T > ( pub T , pub Value < T > ) ;
46+
47+ impl From < HeaderValue < Span > > for HeaderValue < Location > {
48+ fn from ( hv : HeaderValue < Span > ) -> HeaderValue < Location > {
49+ HeaderValue ( hv. 0 . into ( ) , hv. 1 . into ( ) )
3250 }
3351}
3452
@@ -60,6 +78,16 @@ impl fmt::Display for HeaderErrorKind {
6078 }
6179}
6280
81+ impl < T > HeaderError < T > {
82+ /// Returns the [SpansKind] associated with this error.
83+ pub fn spanskind ( & self ) -> SpansKind {
84+ match self . kind {
85+ HeaderErrorKind :: DuplicateEntry => SpansKind :: DuplicationError ,
86+ _ => SpansKind :: Error ,
87+ }
88+ }
89+ }
90+
6391/// Indicates a value prefixed by an optional namespace.
6492/// `Foo::Bar` with optional `Foo` specified being
6593/// ```rust,ignore
@@ -78,24 +106,24 @@ impl fmt::Display for HeaderErrorKind {
78106/// ```
79107#[ derive( Debug , Eq , PartialEq ) ]
80108#[ doc( hidden) ]
81- pub struct Namespaced {
82- pub namespace : Option < ( String , Location ) > ,
83- pub member : ( String , Location ) ,
109+ pub struct Namespaced < T > {
110+ pub namespace : Option < ( String , T ) > ,
111+ pub member : ( String , T ) ,
84112}
85113
86114#[ derive( Debug , Eq , PartialEq ) ]
87115#[ doc( hidden) ]
88- pub enum Setting {
116+ pub enum Setting < T > {
89117 /// A value like `YaccKind::Grmtools`
90- Unitary ( Namespaced ) ,
118+ Unitary ( Namespaced < T > ) ,
91119 /// A value like `YaccKind::Original(UserActions)`.
92120 /// In that example the field ctor would be: `Namespaced { namespace: "YaccKind", member: "Original" }`.
93121 /// The field would be `Namespaced{ None, UserActions }`.
94122 Constructor {
95- ctor : Namespaced ,
96- arg : Namespaced ,
123+ ctor : Namespaced < T > ,
124+ arg : Namespaced < T > ,
97125 } ,
98- Num ( u64 , Location ) ,
126+ Num ( u64 , T ) ,
99127}
100128
101129/// Parser for the `%grmtools` section
@@ -111,9 +139,48 @@ pub struct GrmtoolsSectionParser<'input> {
111139/// like booleans, numeric types, and string values.
112140#[ derive( Debug , Eq , PartialEq ) ]
113141#[ doc( hidden) ]
114- pub enum Value {
115- Flag ( bool , Location ) ,
116- Setting ( Setting ) ,
142+ pub enum Value < T > {
143+ Flag ( bool , T ) ,
144+ Setting ( Setting < T > ) ,
145+ }
146+
147+ impl From < Value < Span > > for Value < Location > {
148+ fn from ( v : Value < Span > ) -> Value < Location > {
149+ match v {
150+ Value :: Flag ( flag, u) => Value :: Flag ( flag, u. into ( ) ) ,
151+ Value :: Setting ( s) => Value :: Setting ( match s {
152+ Setting :: Unitary ( Namespaced {
153+ namespace,
154+ member : ( m, ml) ,
155+ } ) => Setting :: Unitary ( Namespaced {
156+ namespace : namespace. map ( |( n, nl) | ( n, nl. into ( ) ) ) ,
157+ member : ( m, ml. into ( ) ) ,
158+ } ) ,
159+ Setting :: Constructor {
160+ ctor :
161+ Namespaced {
162+ namespace : ctor_ns,
163+ member : ( ctor_m, ctor_ml) ,
164+ } ,
165+ arg :
166+ Namespaced {
167+ namespace : arg_ns,
168+ member : ( arg_m, arg_ml) ,
169+ } ,
170+ } => Setting :: Constructor {
171+ ctor : Namespaced {
172+ namespace : ctor_ns. map ( |( ns, ns_l) | ( ns, ns_l. into ( ) ) ) ,
173+ member : ( ctor_m, ctor_ml. into ( ) ) ,
174+ } ,
175+ arg : Namespaced {
176+ namespace : arg_ns. map ( |( ns, ns_l) | ( ns, ns_l. into ( ) ) ) ,
177+ member : ( arg_m, arg_ml. into ( ) ) ,
178+ } ,
179+ } ,
180+ Setting :: Num ( num, num_loc) => Setting :: Num ( num, num_loc. into ( ) ) ,
181+ } ) ,
182+ }
183+ }
117184}
118185
119186lazy_static ! {
@@ -127,11 +194,11 @@ lazy_static! {
127194
128195const MAGIC : & str = "%grmtools" ;
129196
130- fn add_duplicate_occurrence (
131- errs : & mut Vec < HeaderError > ,
197+ fn add_duplicate_occurrence < T : Eq + PartialEq + Clone > (
198+ errs : & mut Vec < HeaderError < T > > ,
132199 kind : HeaderErrorKind ,
133- orig_loc : Location ,
134- dup_loc : Location ,
200+ orig_loc : T ,
201+ dup_loc : T ,
135202) {
136203 if !errs. iter_mut ( ) . any ( |e| {
137204 if e. kind == kind && e. locations [ 0 ] == orig_loc {
@@ -152,18 +219,18 @@ impl<'input> GrmtoolsSectionParser<'input> {
152219 pub fn parse_value (
153220 & ' _ self ,
154221 mut i : usize ,
155- ) -> Result < ( String , Location , Value , usize ) , HeaderError > {
222+ ) -> Result < ( String , Span , Value < Span > , usize ) , HeaderError < Span > > {
156223 if let Some ( j) = self . lookahead_is ( "!" , i) {
157224 let ( flag_name, k) = self . parse_name ( j) ?;
158225 Ok ( (
159226 flag_name,
160- Location :: Span ( Span :: new ( j, k) ) ,
161- Value :: Flag ( false , Location :: Span ( Span :: new ( i, k) ) ) ,
227+ Span :: new ( j, k) ,
228+ Value :: Flag ( false , Span :: new ( i, k) ) ,
162229 self . parse_ws ( k) ,
163230 ) )
164231 } else {
165232 let ( key_name, j) = self . parse_name ( i) ?;
166- let key_span = Location :: Span ( Span :: new ( i, j) ) ;
233+ let key_span = Span :: new ( i, j) ;
167234 i = self . parse_ws ( j) ;
168235 if let Some ( j) = self . lookahead_is ( ":" , i) {
169236 i = self . parse_ws ( j) ;
@@ -173,7 +240,7 @@ impl<'input> GrmtoolsSectionParser<'input> {
173240 let num_str = & self . src [ num_span. start ( ) ..num_span. end ( ) ] ;
174241 // If the above regex matches we expect this to succeed.
175242 let num = str:: parse :: < u64 > ( num_str) . unwrap ( ) ;
176- let val = Setting :: Num ( num, Location :: Span ( num_span) ) ;
243+ let val = Setting :: Num ( num, num_span) ;
177244 i = self . parse_ws ( num_span. end ( ) ) ;
178245 Ok ( ( key_name, key_span, Value :: Setting ( val) , i) )
179246 }
@@ -197,7 +264,7 @@ impl<'input> GrmtoolsSectionParser<'input> {
197264 } else {
198265 Err ( HeaderError {
199266 kind : HeaderErrorKind :: ExpectedToken ( ')' ) ,
200- locations : vec ! [ Location :: Span ( Span :: new( i, i) ) ] ,
267+ locations : vec ! [ Span :: new( i, i) ] ,
201268 } )
202269 }
203270 } else {
@@ -211,20 +278,23 @@ impl<'input> GrmtoolsSectionParser<'input> {
211278 }
212279 }
213280 } else {
214- Ok ( ( key_name, key_span. clone ( ) , Value :: Flag ( true , key_span) , i) )
281+ Ok ( ( key_name, key_span, Value :: Flag ( true , key_span) , i) )
215282 }
216283 }
217284 }
218285
219- fn parse_namespaced ( & self , mut i : usize ) -> Result < ( Namespaced , usize ) , HeaderError > {
286+ fn parse_namespaced (
287+ & self ,
288+ mut i : usize ,
289+ ) -> Result < ( Namespaced < Span > , usize ) , HeaderError < Span > > {
220290 // Either a name alone, or a namespace which will be followed by a member.
221291 let ( name, j) = self . parse_name ( i) ?;
222- let name_span = Location :: Span ( Span :: new ( i, j) ) ;
292+ let name_span = Span :: new ( i, j) ;
223293 i = self . parse_ws ( j) ;
224294 if let Some ( j) = self . lookahead_is ( "::" , i) {
225295 i = self . parse_ws ( j) ;
226296 let ( member_val, j) = self . parse_name ( i) ?;
227- let member_val_span = Location :: Span ( Span :: new ( i, j) ) ;
297+ let member_val_span = Span :: new ( i, j) ;
228298 i = self . parse_ws ( j) ;
229299 Ok ( (
230300 Namespaced {
@@ -258,7 +328,7 @@ impl<'input> GrmtoolsSectionParser<'input> {
258328 }
259329
260330 #[ allow( clippy:: type_complexity) ]
261- pub fn parse ( & ' _ self ) -> Result < ( Header , usize ) , Vec < HeaderError > > {
331+ pub fn parse ( & ' _ self ) -> Result < ( Header < Span > , usize ) , Vec < HeaderError < Span > > > {
262332 let mut errs = Vec :: new ( ) ;
263333 if let Some ( mut i) = self . lookahead_is ( MAGIC , self . parse_ws ( 0 ) ) {
264334 let mut ret = Header :: new ( ) ;
@@ -276,16 +346,16 @@ impl<'input> GrmtoolsSectionParser<'input> {
276346 } ;
277347 match ret. entry ( key) {
278348 Entry :: Occupied ( orig) => {
279- let ( orig_loc, _) : & ( Location , Value ) = orig. get ( ) ;
349+ let HeaderValue ( orig_loc, _) : & HeaderValue < Span > = orig. get ( ) ;
280350 add_duplicate_occurrence (
281351 & mut errs,
282352 HeaderErrorKind :: DuplicateEntry ,
283- orig_loc. clone ( ) ,
353+ * orig_loc,
284354 key_loc,
285355 )
286356 }
287357 Entry :: Vacant ( entry) => {
288- entry. insert ( ( key_loc, val) ) ;
358+ entry. insert ( HeaderValue ( key_loc, val) ) ;
289359 }
290360 }
291361 if let Some ( j) = self . lookahead_is ( "," , j) {
@@ -305,32 +375,29 @@ impl<'input> GrmtoolsSectionParser<'input> {
305375 } else {
306376 errs. push ( HeaderError {
307377 kind : HeaderErrorKind :: ExpectedToken ( '}' ) ,
308- locations : vec ! [ Location :: Span ( Span :: new(
309- section_start_pos,
310- self . src. len( ) ,
311- ) ) ] ,
378+ locations : vec ! [ Span :: new( section_start_pos, self . src. len( ) ) ] ,
312379 } ) ;
313380 Err ( errs)
314381 }
315382 } else {
316383 errs. push ( HeaderError {
317384 kind : HeaderErrorKind :: ExpectedToken ( '{' ) ,
318- locations : vec ! [ Location :: Span ( Span :: new( i, i) ) ] ,
385+ locations : vec ! [ Span :: new( i, i) ] ,
319386 } ) ;
320387 Err ( errs)
321388 }
322389 } else if self . required {
323390 errs. push ( HeaderError {
324391 kind : HeaderErrorKind :: MissingGrmtoolsSection ,
325- locations : vec ! [ Location :: Span ( Span :: new( 0 , 0 ) ) ] ,
392+ locations : vec ! [ Span :: new( 0 , 0 ) ] ,
326393 } ) ;
327394 Err ( errs)
328395 } else {
329396 Ok ( ( Header :: new ( ) , 0 ) )
330397 }
331398 }
332399
333- fn parse_name ( & self , i : usize ) -> Result < ( String , usize ) , HeaderError > {
400+ fn parse_name ( & self , i : usize ) -> Result < ( String , usize ) , HeaderError < Span > > {
334401 match RE_NAME . find ( & self . src [ i..] ) {
335402 Some ( m) => {
336403 assert_eq ! ( m. start( ) , 0 ) ;
@@ -341,7 +408,7 @@ impl<'input> GrmtoolsSectionParser<'input> {
341408 }
342409 None => Err ( HeaderError {
343410 kind : HeaderErrorKind :: IllegalName ,
344- locations : vec ! [ Location :: Span ( Span :: new( i, i) ) ] ,
411+ locations : vec ! [ Span :: new( i, i) ] ,
345412 } ) ,
346413 }
347414 }
@@ -363,11 +430,12 @@ impl<'input> GrmtoolsSectionParser<'input> {
363430}
364431
365432/// A data structure representation of the %grmtools section.
366- pub type Header = MarkMap < String , ( Location , Value ) > ;
433+ #[ doc( hidden) ]
434+ pub type Header < T > = MarkMap < String , HeaderValue < T > > ;
367435
368- impl TryFrom < YaccKind > for Value {
369- type Error = HeaderError ;
370- fn try_from ( kind : YaccKind ) -> Result < Value , HeaderError > {
436+ impl TryFrom < YaccKind > for Value < Location > {
437+ type Error = HeaderError < Location > ;
438+ fn try_from ( kind : YaccKind ) -> Result < Value < Location > , HeaderError < Location > > {
371439 let from_loc = Location :: Other ( "From<YaccKind>" . to_string ( ) ) ;
372440 Ok ( match kind {
373441 YaccKind :: Grmtools => Value :: Setting ( Setting :: Unitary ( Namespaced {
@@ -402,9 +470,9 @@ impl TryFrom<YaccKind> for Value {
402470 }
403471}
404472
405- impl TryFrom < & Value > for YaccKind {
406- type Error = HeaderError ;
407- fn try_from ( value : & Value ) -> Result < YaccKind , HeaderError > {
473+ impl < T : Clone > TryFrom < & Value < T > > for YaccKind {
474+ type Error = HeaderError < T > ;
475+ fn try_from ( value : & Value < T > ) -> Result < YaccKind , HeaderError < T > > {
408476 let mut err_locs = Vec :: new ( ) ;
409477 match value {
410478 Value :: Flag ( _, loc) => Err ( HeaderError {
0 commit comments