2 个版本
0.1.1 | 2023年11月7日 |
---|---|
0.1.0 | 2023年11月6日 |
#2204 in 解析器实现
12KB
169 行
逻辑表达式解析器
这是一个使用 pest 库编写的简单的逻辑表达式解析器。程序包含两个主要部分:
- parse_expr 函数,它接受字符串作为输入,将其转换为抽象语法树 (AST),并以 Expr 枚举格式保存。
- 为 Expr 枚举实现 evaluate 方法,用于计算表达式的结果
程序具有 CLI。
使用命令 'cargo run -- -h' 显示帮助信息。
支持的语法
解析器支持以下语法
真: '1'
假: '0'
非: '!'
逻辑与: '&&'
逻辑或: '||'
蕴涵: '->'
等价: '<->'
异或: 'xor'
括号: '(', ')'
在 AST 输出中
整数 - 0 或 1
一元非 - !
逻辑运算 - 包含 {
lhs - 左操作数
op - 运算符名称
rhs - 右操作数
}
使用示例
- 输入: 1 || 0
输出
LogicalOp {
lhs: Integer(
1,
),
op: LogicalOr,
rhs: Integer(
0,
),
}
Result: true
- 输入: (0 && 1 -> !1 || 0) && 0
输出
LogicalOp {
lhs: LogicalOp {
lhs: LogicalOp {
lhs: Integer(
0,
),
op: LogicalAnd,
rhs: Integer(
1,
),
},
op: Implication,
rhs: LogicalOp {
lhs: UnaryNot(
Integer(
1,
),
),
op: LogicalOr,
rhs: Integer(
0,
),
},
},
op: LogicalAnd,
rhs: Integer(
0,
),
}
Result: false
技术描述
语法
程序在 grammar.pest 文件中使用 Pest 解析器生成库定义了一个语法。
语法规则
binary_digit: 匹配二进制数字,可以是 "0" 或 "1"。bin_op: 匹配二进制运算符,可以是逻辑与、逻辑或、蕴涵、等价或异或。unary_not: 匹配 "!" 字符,表示逻辑非。logical_and: 匹配 "&&" 字符,表示逻辑与。logical_or: 匹配 "||" 字符,表示逻辑或。implication: 匹配 "->" 字符,表示蕴涵。equivalence: 匹配 "=" 字符,表示等价。xor: 匹配 "xor" 字符,表示异或。primary: 匹配原表达式,可以是二进制数字或括号内的表达式。atom: 匹配原子,是可选的逻辑非和原表达式的组合。expr: 匹配完整表达式,由原子通过二进制运算符分隔。equation: 匹配整个方程,由输入开始 (SOI) 和输入结束 (EOI) 标记包围。WHITESPACE: 匹配空白,由单个空格字符或制表符表示。
解析过程
所有程序逻辑位于 lib.rs 文件中。解析过程使用 pest 库中实现的 Pratt 解析器执行。Pratt 解析器是一种自上而下的运算符优先级解析器,可以处理不同优先级和结合性的运算符。使用 lazy_static 初始化和存储 Pratt 解析器。
运算符优先级从低到高(优先级低的先执行)
- 逻辑非(!)
- 逻辑与(&&)
- 逻辑或(||)
- 等价(<->),异或(xor)
- 蕴涵(->)
评估
解析表达式后,程序构建了一个表示逻辑表达式的抽象语法树(AST)。AST由Expr和Op枚举定义,其中Expr可以表示二进制位、一元非或逻辑运算,Op表示逻辑运算符。
Expr枚举用于评估表达式的真值。evaluate方法通过根据逻辑运算符和真值评估子表达式递归地计算结果。
依赖
~2.2–3MB
~59K SLoC