#lexer #ast #parser

laps

通过派生特质构建词法和解析器

10个版本

0.1.7 2023年12月30日
0.1.6 2023年12月24日
0.1.2 2023年7月13日
0.1.0 2023年6月17日
0.0.1 2022年10月25日

#33解析工具

Download history 38/week @ 2024-03-31

82 每月下载量

MIT/Apache

94KB
2K SLoC

laps

github crates.io docs.rs build status

词法和解析器集合。

使用laps,您只需定义标记/AST并为其派生Tokenize/Parse特质即可构建词法/解析器。

用法

通过运行cargo addlaps添加到您的项目中

cargo add laps --features macros

示例

实现一个S-expression的词法器

use laps::prelude::*;

#[token_kind]
#[derive(Debug, Tokenize)]
enum TokenKind {
  // This token will be skipped.
  #[skip(r"\s+")]
  _Skip,
  /// Parentheses.
  #[regex(r"[()]")]
  Paren(char),
  /// Atom.
  #[regex(r"[^\s()]+")]
  Atom(String),
  /// End-of-file.
  #[eof]
  Eof,
}

以及解析器和ASTs(或实际上是CSTs

type Token = laps::token::Token<TokenKind>;

token_ast! {
  macro Token<TokenKind> {
    [atom] => { kind: TokenKind::Atom(_), prompt: "atom" },
    [lpr] => { kind: TokenKind::Paren('(') },
    [rpr] => { kind: TokenKind::Paren(')') },
    [eof] => { kind: TokenKind::Eof },
  }
}

#[derive(Parse)]
#[token(Token)]
enum Statement {
  Elem(Elem),
  End(Token![eof]),
}

#[derive(Parse)]
#[token(Token)]
struct SExp(Token![lpr], Vec<Elem>, Token![rpr]);

#[derive(Parse)]
#[token(Token)]
enum Elem {
  Atom(Token![atom]),
  SExp(SExp),
}

上述实现形式与S-expression的对应EBNF表示非常接近

Statement ::= Elem | EOF;
SExp      ::= "(" {Elem} ")";
Elem      ::= ATOM | SExp;

更多示例

查看examples目录,其中包含以下示例

  • sexp:一个S-expression解析器。
  • calc:一个简单的表达式计算器。
  • json:一个简单的JSON解析器。
  • clike:C-like编程语言的解释器。

加速IDE的代码补全

默认情况下,Cargo不会为过程宏启用优化,如果您使用laps生成词法器,可能会导致代码补全变慢。为了避免这种情况,您可以在Cargo.toml中添加以下配置

[profile.dev.build-override]
opt-level = 3

您也可以尝试手动启用/禁用词法生成时的并行化,通过添加

#[derive(Tokenize)]
#[enable_par(true)] // or #[enable_par(false)]
enum TokenKind {
  // ...
}

并行化设置仅影响编译速度,对运行时没有影响,默认由laps自动设置。

变更日志

查看CHANGELOG.md

许可证

版权所有 (C) 2022-2023 MaxXing。根据您的选择,许可协议为Apache 2.0MIT

依赖关系

~0.3–11MB
~70K SLoC