use crate::token::{Tokens, Token};
use std::ops;
pub struct Parser<T> {
pub run: Box<dyn Fn(&mut Tokens, &mut Vec<String>) -> Result<(Option<T>, Vec<Token>), String>>,
}
impl<T: 'static> Parser<T> {
pub fn new(f: Box<dyn Fn(&mut Tokens, &mut Vec<String>) -> Result<(Option<T>, Vec<Token>), String>>) -> Self {
Parser{run: f}
}
pub fn err(self, msg: &'static str) -> Self {
Parser::new(Box::new(move |tokens, del| {
if let (Some(proc), left_tokens) = (self.run)(tokens, del)? {
Ok((Some(proc), left_tokens))
} else {
Err(msg.to_string())
}
}))
}
}
pub type Creator<T> = Box<dyn Fn() -> Parser<T>>;
impl<F: 'static, B: 'static, C: 'static> ops::Add<Creator<B>> for Parser<F> where F: FnOnce(B) -> C {
type Output = Parser<C>;
fn add(self, rhs: Creator<B>) -> Self::Output {
Parser::new(Box::new(move |tokens, del| {
match (self.run)(tokens, del)? {
(None, left_tokens) => Ok((None, left_tokens)),
(Some(f), left_tokens) => {
match (rhs().run)(tokens, del)? {
(None, right_tokens) => Ok((None, contact(left_tokens, right_tokens))),
(Some(x), right_tokens) => {
let result = f(x);
Ok((Some(result), contact(left_tokens, right_tokens)))
}
}
}
}
}))
}
}
impl<T: 'static> ops::BitOr<Creator<T>> for Parser<T> {
type Output = Self;
fn bitor(self, rhs: Creator<T>) -> Self::Output {
Parser::new(Box::new(move |tokens, del| {
match (self.run)(tokens, del)? {
(None, left_tokens) => {
tokens.back_tokens(left_tokens);
(rhs().run)(tokens, del)
},
x => Ok(x)
}
}))
}
}
impl<A: 'static, B: 'static> ops::Shr<Creator<B>> for Parser<A> {
type Output = Parser<B>;
fn shr(self, rhs: Creator<B>) -> Self::Output {
Parser::new(Box::new(move |tokens, del| {
match (self.run)(tokens, del)? {
(None, left_tokens) => Ok((None, left_tokens)),
(Some(_), left_tokens) => {
let result = (rhs().run)(tokens, del)?;
Ok((result.0, contact(left_tokens, result.1)))
}
}
}))
}
}
impl<A: 'static, B: 'static> ops::Shl<Creator<B>> for Parser<A> {
type Output = Self;
fn shl(self, rhs: Creator<B>) -> Self::Output {
Parser::new(Box::new(move |tokens, del| {
match (self.run)(tokens, del)? {
(None, left_tokens) => Ok((None, left_tokens)),
(x, left_tokens) => {
match (rhs().run)(tokens, del)? {
(None, right_tokens) => Ok((None, contact(left_tokens, right_tokens))),
(_, right_tokens) => Ok((x, contact(left_tokens, right_tokens)))
}
}
}
}))
}
}
pub fn is<T: 'static, F: 'static, P: 'static>(check: F, p: P) -> Parser<T>
where F: Fn(&Token) -> bool, P: Fn(&Token, &mut Vec<String>) -> T {
Parser::new(Box::new(move |tokens, del| {
if let Some(token) = tokens.next() {
if check(&token) {
let proc = p(&token, del);
Ok((Some(proc), vec![token]))
} else {
tokens.back_token(Some(token));
Ok((None, Vec::new()))
}
} else {
Ok((None, Vec::new()))
}
}))
}
pub fn map<F: 'static, A: 'static, B: 'static>(f: F, parser: Parser<A>) -> Parser<B> where F: Fn(A) -> B + Copy {
Parser::new(Box::new(move |tokens, del| {
match (parser.run)(tokens, del)? {
(None, left_tokens) => Ok((None, left_tokens)),
(Some(x), left_tokens) => {
let result = f(x);
Ok((Some(result), left_tokens))
}
}
}))
}
pub fn zero_or_more<A: 'static>(parser: Creator<A>) -> Parser<Vec<A>> {
Parser::new(Box::new(move |tokens, del| {
let mut v = Vec::new();
let mut back_tokens = Vec::new();
while let (Some(p), mut left_tokens) = (parser().run)(tokens, del)? {
v.push(p);
back_tokens.append(&mut left_tokens);
}
Ok((Some(v), back_tokens))
}))
}
pub fn one_or_more<A: 'static>(parser: Creator<A>) -> Parser<Vec<A>> {
Parser::new(Box::new(move |tokens, del| {
let mut v = Vec::new();
let mut back_tokens = Vec::new();
match (parser().run)(tokens, del)? {
(None, _) => return Err("必须有一个满足要求".to_string()),
(Some(p), mut left_tokens) => {
v.push(p);
back_tokens.append(&mut left_tokens);
while let (Some(p), mut left_tokens) = (parser().run)(tokens, del)? {
v.push(p);
back_tokens.append(&mut left_tokens);
}
}
}
Ok((Some(v), back_tokens))
}))
}
pub fn zero_or_one<A: 'static>(parser: Creator<A>) -> Parser<Option<A>> {
Parser::new(Box::new(move |tokens, del| {
let result = (parser().run)(tokens, del)?;
Ok((Some(result.0), result.1))
}))
}
pub fn set_var(parser: Parser<syn::Ident>) -> Parser<syn::Ident> {
Parser::new(Box::new(move |tokens, del| {
match (parser.run)(tokens, del)? {
(Some(proc), left_tokens) => {
del.push(proc.to_string());
Ok((Some(proc), left_tokens))
},
(x, left_tokens) => Ok((x, left_tokens))
}
}))
}
pub fn has_var(parser: Parser<syn::Ident>) -> Parser<(syn::Ident, bool)> {
Parser::new(Box::new(move |tokens, del| {
match (parser.run)(tokens, del)? {
(Some(proc), left_tokens) => {
let has = del.contains(&proc.to_string());
Ok((Some((proc, has)), left_tokens))
},
(None, left_tokens) => Ok((None, left_tokens))
}
}))
}
fn contact<T>(mut left: Vec<T>, mut right: Vec<T>) -> Vec<T> {
left.append(&mut right);
left
}