4个版本

新版本 0.0.4 2024年8月5日
0.0.3 2024年6月9日
0.0.2 2024年6月3日
0.0.1 2024年5月28日

626Rust模式

Download history 172/week @ 2024-05-27 293/week @ 2024-06-03 36/week @ 2024-06-10

每月325次下载

MIT 许可证

230KB
6K SLoC

teleparse

正在进行中 - 由Proc-macro驱动的LL(1)解析库

此库与serde在解析方面可比 - 所需的所有操作只是定义语法为数据类型,并在根类型上调用parse()

功能

  • 在结构和枚举上使用宏属性定义的语法树 - 无需单独的语法文件
  • 由Proc-macro驱动 - 无需单独的构建步骤来生成解析器代码
  • 提供一个 #[test] 来确保语法是LL(1),或者在运行时失败
  • 用于将组件解析为元组、选项和分隔列表等原语的工具

致谢

  • 词法分析器实现依赖于 极快logos
  • Alfred V. Aho, Monica S. Lam, Ravi Sethi 和 Jeffrey D. Ullman 的《编译原理、技术和工具》的“Dragon Book”

进度

  • 词法分析器/标记
    • 终端宏
  • 解析器
    • LL(1)相关
    • 语义标记(解析器稍后应用到的标记类型)
      • 测试
      • 文档
    • 测试
    • 文档
    • 钩子
  • 实用类型 tp
  • 静态元数据
    • 基准测试
    • 测试
    • 文档
  • mdBook
    • 章节
      • derive_lexicon
      • derive_syntax
      • 使用 tp
      • 语义标记
      • 钩子(1.1)
      • 使用解析器数据
    • 第二次迭代以添加链接
  • 可用性测试
  • crates文档链接到书籍

传统上递归的语法也可以使用内置的语法类型简化。

// with recursion
E  => T E'
E' => + T E' | ε
T  => F T'
T' => * F T' | ε
F  => ( E ) | id

// simplified
E  => T ( + T )*
T  => F ( * F )*
F  => ( E ) | id

然后可以按如下方式实现

use teleparse::prelude::*;

#[derive_lexicon]
#[teleparse(ignore(r"\s+"))]
pub enum TokenType {
    #[teleparse(regex(r"\w+"), terminal(Ident))]
    Ident,
    #[teleparse(terminal(
        OpAdd = "+",
        OpMul = "*",
    ))]
    Op,
    /// Parentheses
    #[teleparse(terminal(
        ParenOpen = "(",
        ParenClose = ")"
    ))]
    Paren,
}

#[derive_syntax]
#[teleparse(root)]
struct E(tp::Split<T, OpAdd>); // E -> T ( + T )*
#[derive_syntax]
struct T(tp::Split<F, OpMul>); // T -> F ( * F )*
#[derive_syntax]
enum F {
    Ident(Ident),
    Paren((ParenOpen, Box<E>, ParenClose)),
}

fn main() -> Result<(), teleparse::GrammarError> {
    let source = "(a+b)*(c+d)";
    let _expr = E::parse(source)?;
    
    Ok(())
}

依赖项

~7.5MB
~113K SLoC