#lexer #lexical-analysis #lexical #analysis #compiler #parser

已删除 pattern-lexer

基于插件的词法分析器

2 个版本

0.1.1 2024 年 1 月 14 日
0.1.0 2024 年 1 月 14 日

#17#lexical-analysis

MIT 许可证

22KB
239 代码行

词法分析器

我个人的词法分析器实现。

原则

词法分析器基于插件。这不是一个 解析器 也不是一个 编译器

令牌

有 8 种预制的令牌类型(以下示例不是强制的)

TokenKind 说明 示例
KEYWORD 保留字 if return ...
DELIMITER 成对的分隔符符号 () [] {} ...
PUNCTUATION 标点符号 ; . ...
OPERATOR 操作参数的符号 + - = ...
COMMENT 行或块注释 // /* ... */ ...
WHITESPACE 不可打印的字符 -
LITERAL 数值、逻辑、文本值 1 true "true" ...
IDENTIFIER 程序中指定的名称 x temp PRINT ...

这些令牌类型(除 IDENTIFIER)应使用可区分相同类型的名称构造。

每个 TokenKind 都可以与一个或多个 Pattern 关联,这些 Pattern 通过 Tokenizer 将它们与字符串匹配,从而生成一个 Token

词法分析器

词法分析器应该使用包含几个 TokenizerLexerBuilder 构造。

示例

简单的数学 Lexer

let plus = Tokenizer::new(TokenKind::OPERATOR("PLUS"), '+');
let minus = Tokenizer::new(TokenKind::OPERATOR("MINUS"), '-');
let star = Tokenizer::new(TokenKind::OPERATOR("STAR"), '*');
let slash = Tokenizer::new(TokenKind::OPERATOR("SLASH"), '/');
let equal = Tokenizer::new(TokenKind::OPERATOR("EQUAL"), '=');
let number = Tokenizer::new(TokenKind::LITERAL("NUMBER"), |s: &str| {
  let mut dot_seen = false;

  for ch in s.chars() {
    if !ch.is_digit(10) && (ch != '.' || dot_seen) {
      return false;
    } else if ch == '.' {
      dot_seen = true;
    }
  }
  
  true
});
let id_regex = Regex::new(r"[a-zA-Z_$][a-zA-Z_$0-9]*").unwrap();
let id = Tokenizer::new(TokenKind::IDENTIFIER, id_regex);
let whitespace = Tokenizer::new(TokenKind::WHITESPACE("SPACE"), ' ');
let lexer = Lexer::builder()
  .extend(vec![plus, minus, star, slash, equal, number, id, whitespace])
  .build();

lexer.tokenize("x_4 = 2 + 2 = 4 * 0.5")?;
/* [Token { kind: IDENTIFIER, value: "x_4" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: OPERATOR("EQUAL"), value: "=" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: LITERAL("NUMBER"), value: "2" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: OPERATOR("PLUS"), value: "+" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: LITERAL("NUMBER"), value: "2" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: OPERATOR("EQUAL"), value: "=" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: LITERAL("NUMBER"), value: "4" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: OPERATOR("STAR"), value: "*" }, 
  Token { kind: WHITESPACE("SPACE"), value: " " }, 
  Token { kind: LITERAL("NUMBER"), value: "0.5" }] */

依赖项

~2.2–3MB
~55K SLoC