@@ -124,6 +124,7 @@ pub enum Setting<T> {
124
124
arg : Namespaced < T > ,
125
125
} ,
126
126
Num ( u64 , T ) ,
127
+ String ( String , T ) ,
127
128
}
128
129
129
130
/// Parser for the `%grmtools` section
@@ -178,6 +179,7 @@ impl From<Value<Span>> for Value<Location> {
178
179
} ,
179
180
} ,
180
181
Setting :: Num ( num, num_loc) => Setting :: Num ( num, num_loc. into ( ) ) ,
182
+ Setting :: String ( s, str_loc) => Setting :: String ( s, str_loc. into ( ) ) ,
181
183
} ) ,
182
184
}
183
185
}
@@ -190,6 +192,7 @@ lazy_static! {
190
192
. build( )
191
193
. unwrap( ) ;
192
194
static ref RE_DIGITS : Regex = Regex :: new( r"^[0-9]+" ) . unwrap( ) ;
195
+ static ref RE_STRING : Regex = Regex :: new( r#"^\"(\\.|[^"\\])*\""# ) . unwrap( ) ;
193
196
}
194
197
195
198
const MAGIC : & str = "%grmtools" ;
@@ -244,38 +247,50 @@ impl<'input> GrmtoolsSectionParser<'input> {
244
247
i = self . parse_ws ( num_span. end ( ) ) ;
245
248
Ok ( ( key_name, key_span, Value :: Setting ( val) , i) )
246
249
}
247
- None => {
248
- let ( path_val, j) = self . parse_namespaced ( i) ?;
249
- i = self . parse_ws ( j) ;
250
- if let Some ( j) = self . lookahead_is ( "(" , i) {
251
- let ( arg, j) = self . parse_namespaced ( j) ?;
250
+ None => match RE_STRING . find ( & self . src [ i..] ) {
251
+ Some ( m) => {
252
+ let end = i + m. end ( ) ;
253
+ // Trim the leading and trailing quotes.
254
+ let str_span = Span :: new ( i + m. start ( ) + 1 , end - 1 ) ;
255
+ let str = & self . src [ str_span. start ( ) ..str_span. end ( ) ] ;
256
+ let setting = Setting :: String ( str. to_string ( ) , str_span) ;
257
+ // After the trailing quotes.
258
+ i = self . parse_ws ( end) ;
259
+ Ok ( ( key_name, key_span, Value :: Setting ( setting) , i) )
260
+ }
261
+ None => {
262
+ let ( path_val, j) = self . parse_namespaced ( i) ?;
252
263
i = self . parse_ws ( j) ;
253
- if let Some ( j) = self . lookahead_is ( ")" , i) {
264
+ if let Some ( j) = self . lookahead_is ( "(" , i) {
265
+ let ( arg, j) = self . parse_namespaced ( j) ?;
254
266
i = self . parse_ws ( j) ;
267
+ if let Some ( j) = self . lookahead_is ( ")" , i) {
268
+ i = self . parse_ws ( j) ;
269
+ Ok ( (
270
+ key_name,
271
+ key_span,
272
+ Value :: Setting ( Setting :: Constructor {
273
+ ctor : path_val,
274
+ arg,
275
+ } ) ,
276
+ i,
277
+ ) )
278
+ } else {
279
+ Err ( HeaderError {
280
+ kind : HeaderErrorKind :: ExpectedToken ( ')' ) ,
281
+ locations : vec ! [ Span :: new( i, i) ] ,
282
+ } )
283
+ }
284
+ } else {
255
285
Ok ( (
256
286
key_name,
257
287
key_span,
258
- Value :: Setting ( Setting :: Constructor {
259
- ctor : path_val,
260
- arg,
261
- } ) ,
288
+ Value :: Setting ( Setting :: Unitary ( path_val) ) ,
262
289
i,
263
290
) )
264
- } else {
265
- Err ( HeaderError {
266
- kind : HeaderErrorKind :: ExpectedToken ( ')' ) ,
267
- locations : vec ! [ Span :: new( i, i) ] ,
268
- } )
269
291
}
270
- } else {
271
- Ok ( (
272
- key_name,
273
- key_span,
274
- Value :: Setting ( Setting :: Unitary ( path_val) ) ,
275
- i,
276
- ) )
277
292
}
278
- }
293
+ } ,
279
294
}
280
295
} else {
281
296
Ok ( ( key_name, key_span, Value :: Flag ( true , key_span) , i) )
@@ -489,6 +504,14 @@ impl<T: Clone> TryFrom<&Value<T>> for YaccKind {
489
504
) ,
490
505
locations : vec ! [ loc. clone( ) ] ,
491
506
} ) ,
507
+ Value :: Setting ( Setting :: String ( _, loc) ) => Err ( HeaderError {
508
+ kind : HeaderErrorKind :: ConversionError (
509
+ "From<YaccKind>" ,
510
+ "Cannot convert string to YaccKind" ,
511
+ ) ,
512
+ locations : vec ! [ loc. clone( ) ] ,
513
+ } ) ,
514
+
492
515
Value :: Setting ( Setting :: Unitary ( Namespaced {
493
516
namespace,
494
517
member : ( yk_value, yk_value_loc) ,
0 commit comments