Skip to content

Instantly share code, notes, and snippets.

@brosenan
Created December 10, 2018 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brosenan/8a90ffbae1acbea2ad425ae40bb9ab7a to your computer and use it in GitHub Desktop.
Save brosenan/8a90ffbae1acbea2ad425ae40bb9ab7a to your computer and use it in GitHub Desktop.
use std::ops::{Mul, Add};
struct Parser {
parser: Box<Fn(&[u8], usize) -> Vec<usize>>,
}
fn empty() -> Parser {
Parser{parser: Box::new(|_s: &[u8], idx| vec![idx])}
}
fn byte(c: u8) -> Parser {
Parser{parser: Box::new(move |s : &[u8], idx| {
if idx < s.len() && s[idx] == c {
return vec![idx + 1];
} else {
return vec![];
}
})}
}
fn token(s: String) -> Parser {
let bytes = s.as_bytes();
let mut res = empty();
for b in bytes {
res = res * byte(*b);
}
res
}
impl Mul for Parser {
type Output = Parser;
fn mul(self, other: Self) -> Parser {
Parser{parser: Box::new(move |s: &[u8], idx| {
let mid = (self.parser)(s, idx);
let mut res = vec![];
for m in mid {
res.append(&mut (other.parser)(s, m));
}
res
})}
}
}
impl Add for Parser {
type Output = Parser;
fn add(self, other: Self) -> Parser {
Parser{parser: Box::new(move |s: &[u8], idx| {
let mut res = (self.parser)(s, idx);
res.append(&mut (other.parser)(s, idx));
res
})}
}
}
fn main() {
let s = String::from("aabbc");
let p = empty() + token(String::from("a")) * p * token(String::from("b"));
for v in (p.parser)(s.as_bytes(), 0) {
println!("{}", v);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment