#lexer #token #flex #define #tokenize #flex-like #lexing-tokenizing

reflex

最小化的 flex-like 词法分析器

3 个版本

使用旧的 Rust 2015

0.1.2 2019 年 2 月 18 日
0.1.1 2018 年 2 月 16 日
0.1.0 2018 年 2 月 10 日

8 in #flex

MIT 许可证

5KB
62 代码行

reflex

一个简单的用 Rust 编写的 flex-like 词法分析/标记化库

工作流程

  • 定义一个带有所有可能标记的 Token 枚举,该枚举实现了 Clone
  • 使用 Ruleset::<Token>::new() 创建一个 Ruleset
  • 使用 add_rule()add_simple()add_noop() 添加标记规则
  • 使用要标记化的字符串调用 lex()
  • 根据需要使用结果懒迭代器

标记化简单计算器语言的示例代码

extern crate reflex;

use std::io;
use std::fmt;
use reflex::{Ruleset, lex};

#[derive(Clone)]
enum Token {
    Number(f64),
    OpAdd,
    OpSub,
    OpMul,
    OpDiv,
    OpPow,
}

impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            Token::Number(n) => n.to_string(),
            Token::OpAdd     => "+".to_string(),
            Token::OpSub     => "-".to_string(),
            Token::OpMul     => "*".to_string(),
            Token::OpDiv     => "/".to_string(),
            Token::OpPow     => "^".to_string(),
        }.to_string())
    }
}

fn main() {
    let mut program = String::new();
    io::stdin().read_line(&mut program).unwrap();

    let mut ruleset: Ruleset<Token> = Ruleset::new();
    ruleset.add_rule(r"-?[0-9]*\.?[0-9]+", |token| Token::Number(token.parse().unwrap_or(0.0)));
    ruleset.add_simple(r"\+", Token::OpAdd);
    ruleset.add_simple(r"-", Token::OpSub);
    ruleset.add_simple(r"\*", Token::OpMul);
    ruleset.add_simple(r"/", Token::OpDiv);
    ruleset.add_simple(r"\^", Token::OpPow);
    ruleset.add_noop(r"(?s)\s");

    for token in lex(&ruleset, program) {
        println!("{}", token.unwrap());
    }
}

依赖项

~2.2–3MB
~54K SLoC