Skip to content

Commit 2324bdd

Browse files
committed
Improve error when CTParserBuilder::mod_name is not a valid rust ident.
This uses the suggested method in dtolnay/quote#172 to check the ident for validity, and produce a helpful error.
1 parent 3314528 commit 2324bdd

1 file changed

Lines changed: 34 additions & 1 deletion

File tree

lrpar/src/lib/ctbuilder.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,12 @@ where
973973
None
974974
};
975975

976-
let mod_name = format_ident!("{}", mod_name);
976+
let mod_name = match syn::parse_str::<proc_macro2::Ident>(mod_name) {
977+
Ok(s) => s,
978+
Err(e) => {
979+
return Err(format!("CTParserBuilder::mod_name(\"{}\") is not a valid rust identifier due to '{}'", mod_name, e).into())
980+
}
981+
};
977982
let out_tokens = quote! {
978983
#visibility mod #mod_name {
979984
// At the top so that `user_actions` may contain #![inner_attribute]
@@ -1801,6 +1806,34 @@ C : 'a';"
18011806
}
18021807
}
18031808

1809+
#[test]
1810+
/// Tests a yacc .y filename containing a dash character leading to an invalid rust identifier
1811+
/// when that dash is subsequently used as the default `CTParserBuilder::mod_name`.
1812+
fn test_invalid_identifier_in_derived_mod_name() {
1813+
let temp = TempDir::new().unwrap();
1814+
let mut file_path = PathBuf::from(temp.as_ref());
1815+
file_path.push("contains-a-dash.y");
1816+
let mut f = File::create(&file_path).unwrap();
1817+
let _ = f.write_all(
1818+
"%start A
1819+
%%
1820+
A : 'a';"
1821+
.as_bytes(),
1822+
);
1823+
match CTParserBuilder::<TestLexerTypes>::new()
1824+
.yacckind(YaccKind::Original(YaccOriginalActionKind::GenericParseTree))
1825+
.grammar_path(file_path.to_str().unwrap())
1826+
.output_path(file_path.with_extension("ignored"))
1827+
.build()
1828+
{
1829+
Ok(_) => panic!("Expected error"),
1830+
Err(e) => {
1831+
let err_string = e.to_string();
1832+
assert_eq!(err_string, "CTParserBuilder::mod_name(\"contains-a-dash_y\") is not a valid rust identifier due to 'unexpected token'");
1833+
}
1834+
}
1835+
}
1836+
18041837
#[cfg(test)]
18051838
#[test]
18061839
fn test_recoverer_header() -> Result<(), Box<dyn std::error::Error>> {

0 commit comments

Comments
 (0)