Refactor Term to allow sequences
This commit is contained in:
+35
-24
@@ -13,7 +13,7 @@ struct Grammar {
|
|||||||
|
|
||||||
struct Rule {
|
struct Rule {
|
||||||
name: Ident,
|
name: Ident,
|
||||||
terms: Vec<Term>,
|
definition: Term,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Term {
|
enum Term {
|
||||||
@@ -34,23 +34,32 @@ impl Parse for Rule {
|
|||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
let name = input.parse()?;
|
let name = input.parse()?;
|
||||||
input.parse::<Token![=]>()?;
|
input.parse::<Token![=]>()?;
|
||||||
let mut terms = vec![];
|
let definition = input.parse()?;
|
||||||
while !input.peek(Token![;]) {
|
Ok(Self { name, definition })
|
||||||
terms.push(input.parse()?);
|
|
||||||
}
|
|
||||||
Ok(Self { name, terms })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Term {
|
impl Parse for Term {
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
let look = input.lookahead1();
|
let mut terms = vec![];
|
||||||
if look.peek(Ident) {
|
let parse_one = || {
|
||||||
input.parse().map(Term::Rule)
|
let look = input.lookahead1();
|
||||||
} else if look.peek(LitStr) {
|
if look.peek(Ident) {
|
||||||
input.parse().map(Term::Literal)
|
input.parse().map(Term::Rule)
|
||||||
|
} else if look.peek(LitStr) {
|
||||||
|
input.parse().map(Term::Literal)
|
||||||
|
} else {
|
||||||
|
Err(look.error())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
terms.push(parse_one()?);
|
||||||
|
while !input.is_empty() && !input.peek(Token![;]) {
|
||||||
|
terms.push(parse_one()?);
|
||||||
|
}
|
||||||
|
if terms.len() == 1 {
|
||||||
|
Ok(terms.pop().unwrap())
|
||||||
} else {
|
} else {
|
||||||
Err(look.error())
|
Ok(Term::Sequence(terms))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +75,9 @@ impl Term {
|
|||||||
println!("parse literal");
|
println!("parse literal");
|
||||||
// call p.literal()
|
// call p.literal()
|
||||||
},
|
},
|
||||||
Term::Sequence(terms) => todo!(),
|
Term::Sequence(terms) => quote! {
|
||||||
|
println!("sequence");
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,22 +117,22 @@ pub fn grammar(ts: TokenStream) -> TokenStream {
|
|||||||
let fn_name = &r.name;
|
let fn_name = &r.name;
|
||||||
|
|
||||||
// Generate a string for debugging
|
// Generate a string for debugging
|
||||||
let term_strs: Vec<String> = r
|
fn term2str(t: &Term) -> String {
|
||||||
.terms
|
match t {
|
||||||
.iter()
|
|
||||||
.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!(),
|
Term::Sequence(terms) => {
|
||||||
})
|
let parts: Vec<_> = terms.iter().map(term2str).collect();
|
||||||
.collect();
|
format!("sequence [{}]", parts.join(", "))
|
||||||
let text = format!("I'm generated! ({})", term_strs.join(", "));
|
}
|
||||||
|
}
|
||||||
let generated: Vec<_> = r.terms.iter().map(|t| t.generate_code()).collect();
|
}
|
||||||
|
let text = format!("I'm generated! ({})", term2str(&r.definition));
|
||||||
|
|
||||||
|
let generated = r.definition.generate_code();
|
||||||
quote! {
|
quote! {
|
||||||
fn #fn_name(p: &mut crate::peg::ParseState) -> String {
|
fn #fn_name(p: &mut crate::peg::ParseState) -> String {
|
||||||
#(#generated)*
|
#generated
|
||||||
#text.into()
|
#text.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -87,6 +87,6 @@ mod tests {
|
|||||||
fn test_generated() {
|
fn test_generated() {
|
||||||
let mut p = ParseState::new("");
|
let mut p = ParseState::new("");
|
||||||
assert_snapshot!(generated_this(&mut p), @"I'm generated! (rule foo)");
|
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)"#);
|
assert_snapshot!(generated_that(&mut p), @r#"I'm generated! (sequence [literal "bar", rule baz])"#);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user