af_path 0.2.3

path查询语言库
Documentation
use crate::token::{Tokens, Token};
use std::ops;

/// 解析器主体是解析函数。解析函数对单词流进行解析,返回解析结果。解析结果包含:
/// * 解析器已经使用的单词,以便解析不成功时,对这些单词进行回退。
/// * 不满足解析器解析规则时,返回None。
/// * 满足解析规则,但出错时,返回Err。
/// 参数说明:
/// - Tokens:解析时的单词流
/// - Vec<String>:上下文环境,保存已经找到的变量名。
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}
    }

    /// 如果parser解析结果为None,转换成错误
    /// # Eamples
    /// ```rust
    /// let parser = parser_a.err("必须有值")
    /// ```
    pub fn err(self, msg: &'static str) -> Self {
        Parser::new(Box::new(move |tokens, del| {
            // 如果本身已经出错,返回错误
            // 如果是None,返回指定错误
            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>>;

/// 实现解析器连接操作
/// # Examples
/// ```rust
/// let parser = parser_a + parser_b
/// ```
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| {
            // p1先运行,没有值,出错,有值,让p2运行
            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)))
                        }
                    }
                }
            }
        }))
    }
}

/// 实现解析器选择操作
/// # Examples
/// ```rust
/// let parser = parser_a | parser_b
/// ```
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)
            }
        }))
    }
}

/// 实现前面解析器丢弃操作
/// # Examples
/// ```rust
/// let parser = parser_a >> parser_b
/// ```
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)))
                }
            }
        }))
    }
}

/// 实现后面解析器丢弃操作
/// # Examples
/// ```rust
/// let parser = parser_a << parser_b
/// ```
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)))
                    }
                }
            }
        }))
    }
}

/// 看下一个单词是否满足给定条件,如果满足,由给定处理过程进行处理。否则,单词回退,返回空。
/// # Examples
/// ```rust
/// let parser = is(|token| token.is_lit(), |token| token.to_lit())
/// ```
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() {
            // 满足条件,调用p产生处理器
            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()))
        }
    }))
}

/// 把解析器处理结果,进行转换的解析器
/// # Examples
/// ```rust
/// let exp = |ident| { Expression::Ident(ident) };
/// let parser = map(exp, ident())
/// ```
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))
            }
        }
    }))
}

/// 解决 A:=B*文法,代表0个或多个。
/// # Examples
/// ```rust
/// let exp = zero_or_more(parser_a)
/// ```
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))
    }))
}

/// 解决 A:=B+文法,代表一个或多个。
/// # Examples
/// ```rust
/// let parser = one_or_more(parser_a)
/// ```
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))
    }))
}

/// 解决 A:=B?,代表B可以没有的情况
/// # Examples
/// ```rust
/// let a = zero_or_one(parser_a);
/// ```
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))
    }))
}

/// 把解析器找到的函数名设置到环境中,用于变量定义处理
/// # Examples
/// ```rust
/// let parser = set_var(parser_a)
/// ```
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))
        }
    }))
}

/// 获得解析器所得变量是否在环境中存在
/// # Examples
/// ```rust
/// let parser = has_var(parser_a)
/// ```
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
}