2 个版本

0.1.1 2020年8月11日
0.1.0 2020年8月11日

#240 in 解析工具

MIT 许可证

56KB
1.5K SLoC

萨纳

Rust crates.io docs.rs

萨纳是 Rust 的词法分析器生成器。它提供了一种简单的方式来创建一种语言的词法分析器。

与其他词法分析器生成器不同,萨纳支持扩展的正则表达式,这使得您能够更清晰地表达您的意图。例如,您可以使用以下代码来表示不包含 -- 的标点符号序列:"[[:punct:]]+" & !".*--.*"

在编译时,萨纳

  • 从令牌定义构建确定状态自动机
  • 从自动机生成 IR
  • 将 IR 编译成 Rust 代码

有关萨纳架构的概述,请参阅 DESIGN.md

示例

use sana::{Sana, Spanned};

#[derive(Debug, Clone, Copy, PartialEq, Sana)]
#[backend(rust)] // optional. can be either rust or vm. default is rust
enum Token {
    #[regex("[a-zA-Z_][a-zA-Z0-9_]*")]
    Ident,
    #[regex("[0-9]+")]
    Integer,

    #[token("let", priority = 1)]
    Let,
    #[token("=")]
    Equals,
    #[regex(";")]
    Semicolon,

    #[regex("[ \t\r\n]")]
    Whitespace,
    #[error]
    Error,
}

fn main() {
    let mut lexer = Token::lexer("let answer = 42;");

    assert_eq!(
        lexer.next(),
        Some(Spanned { value: Token::Let, start: 0, end: 3 })
    );
    assert_eq!(lexer.next(),
        Some(Spanned { value: Token::Whitespace, start: 3, end: 4 })
    );
    assert_eq!(lexer.next(),
        Some(Spanned { value: Token::Ident, start: 4, end: 10 })
    );
    assert_eq!(lexer.next(),
        Some(Spanned { value: Token::Whitespace, start: 10, end: 11 })
    );
    assert_eq!(
        lexer.next(),
        Some(Spanned { value: Token::Equals, start: 11, end: 12 })
    );
    assert_eq!(
        lexer.next(),
        Some(Spanned { value: Token::Whitespace, start: 12, end: 13 })
    );
    assert_eq!(
        lexer.next(),
        Some(Spanned { value: Token::Integer, start: 13, end: 15 })
    );
    assert_eq!(
        lexer.next(),
        Some(Spanned { value: Token::Semicolon, start: 15, end: 16 })
    );

    // No tokens left
    assert_eq!(
        lexer.next(),
        None
    );
}

您可以在 examples 目录中找到更多示例。

依赖项

~3.5MB
~93K SLoC