12 个版本 (4 个稳定版本)
1.0.3 | 2024 年 4 月 27 日 |
---|---|
1.0.2 | 2022 年 9 月 27 日 |
1.0.1 | 2022 年 3 月 5 日 |
1.0.0 | 2021 年 5 月 4 日 |
0.1.0 | 2020 年 6 月 14 日 |
#185 in 解析器实现
1,292 每月下载量
用于 6 个 crate(5 个直接使用)
34KB
590 行
这是一个构建和准备表达式的库,例如布尔表达式(如 (A | B) & !(C | D | E)
),可以在动态内容上执行。
通过依次推送部分(括号、运算符、原子(“变量”))来构建表达式。您可以通过调用 push_operator
、open_par
、close_par
和 push_atom
函数来完成此操作,这些函数会为您构建树。
然后可以使用带有参数的 eval
函数进行评估
- 一个为原子提供值的函数
- 给定一个运算符和一个或两个值,给出新值的函数
- 决定是否短路的功能
正常评估顺序是从左到右,但可以用括号修改。
bet 是围绕构建、转换和评估的分离设计的,这样表达式就可以在许多输入上高效地应用。bet 设计用于非常快速的评估。
如果您想知道 bet 是否适用于您的问题,请随时 加入讨论。
已知的开源用途
dysk
bet 被用于 dysk 以过滤文件系统。
示例:dysk -f '(type=xfs & remote=no) | size > 5T'
。
在这里,原子是 类型=xfs
,remote=no
,以及 size > 5T
。
解析此类表达式的最简单方法是首先将其作为简单的字符串解析,然后对树应用 try_map_atoms
以替换字符串为可以高效评估的结构。
下面是如何实现的
impl FromStr for Filter {
type Err = ParseExprError;
fn from_str(input: &str) -> Result<Self, ParseExprError> {
// we start by reading the global structure
let mut expr: BeTree<BoolOperator, String> = BeTree::new();
for c in input.chars() {
match c {
'&' => expr.push_operator(BoolOperator::And),
'|' => expr.push_operator(BoolOperator::Or),
'!' => expr.push_operator(BoolOperator::Not),
' ' => {},
'(' => expr.open_par(),
')' => expr.close_par(),
_ => expr.mutate_or_create_atom(String::new).push(c),
}
}
// then we parse each leaf
let expr = expr.try_map_atoms(|raw| raw.parse())?;
Ok(Self { expr })
}
}
broot
在 broot 中,bet 允许对文件进行复合查询。
例如,!lock&(carg|c/carg/)
查找名称或内容包含 "carg" 的文件,但排除名称包含 "lock" 的文件。
rhit
bet 用于 rhit 过滤日志行。
例如,使用 rhit -p 'y & !( \d{4} | sp | bl )'
,您将获得包含 "y" 但不包含4位数、"sp" 或 "bl" 的路径上的命中统计信息。