@@ -1185,14 +1185,17 @@ impl CTLexer {
11851185
11861186/// Create a Rust module named `mod_name` that can be imported with
11871187/// [`lrlex_mod!(mod_name)`](crate::lrlex_mod). The module contains one `const` `StorageT` per
1188- /// token in `token_map`, with the token prefixed by `T_`. For example with `StorageT` `u8`,
1189- /// `mod_name` `x`, and `token_map` `HashMap{"ID": 0, "INT": 1}` the generated module will look
1190- /// roughly as follows:
1188+ /// token in `token_map`, with the token prefixed by `T_`. In addition, it will
1189+ /// contain an array of all token IDs `TOK_IDS`.
1190+ ///
1191+ /// For example with `StorageT` `u8`, `mod_name` `x`, and `token_map`
1192+ /// `HashMap{"ID": 0, "INT": 1}` the generated module will look roughly as follows:
11911193///
11921194/// ```rust,ignore
11931195/// mod x {
11941196/// pub const T_ID: u8 = 0;
11951197/// pub const T_INT: u8 = 1;
1198+ /// pub const TOK_IDS: &[u8] = &[T_ID, T_INT];
11961199/// }
11971200/// ```
11981201///
@@ -1205,6 +1208,7 @@ impl CTLexer {
12051208/// mod x {
12061209/// pub const T_PLUS: u8 = 0;
12071210/// pub const T_ID: u8 = 1;
1211+ /// pub const TOK_IDS: &[u8] = &[T_PLUS, T_ID];
12081212/// }
12091213/// ```
12101214pub fn ct_token_map < StorageT : Display + ToTokens > (
@@ -1219,31 +1223,36 @@ pub fn ct_token_map<StorageT: Display + ToTokens>(
12191223 let timestamp = env ! ( "VERGEN_BUILD_TIMESTAMP" ) ;
12201224 let mod_ident = format_ident ! ( "{}" , mod_name) ;
12211225 write ! ( outs, "// lrlex build time: {}\n \n " , quote!( #timestamp) , ) . ok ( ) ;
1226+ let storaget = str:: parse :: < TokenStream > ( type_name :: < StorageT > ( ) ) . unwrap ( ) ;
12221227 // Sort the tokens so that they're always in the same order.
12231228 // This will prevent unneeded rebuilds.
12241229 let mut token_map_sorted = Vec :: from_iter ( token_map. borrow ( ) . iter ( ) ) ;
12251230 token_map_sorted. sort_by_key ( |( k, _) | * k) ;
1226- let tokens = & token_map_sorted
1227- . into_iter ( )
1231+ let ( token_array , tokens) : ( TokenStream , TokenStream ) = token_map_sorted
1232+ . iter ( )
12281233 . map ( |( k, id) | {
12291234 let name = match rename_map {
12301235 Some ( rmap) => * rmap. get ( k. as_str ( ) ) . unwrap_or ( & k. as_str ( ) ) ,
1231- _ => k,
1236+ _ => & k,
12321237 } ;
12331238 let tok_ident = format_ident ! ( "T_{}" , name. to_ascii_uppercase( ) ) ;
1234- let storaget = str:: parse :: < TokenStream > ( type_name :: < StorageT > ( ) ) . unwrap ( ) ;
1235- // Code gen for the constant token values.
1236- quote ! {
1237- pub const #tok_ident: #storaget = #id;
1238- }
1239+ (
1240+ quote ! {
1241+ #tok_ident,
1242+ } ,
1243+ quote ! {
1244+ pub const #tok_ident: #storaget = #id;
1245+ } ,
1246+ )
12391247 } )
1240- . collect :: < Vec < _ > > ( ) ;
1248+ . unzip ( ) ;
12411249 // Since the formatter doesn't preserve comments and we don't want to lose build time,
12421250 // just format the module contents.
12431251 let unformatted = quote ! {
12441252 mod #mod_ident {
12451253 #![ allow( dead_code) ]
1246- #( #tokens) *
1254+ #tokens
1255+ pub const TOK_IDS : & [ #storaget] = & [ #token_array] ;
12471256 }
12481257 }
12491258 . to_string ( ) ;
0 commit comments