14 个稳定版本 (4 个主要版本)
5.2.0 | 2022年11月26日 |
---|---|
5.1.1 | 2022年11月25日 |
4.1.0 | 2022年5月7日 |
4.0.0 | 2022年4月29日 |
1.2.0 | 2022年4月9日 |
#1827 在 解析器实现
每月146 次下载
用于 toros
9MB
15K SLoC
🐉 NixEL
Nix 表达式语言的解析器。
特性
-
✔️ 快速
它可以在不到25秒内解析Nixpkgs中的所有文件,单线程。[^基准规范]
-
✔️ 正确
这个库是Nix的原始词法分析器和解析器的复制粘贴,并对一些类型进行了适配,以更好地适应人体工程学。
没有解析器比这个更接近原始实现。
-
✔️ 可靠
高覆盖率,经过实战检验,且内存安全[^内存安全]。
-
✔️ 有用
它提供注释、空白、起始和结束位置、自动字符串转义、多行字符串缩进处理、类型化API以及解析Nix语言所需的一切!
使用方法
您可以在docs.rs/nixel查看文档。
这是一个完整的用法示例
let input: String = String::from(
r#"
# Greet the user
"Hello, World!"
# Bye!
"#,
);
let parsed: nixel::Parsed = nixel::parse(input);
match &*parsed.expression {
nixel::Expression::String(string) => {
assert_eq!(
&string.span,
&nixel::Span {
start: nixel::Position { line: 3, column: 9 }.into(),
end: nixel::Position { line: 3, column: 24 }.into(),
}
.into()
);
assert_eq!(
&parsed.trivia_before(&string.span.start)[1],
&nixel::Trivia::Comment(nixel::TriviaComment {
content: "# Greet the user".into(),
span: nixel::Span {
start: nixel::Position { line: 2, column: 9 }.into(),
end: nixel::Position { line: 2, column: 25 }.into(),
}
.into()
})
);
assert_eq!(
&string.parts[0],
&nixel::Part::Raw(nixel::PartRaw {
content: "Hello, World!".into(),
span: nixel::Span {
start: nixel::Position { line: 3, column: 10 }.into(),
end: nixel::Position { line: 3, column: 23 }.into(),
}
.into()
})
);
assert_eq!(
&parsed.trivia_after(&string.span.end)[1],
&nixel::Trivia::Comment(nixel::TriviaComment {
content: "# Bye!".into(),
span: nixel::Span {
start: nixel::Position { line: 4, column: 9 }.into(),
end: nixel::Position { line: 4, column: 15 }.into(),
}
.into()
})
);
},
expression => unreachable!("Expected a String, got: {expression:#?}"),
}
或从命令行使用Rust的Debug特性
$ echo '1 + 2' | nix run github:kamadorueda/nixel -- --format=debug
BinaryOperation(
BinaryOperation {
left: Integer(
Integer {
value: "1",
span: Span {
start: Position {
line: 1,
column: 1,
},
end: Position {
line: 1,
column: 2,
},
},
},
),
operator: Addition,
right: Integer(
Integer {
value: "2",
span: Span {
start: Position {
line: 1,
column: 5,
},
end: Position {
line: 1,
column: 6,
},
},
},
),
},
)
或从命令行使用JSON格式
$ echo '1 + 2' | nix run github:kamadorueda/nixel -- --format=json
{
"BinaryOperation": {
"left": {
"Integer": {
"value": "1",
"span": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 2
}
}
}
},
"operator": "Addition",
"right": {
"Integer": {
"value": "2",
"span": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
}
}
}
}
}
}
您可以在测试文件夹中查看更多示例。
替代方案
许可协议
请阅读LICENSE.md。
脚注
[^基准规范]: 在机器上运行
- CPU: 4 physical, 4 logical, 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
- MHz: from 400 to 4700 MHz
- BogoMips: 5606.40
- Cache L3: 12 MiB
The following command takes around 1 minute:
```bash
$ nix build --system x86_64-linux
$ time find /data/nixpkgs -type f -name '*.nix' \
-exec ./result/bin/nixel --format=none {} \;
real 0m24.293s
user 0m15.066s
sys 0m8.955s
```
[^内存安全]: 使用Valgrind在真实工作负载下测试,并通过对Nixpkgs运行无限循环的解析周期进行测试。
```bash
$ nix build --system x86_64-linux
$ valgrind ./result/bin/nixel $file
LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
suppressed: 0 bytes in 0 blocks
```