Skip to content

Instantly share code, notes, and snippets.

@1011X
Created February 16, 2017 02:12
Show Gist options
  • Save 1011X/db99acc25e2cc53535d5ddeb8d8acbb6 to your computer and use it in GitHub Desktop.
Save 1011X/db99acc25e2cc53535d5ddeb8d8acbb6 to your computer and use it in GitHub Desktop.
Basic Backus-Naur form grammar macro
macro_rules! bnf {
(<$id:ident> ::= <$p1:ident> | <$p2:ident>; $($t:tt)*) => {
fn $id(i: &'static str) -> (&str, &str) {
let p1 = ::std::thread::spawn(move || $p1(i));
if p1.join().is_ok() {
$p1(i)
} else {
$p2(i)
}
}
bnf!($($t)*);
};
(<$id:ident> ::= <$p1:ident> <$p2:ident>; $($t:tt)*) => {
fn $id(i: &str) -> (&str, &str) {
let (res1, j) = $p1(i);
let (res2, _) = $p2(j);
i.split_at(res1.len() + res2.len())
}
bnf!($($t)*);
};
(<$id:ident> ::= $e:expr; $($t:tt)*) => {
fn $id(i: &str) -> (&str, &str) {
let e = $e;
assert!(i.starts_with(e));
i.split_at(e.len())
}
bnf!($($t)*);
};
() => ()
}
bnf! {
<hello> ::= "hello";
<hi> ::= "hi";
<hihello> ::= <hi> <hello>;
<hi_hello> ::= <hi> | <hello>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment