I am designing a custom HTML syntax parser using proc_macro
and syn
. A sample:
#[derive(Debug)]
struct BlockElement {
stag: Ident,
child: Vec<Element>,
ctag: Ident
}
impl Synom for BlockElement {
named!(parse -> Self, do_parse!(
punct!(<) >>
stag: syn!(Ident) >>
punct!(>) >>
child: syn!(ElementList) >>
punct!(<) >>
punct!(/) >>
ctag: syn!(Ident) >>
punct!(>) >>
(BlockElement { stag, child: child.inner, ctag })
));
}
Though I know how give out errors using Span
after it has been parsed, I am not able to figure how to do it during a parse. It just errors out with failed to parse anything
. How to pin-point where parsing failed and give appropriate error?
By upgrading your macro to use Syn 0.15 or greater, you get helpful parse error messages with no additional effort.
extern crate proc_macro;
use self::proc_macro::TokenStream;
use syn::parse::{Parse, ParseStream, Result};
use syn::{parse_macro_input, Ident, Token};
// FIXME
type Element = Ident;
struct ElementList {
inner: Vec<Element>,
}
impl Parse for ElementList {
fn parse(input: ParseStream) -> Result<Self> {
let mut list = Vec::new();
while let Some(element) = input.parse()? {
list.push(element);
}
Ok(ElementList { inner: list })
}
}
struct BlockElement {
stag: Ident,
child: Vec<Element>,
ctag: Ident
}
impl Parse for BlockElement {
fn parse(input: ParseStream) -> Result<Self> {
input.parse::<Token![<]>()?;
let stag: Ident = input.parse()?;
input.parse::<Token![>]>()?;
let child: ElementList = input.parse()?;
input.parse::<Token![<]>()?;
input.parse::<Token![/]>()?;
let ctag: Ident = input.parse()?;
input.parse::<Token![>]>()?;
Ok(BlockElement { stag, child: child.inner, ctag })
}
}
#[proc_macro]
pub fn html_syntax(input: TokenStream) -> TokenStream {
let _input = parse_macro_input!(input as BlockElement);
// TODO
TokenStream::new()
}
Here is an example of an input parse error. Such errors will indicate where the input failed to parse and what token(s) the macro would have expected in that position.
fn main() {
html_syntax!(<em>syn quote proc_macro2<em>);
}
error: expected `/`
--> src/main.rs
|
| html_syntax!(<em>syn quote proc_macro2<em>);
| ^^
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With