Hacking on grammar! proc macro

- Generated functions take parser state as input
- Start of code generation
- WIP modeling of sequences
This commit is contained in:
2025-05-25 18:43:36 -07:00
parent 6933ae47b4
commit 2305e6453f
4 changed files with 30 additions and 6 deletions
+1
View File
@@ -7,5 +7,6 @@ edition = "2024"
proc-macro = true
[dependencies]
proc-macro2 = "1.0.95"
quote = "1.0.40"
syn = "2.0.101"
+23 -2
View File
@@ -17,8 +17,9 @@ struct Rule {
}
enum Term {
Rule(Ident),
Literal(LitStr),
Rule(Ident),
Sequence(Vec<Term>),
}
impl Parse for Grammar {
@@ -54,6 +55,22 @@ impl Parse for Term {
}
}
impl Term {
fn generate_code(&self) -> proc_macro2::TokenStream {
match self {
Term::Rule(ident) => quote! {
println!("call subrule");
// call subrule
},
Term::Literal(lit_str) => quote! {
println!("parse literal");
// call p.literal()
},
Term::Sequence(terms) => todo!(),
}
}
}
#[proc_macro]
pub fn grammar_old(ts: TokenStream) -> TokenStream {
let token = ts.into_iter().next().expect("must have at least one token");
@@ -95,12 +112,16 @@ pub fn grammar(ts: TokenStream) -> TokenStream {
.map(|t| match t {
Term::Rule(ident) => format!("rule {}", ident.to_string()),
Term::Literal(lit_str) => format!("literal \"{}\"", lit_str.value()),
Term::Sequence(terms) => todo!(),
})
.collect();
let text = format!("I'm generated! ({})", term_strs.join(", "));
let generated: Vec<_> = r.terms.iter().map(|t| t.generate_code()).collect();
quote! {
fn #fn_name() -> String {
fn #fn_name(p: &mut crate::peg::ParseState) -> String {
#(#generated)*
#text.into()
}
}