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:
Generated
+3
-2
@@ -131,6 +131,7 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|||||||
name = "peg_macro"
|
name = "peg_macro"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
@@ -168,9 +169,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.94"
|
version = "1.0.95"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ edition = "2024"
|
|||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
proc-macro2 = "1.0.95"
|
||||||
quote = "1.0.40"
|
quote = "1.0.40"
|
||||||
syn = "2.0.101"
|
syn = "2.0.101"
|
||||||
|
|||||||
+23
-2
@@ -17,8 +17,9 @@ struct Rule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum Term {
|
enum Term {
|
||||||
Rule(Ident),
|
|
||||||
Literal(LitStr),
|
Literal(LitStr),
|
||||||
|
Rule(Ident),
|
||||||
|
Sequence(Vec<Term>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Grammar {
|
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]
|
#[proc_macro]
|
||||||
pub fn grammar_old(ts: TokenStream) -> TokenStream {
|
pub fn grammar_old(ts: TokenStream) -> TokenStream {
|
||||||
let token = ts.into_iter().next().expect("must have at least one token");
|
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 {
|
.map(|t| match t {
|
||||||
Term::Rule(ident) => format!("rule {}", ident.to_string()),
|
Term::Rule(ident) => format!("rule {}", ident.to_string()),
|
||||||
Term::Literal(lit_str) => format!("literal \"{}\"", lit_str.value()),
|
Term::Literal(lit_str) => format!("literal \"{}\"", lit_str.value()),
|
||||||
|
Term::Sequence(terms) => todo!(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let text = format!("I'm generated! ({})", term_strs.join(", "));
|
let text = format!("I'm generated! ({})", term_strs.join(", "));
|
||||||
|
|
||||||
|
let generated: Vec<_> = r.terms.iter().map(|t| t.generate_code()).collect();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
fn #fn_name() -> String {
|
fn #fn_name(p: &mut crate::peg::ParseState) -> String {
|
||||||
|
#(#generated)*
|
||||||
#text.into()
|
#text.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -85,7 +85,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_generated() {
|
fn test_generated() {
|
||||||
assert_snapshot!(generated_this(), @"I'm generated! (rule foo)");
|
let mut p = ParseState::new("");
|
||||||
assert_snapshot!(generated_that(), @r#"I'm generated! (literal "bar", rule baz)"#);
|
assert_snapshot!(generated_this(&mut p), @"I'm generated! (rule foo)");
|
||||||
|
assert_snapshot!(generated_that(&mut p), @r#"I'm generated! (literal "bar", rule baz)"#);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user