13个版本

0.0.13 2024年8月6日
0.0.12 2024年5月15日
0.0.11 2024年4月23日
0.0.9 2024年3月15日
0.0.4 2024年2月24日

#269Rust模式

Download history 55/week @ 2024-05-06 5295/week @ 2024-05-13 2808/week @ 2024-05-20 1146/week @ 2024-05-27 741/week @ 2024-06-03 462/week @ 2024-06-10 333/week @ 2024-06-17 367/week @ 2024-06-24 291/week @ 2024-07-01 197/week @ 2024-07-08 186/week @ 2024-07-15 130/week @ 2024-07-22 244/week @ 2024-07-29 390/week @ 2024-08-05 321/week @ 2024-08-12 240/week @ 2024-08-19

4,937 每月下载量
用于 5 个crate(直接使用3个)

MIT 许可协议

12KB
216

最简单的解析器库 (TSPL)

TSPL 是一个在 Rust 中工作的最简单的解析器库。

概念

在纯函数式语言如 Haskell 中,解析器可以表示为一个函数

Parser<A> ::= String -> Reply<A, Error>

这使我们能够为 Parser<A> 实现一个 Monad 实例,让我们可以使用 do-notation 创建简单而优雅的自定义类型解析器。遗憾的是,Rust 没有等效的功能。然而,我们可以通过以下方式轻松模拟它:

  1. 使用结构和 impl 内部管理光标状态。

  2. 返回一个 Result,这使我们能够使用 Rust 的 ? 来模拟单调块。

这个库仅公开了一些函数来实现以这种方式实现的解析器,除此之外没有其他功能。

示例

作为一个示例,让我们使用 TSPL 创建一个 λ-Term 解析器。

  1. 实现你想要创建解析器的类型。
enum Term {
  Lam { name: String, body: Box<Term> },
  App { func: Box<Term>, argm: Box<Term> },
  Var { name: String },
}
  1. 定义你的语法。我们将使用以下
<term> ::= <lam> | <app> | <var>
<lam>  ::= "λ" <name> " " <term>
<app>  ::= "(" <term> " " <term> ")"
<var>  ::= alphanumeric_string
  1. 使用 new_parser()! 宏创建一个新的解析器。
TSPL::new_parser!(TermParser);
  1. 使用你的语法创建一个 impl TermParser
impl<'i> TermParser<'i> {
  fn parse(&mut self) -> Result<Term, String> {
    self.skip_trivia();
    match self.peek_one() {
      Some('λ') => {
        self.consume("λ")?;
        let name = self.parse_name()?;
        let body = Box::new(self.parse()?);
        Ok(Term::Lam { name, body })
      }
      Some('(') => {
        self.consume("(")?;
        let func = Box::new(self.parse()?);
        let argm = Box::new(self.parse()?);
        self.consume(")")?;
        Ok(Term::App { func, argm })
      }
      _ => {
        let name = self.parse_name()?;
        Ok(Term::Var { name })
      }
    }
  }
}
  1. 使用你的解析器!
fn main() {
  let mut parser = TermParser::new("λx(λy(x y) λz z)");
  match parser.parse() {
    Ok(term) => println!("{:?}", term),
    Err(err) => eprintln!("{}", err),
  }
}

完整的示例可在 ./examples/lambda_term.rs 中找到。使用以下命令运行它:

cargo run --example lambda_term

致谢

此设计基于 T6 为 HVM-Core 的新解析器,比旧的 HOPA 方法更干净。

依赖项

~16KB