20 个不稳定版本 (5 个破坏性更新)
0.6.0 | 2020年4月12日 |
---|---|
0.5.1 | 2019年10月20日 |
0.4.2 | 2019年7月12日 |
0.3.1 | 2019年3月30日 |
0.2.1 | 2018年11月25日 |
#777 in 文本处理
31,066 每月下载量
在 7 个crate中(直接使用2个) 使用
27KB
296 行
uwl
一个 Unicode 兼容的词法分析器。正如它最初的形式。
这个crate提供了一个字符串源的流,用于操作其字节内容,可以直接使用字节本身,或者通过它们的 Unicode 代码点字符表示形式。
许可证
许可协议为以下之一
- Apache 许可协议第 2 版 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可协议 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
除非你明确声明,否则根据 Apache-2.0 许可证定义的,你有意提交的任何贡献,都应作为上述双重许可,而不附加任何其他条款或条件。
lib.rs
:
为单独操作字节和 Unicode 代码点字符而设计的流。
示例
使用流创建一个用于标记英语语言的词法分析器。
use uwl::Stream;
#[derive(Debug, PartialEq)]
enum TokenKind {
Ident,
Number,
Question,
Exclamation,
Comma,
Point,
// An invalid token
Illegal,
}
#[derive(Debug, PartialEq)]
struct Token<'a> {
kind: TokenKind,
lit: &'a str,
}
impl<'a> Token<'a> {
fn new(kind: TokenKind, lit: &'a str) -> Self {
Self { kind, lit }
}
}
fn lex<'a>(stream: &mut Stream<'a>) -> Option<Token<'a>> {
let b: u8 = stream.current()?;
if b.is_ascii_whitespace() {
// Ignore whitespace.
stream.take_while(|b| b.is_ascii_whitespace());
return lex(stream);
}
if b.is_ascii_digit() {
let lit = stream.take_while(|b| b.is_ascii_digit());
return Some(Token::new(TokenKind::Number, lit));
}
if b.is_ascii_alphabetic() {
let lit = stream.take_while(|b| b.is_ascii_alphabetic());
return Some(Token::new(TokenKind::Ident, lit));
}
let token = match b {
b'?' => Some(Token::new(TokenKind::Question, &stream.rest()[..1])),
b'!' => Some(Token::new(TokenKind::Exclamation, &stream.rest()[..1])),
b',' => Some(Token::new(TokenKind::Comma, &stream.rest()[..1])),
b'.' => Some(Token::new(TokenKind::Point, &stream.rest()[..1])),
_ => Some(Token::new(TokenKind::Illegal, &stream.rest()[..1])),
};
stream.next();
token
}
fn main() {
let mut stream = Stream::new("Hello, world! ...world? Hello?");
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "Hello")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Comma, ",")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "world")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Exclamation, "!")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Point, ".")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Point, ".")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Point, ".")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "world")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Question, "?")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "Hello")));
assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Question, "?")));
// Reached the end
assert_eq!(lex(&mut stream), None);
}