2个版本

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

#73 in #scanner


用于 sana

MIT 许可证

76KB
2K SLoC

Sana

Rust crates.io docs.rs

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

与其他词法分析器生成器不同,Sana支持扩展正则表达式,这允许你更清晰地表达你的意图。例如,你可以编写 "[[:punct:]]+" & !".*--.*" 来表示不包含 -- 的标点符号序列。

在编译时,Sana

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

有关Sana架构的概述,请参阅 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