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日 |
626 在 Rust模式
每月325次下载
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