#lexer #parser #lexical-analysis

chisel-lexers

Chisel后端词法分析器/扫描器

1个稳定版本

1.1.0 2023年10月30日
1.0.13 2023年10月29日

630文本处理

Download history 18/week @ 2024-03-29 4/week @ 2024-04-05

72 每月下载量
chisel-parsers 中使用

MIT/Apache

11MB
2K SLoC

chisel-lexers

Workflow Status

crates.io

crates.io

概述

此crate包含由chisel使用的词法分析后端。基本架构非常简单 - 多个词法分析器使用公共的扫描实现。

扫描器从底层字符源消耗字符,并跟踪读取字符的位置。它还提供了一些基本的缓冲和前瞻/回推功能。

始终假设输入是线性读取的,并且只能从开始到结束读取一次。

词法分析器从扫描器中消耗内容,并尝试构建令牌,这些令牌可以被堆栈更高层的解析器消耗。

词法分析器定义并能够产生其自己的独特令牌集合,这些令牌特定于当前的解析任务。(例如,JSON词法分析器仅产生JSON特定的令牌)。

扫描输入

扫描器通过维护简单的内部状态来操作

  • 输入中的当前位置
  • 用于控制回推和前瞻的输入缓冲区
  • 用于收集字符的累积缓冲区

词法分析器简单地通过扫描器(为每个字符添加位置信息)拉取字符,并在累积缓冲区中收集它们,直到它看到触发有效令牌解析的内容。

一旦词法分析器准备好消耗累积缓冲区中的所有内容,就会提供函数以提取缓冲区的内容的多种格式(例如字符串或字符数组),然后清除缓冲区而无需重置所有内部扫描器状态。

以下是一个使用扫描器的简单示例

 use std::io::BufReader;
 use chisel_common::reader_from_bytes;
 use chisel_decoders::utf8::Utf8Decoder;
 use chisel_lexers::scanner::Scanner;

 // construct a new scanner instance, based on a decoded byte source
 let buffer: &[u8] = "let goodly sin and sunshine in".as_bytes();
 let mut reader = BufReader::new(buffer);
 let mut decoder = Utf8Decoder::new(&mut reader);
 let mut scanner = Scanner::new(&mut decoder);

// consume the first character from the scanner...
let first = scanner.advance(true);
assert!(first.is_ok());
assert_eq!(scanner.front().unwrap().ch, 'l');
assert_eq!(scanner.front().unwrap().coords.column, 1);

// consume a second character
assert!(scanner.advance(true).is_ok());

// ...and then pushback onto the buffer
scanner.pushback();

// front of the buffer should still be 'l'
assert_eq!(scanner.front().unwrap().ch, 'l');

// advance again - this time char will be taken from the pushback buffer
let _ = scanner.advance(true);
assert_eq!(scanner.front().unwrap().ch, 'e');

// grab the contents of the buffer as a string
let buffer_contents= scanner.buffer_as_string_with_span();
assert_eq!(buffer_contents.str, String::from("le"));

// reset the scanner and empty the buffer
scanner.clear();

// buffer should now be empty
assert!(scanner.buffer_as_string_with_span().str.is_empty());

// advance yet again
assert!(scanner.advance(true).is_ok());

// the third character read will be from the 3rd column in the input
assert_eq!(scanner.front().unwrap().ch, 't');
assert_eq!(scanner.front().unwrap().coords.column, 3);


词法分析器

在当前版本中,此crate中仅实现了一个词法分析器后端

JSON词法分析器

构建和测试

内容 命令
构建crate cargobuild
测试crate cargotest
运行所有基准测试 cargobench

此crate包含两个特定的基准测试,可以单独运行

描述 命令
JSON词法分析(令牌化)基准测试 cargobench --benchjson_lexer
扫描(字符吞噬)基准测试 cargobench --benchscanner

建议和请求

如果您有任何建议、请求或只是关于此crate的评论,请只需添加一个问题,我会在有时间的时候查看。如果您想在您自己的工作中利用/修改此代码,请随时fork此仓库。

依赖项