@@ -137,6 +137,8 @@ pub enum Setting<T> {
137137 } ,
138138 Num ( u64 , T ) ,
139139 String ( String , T ) ,
140+ // The two `T` values are for the spans of the open and close brackets `[`, and `]`.
141+ Array ( Vec < Setting < T > > , T , T ) ,
140142}
141143
142144/// Parser for the `%grmtools` section
@@ -157,92 +159,54 @@ pub enum Value<T> {
157159 Setting ( Setting < T > ) ,
158160}
159161
160- impl From < Value < Span > > for Value < Location > {
161- fn from ( v : Value < Span > ) -> Value < Location > {
162- match v {
163- Value :: Flag ( flag, u) => Value :: Flag ( flag, u. into ( ) ) ,
164- Value :: Setting ( s) => Value :: Setting ( match s {
165- Setting :: Unitary ( Namespaced {
166- namespace,
167- member : ( m, ml) ,
168- } ) => Setting :: Unitary ( Namespaced {
169- namespace : namespace. map ( |( n, nl) | ( n, nl. into ( ) ) ) ,
170- member : ( m, ml. into ( ) ) ,
171- } ) ,
172- Setting :: Constructor {
173- ctor :
174- Namespaced {
175- namespace : ctor_ns,
176- member : ( ctor_m, ctor_ml) ,
177- } ,
178- arg :
179- Namespaced {
180- namespace : arg_ns,
181- member : ( arg_m, arg_ml) ,
182- } ,
183- } => Setting :: Constructor {
184- ctor : Namespaced {
185- namespace : ctor_ns. map ( |( ns, ns_l) | ( ns, ns_l. into ( ) ) ) ,
186- member : ( ctor_m, ctor_ml. into ( ) ) ,
187- } ,
188- arg : Namespaced {
189- namespace : arg_ns. map ( |( ns, ns_l) | ( ns, ns_l. into ( ) ) ) ,
190- member : ( arg_m, arg_ml. into ( ) ) ,
191- } ,
192- } ,
193- Setting :: Num ( num, num_loc) => Setting :: Num ( num, num_loc. into ( ) ) ,
194- Setting :: String ( s, str_loc) => Setting :: String ( s, str_loc. into ( ) ) ,
195- } ) ,
196- }
197- }
198- }
199-
200- impl < T > Value < T > {
201- pub fn expect_string_with_context ( & self , ctxt : & str ) -> Result < & str , Box < dyn Error > > {
202- let found = match self {
203- Value :: Flag ( _, _) => "bool" . to_string ( ) ,
204- Value :: Setting ( Setting :: String ( s, _) ) => {
205- return Ok ( s) ;
206- }
207- Value :: Setting ( Setting :: Num ( _, _) ) => "numeric" . to_string ( ) ,
208- Value :: Setting ( Setting :: Unitary ( Namespaced {
162+ impl From < Setting < Span > > for Setting < Location > {
163+ fn from ( s : Setting < Span > ) -> Setting < Location > {
164+ match s {
165+ Setting :: Unitary ( Namespaced {
209166 namespace,
210- member : ( member, _) ,
211- } ) ) => {
212- if let Some ( ( ns, _) ) = namespace {
213- format ! ( "'{ns}::{member}'" )
214- } else {
215- format ! ( "'{member}'" )
216- }
217- }
218- Value :: Setting ( Setting :: Constructor {
167+ member : ( m, ml) ,
168+ } ) => Setting :: Unitary ( Namespaced {
169+ namespace : namespace. map ( |( n, nl) | ( n, nl. into ( ) ) ) ,
170+ member : ( m, ml. into ( ) ) ,
171+ } ) ,
172+ Setting :: Constructor {
219173 ctor :
220174 Namespaced {
221175 namespace : ctor_ns,
222- member : ( ctor_memb , _ ) ,
176+ member : ( ctor_m , ctor_ml ) ,
223177 } ,
224178 arg :
225179 Namespaced {
226180 namespace : arg_ns,
227- member : ( arg_memb , _ ) ,
181+ member : ( arg_m , arg_ml ) ,
228182 } ,
229- } ) => {
230- format ! (
231- "'{}({})'" ,
232- if let Some ( ( ns, _) ) = ctor_ns {
233- format!( "{ns}::{ctor_memb}" )
234- } else {
235- arg_memb. to_string( )
236- } ,
237- if let Some ( ( ns, _) ) = arg_ns {
238- format!( "{ns}::{arg_memb}" )
239- } else {
240- arg_memb. to_string( )
241- }
242- )
243- }
244- } ;
245- Err ( format ! ( "Expected 'String' value, found {}, at {ctxt}" , found) . into ( ) )
183+ } => Setting :: Constructor {
184+ ctor : Namespaced {
185+ namespace : ctor_ns. map ( |( ns, ns_l) | ( ns, ns_l. into ( ) ) ) ,
186+ member : ( ctor_m, ctor_ml. into ( ) ) ,
187+ } ,
188+ arg : Namespaced {
189+ namespace : arg_ns. map ( |( ns, ns_l) | ( ns, ns_l. into ( ) ) ) ,
190+ member : ( arg_m, arg_ml. into ( ) ) ,
191+ } ,
192+ } ,
193+ Setting :: Num ( num, num_loc) => Setting :: Num ( num, num_loc. into ( ) ) ,
194+ Setting :: String ( s, str_loc) => Setting :: String ( s, str_loc. into ( ) ) ,
195+ Setting :: Array ( mut xs, arr_open_loc, arr_close_loc) => Setting :: Array (
196+ xs. drain ( ..) . map ( |x| x. into ( ) ) . collect ( ) ,
197+ arr_open_loc. into ( ) ,
198+ arr_close_loc. into ( ) ,
199+ ) ,
200+ }
201+ }
202+ }
203+
204+ impl From < Value < Span > > for Value < Location > {
205+ fn from ( v : Value < Span > ) -> Value < Location > {
206+ match v {
207+ Value :: Flag ( flag, u) => Value :: Flag ( flag, u. into ( ) ) ,
208+ Value :: Setting ( s) => Value :: Setting ( s. into ( ) ) ,
209+ }
246210 }
247211}
248212
@@ -281,7 +245,85 @@ fn add_duplicate_occurrence<T: Eq + PartialEq + Clone>(
281245}
282246
283247impl < ' input > GrmtoolsSectionParser < ' input > {
284- pub fn parse_value (
248+ fn parse_setting ( & ' _ self , mut i : usize ) -> Result < ( Setting < Span > , usize ) , HeaderError < Span > > {
249+ i = self . parse_ws ( i) ;
250+ match RE_DIGITS . find ( & self . src [ i..] ) {
251+ Some ( m) => {
252+ let num_span = Span :: new ( i + m. start ( ) , i + m. end ( ) ) ;
253+ let num_str = & self . src [ num_span. start ( ) ..num_span. end ( ) ] ;
254+ // If the above regex matches we expect this to succeed.
255+ let num = str:: parse :: < u64 > ( num_str) . unwrap ( ) ;
256+ let val = Setting :: Num ( num, num_span) ;
257+ i = self . parse_ws ( num_span. end ( ) ) ;
258+ Ok ( ( val, i) )
259+ }
260+ None => match RE_STRING . find ( & self . src [ i..] ) {
261+ Some ( m) => {
262+ let end = i + m. end ( ) ;
263+ // Trim the leading and trailing quotes.
264+ let str_span = Span :: new ( i + m. start ( ) + 1 , end - 1 ) ;
265+ let str = & self . src [ str_span. start ( ) ..str_span. end ( ) ] ;
266+ let setting = Setting :: String ( str. to_string ( ) , str_span) ;
267+ // After the trailing quotes.
268+ i = self . parse_ws ( end) ;
269+ Ok ( ( setting, i) )
270+ }
271+ None => {
272+ if let Some ( mut j) = self . lookahead_is ( "[" , i) {
273+ let mut vals = Vec :: new ( ) ;
274+ let open_pos = j;
275+
276+ loop {
277+ j = self . parse_ws ( j) ;
278+ if let Some ( end_pos) = self . lookahead_is ( "]" , j) {
279+ return Ok ( (
280+ Setting :: Array (
281+ vals,
282+ Span :: new ( i, open_pos) ,
283+ Span :: new ( j, end_pos) ,
284+ ) ,
285+ end_pos,
286+ ) ) ;
287+ }
288+ if let Ok ( ( val, k) ) = self . parse_setting ( j) {
289+ vals. push ( val) ;
290+ j = self . parse_ws ( k) ;
291+ }
292+ if let Some ( k) = self . lookahead_is ( "," , j) {
293+ j = k
294+ }
295+ }
296+ } else {
297+ let ( path_val, j) = self . parse_namespaced ( i) ?;
298+ i = self . parse_ws ( j) ;
299+ if let Some ( j) = self . lookahead_is ( "(" , i) {
300+ let ( arg, j) = self . parse_namespaced ( j) ?;
301+ i = self . parse_ws ( j) ;
302+ if let Some ( j) = self . lookahead_is ( ")" , i) {
303+ i = self . parse_ws ( j) ;
304+ Ok ( (
305+ Setting :: Constructor {
306+ ctor : path_val,
307+ arg,
308+ } ,
309+ i,
310+ ) )
311+ } else {
312+ Err ( HeaderError {
313+ kind : HeaderErrorKind :: ExpectedToken ( ')' ) ,
314+ locations : vec ! [ Span :: new( i, i) ] ,
315+ } )
316+ }
317+ } else {
318+ Ok ( ( Setting :: Unitary ( path_val) , i) )
319+ }
320+ }
321+ }
322+ } ,
323+ }
324+ }
325+
326+ pub fn parse_key_value (
285327 & ' _ self ,
286328 mut i : usize ,
287329 ) -> Result < ( String , Span , Value < Span > , usize ) , HeaderError < Span > > {
@@ -298,62 +340,8 @@ impl<'input> GrmtoolsSectionParser<'input> {
298340 let key_span = Span :: new ( i, j) ;
299341 i = self . parse_ws ( j) ;
300342 if let Some ( j) = self . lookahead_is ( ":" , i) {
301- i = self . parse_ws ( j) ;
302- match RE_DIGITS . find ( & self . src [ i..] ) {
303- Some ( m) => {
304- let num_span = Span :: new ( i + m. start ( ) , i + m. end ( ) ) ;
305- let num_str = & self . src [ num_span. start ( ) ..num_span. end ( ) ] ;
306- // If the above regex matches we expect this to succeed.
307- let num = str:: parse :: < u64 > ( num_str) . unwrap ( ) ;
308- let val = Setting :: Num ( num, num_span) ;
309- i = self . parse_ws ( num_span. end ( ) ) ;
310- Ok ( ( key_name, key_span, Value :: Setting ( val) , i) )
311- }
312- None => match RE_STRING . find ( & self . src [ i..] ) {
313- Some ( m) => {
314- let end = i + m. end ( ) ;
315- // Trim the leading and trailing quotes.
316- let str_span = Span :: new ( i + m. start ( ) + 1 , end - 1 ) ;
317- let str = & self . src [ str_span. start ( ) ..str_span. end ( ) ] ;
318- let setting = Setting :: String ( str. to_string ( ) , str_span) ;
319- // After the trailing quotes.
320- i = self . parse_ws ( end) ;
321- Ok ( ( key_name, key_span, Value :: Setting ( setting) , i) )
322- }
323- None => {
324- let ( path_val, j) = self . parse_namespaced ( i) ?;
325- i = self . parse_ws ( j) ;
326- if let Some ( j) = self . lookahead_is ( "(" , i) {
327- let ( arg, j) = self . parse_namespaced ( j) ?;
328- i = self . parse_ws ( j) ;
329- if let Some ( j) = self . lookahead_is ( ")" , i) {
330- i = self . parse_ws ( j) ;
331- Ok ( (
332- key_name,
333- key_span,
334- Value :: Setting ( Setting :: Constructor {
335- ctor : path_val,
336- arg,
337- } ) ,
338- i,
339- ) )
340- } else {
341- Err ( HeaderError {
342- kind : HeaderErrorKind :: ExpectedToken ( ')' ) ,
343- locations : vec ! [ Span :: new( i, i) ] ,
344- } )
345- }
346- } else {
347- Ok ( (
348- key_name,
349- key_span,
350- Value :: Setting ( Setting :: Unitary ( path_val) ) ,
351- i,
352- ) )
353- }
354- }
355- } ,
356- }
343+ let ( val, j) = self . parse_setting ( j) ?;
344+ Ok ( ( key_name, key_span, Value :: Setting ( val) , j) )
357345 } else {
358346 Ok ( ( key_name, key_span, Value :: Flag ( true , key_span) , i) )
359347 }
@@ -414,7 +402,7 @@ impl<'input> GrmtoolsSectionParser<'input> {
414402 if let Some ( j) = self . lookahead_is ( "{" , i) {
415403 i = self . parse_ws ( j) ;
416404 while self . lookahead_is ( "}" , i) . is_none ( ) && i < self . src . len ( ) {
417- let ( key, key_loc, val, j) = match self . parse_value ( i) {
405+ let ( key, key_loc, val, j) = match self . parse_key_value ( i) {
418406 Ok ( ( key, key_loc, val, pos) ) => ( key, key_loc, val, pos) ,
419407 Err ( e) => {
420408 errs. push ( e) ;
@@ -439,7 +427,7 @@ impl<'input> GrmtoolsSectionParser<'input> {
439427 i = self . parse_ws ( j) ;
440428 continue ;
441429 } else {
442- i = j ;
430+ i = self . parse_ws ( j ) ;
443431 break ;
444432 }
445433 }
@@ -587,6 +575,13 @@ impl<T: Clone> TryFrom<&Value<T>> for YaccKind {
587575 ) ,
588576 locations : vec ! [ loc. clone( ) ] ,
589577 } ) ,
578+ Value :: Setting ( Setting :: Array ( _, loc, _) ) => Err ( HeaderError {
579+ kind : HeaderErrorKind :: ConversionError (
580+ "From<YaccKind>" ,
581+ "Cannot convert array to YaccKind" ,
582+ ) ,
583+ locations : vec ! [ loc. clone( ) ] ,
584+ } ) ,
590585 Value :: Setting ( Setting :: String ( _, loc) ) => Err ( HeaderError {
591586 kind : HeaderErrorKind :: ConversionError (
592587 "From<YaccKind>" ,
0 commit comments