2 个版本
0.1.1 | 2022 年 12 月 21 日 |
---|---|
0.1.0 | 2022 年 12 月 20 日 |
#1821 in 算法
18KB
261 行
fixit
将中缀标记转换为后缀标记,也称为https://zh.wikipedia.org/wiki/逆波兰表示法。
这个库不做表达式的解析或执行,只过滤/重新排序标记以允许基于堆栈的执行。基于堆栈执行的可能不太高效)的替代方案通常涉及遍历表达式树。
示例
use fixit::{BinaryOperator, InfixToken, convert};
// Define your own operand: it could be anything.
type MyOperand = f32;
// Define your own operator.
enum MyBinaryOp {
Add,
Sub,
Mul,
Div,
}
// Assign a precedence to each operator
impl BinaryOperator for MyBinaryOp {
fn precedence(&self) -> u8 {
match self {
MyBinaryOp::Add => 1,
MyBinaryOp::Sub => 1,
MyBinaryOp::Mul => 2,
MyBinaryOp::Div => 2,
}
}
}
type MyInfixToken = InfixToken<MyOperand, MyBinaryOp>;
// The incoming `expr` tokens could have been parsed from a string via a crate like `nom` or `pest`.
// Parsing an expression like "a + b * c + d" should give:
// vec![
// InfixToken::Operand("a"), InfixToken::BinaryOp(MyBinaryOp::Add), InfixToken::Operand("b"),
// InfixToken::BinaryOp(MyBinaryOp::Mul),
// InfixToken::Operand("c"), InfixToken::BinaryOp(MyBinaryOp::Add), InfixToken::Operand("d")
// ]
fn example(expr: Vec<MyInfixToken>) {
// Convert to postfix. The result will contain:
// vec![
// PostfixToken::Operand("a"),
// PostfixToken::Operand("b"),
// PostfixToken::Operand("c"),
// PostfixToken::BinaryOp(MyBinaryOp::Mul),
// PostfixToken::BinaryOp(MyBinaryOp::Add),
// PostfixToken::Operand("d"),
// PostfixToken::BinaryOp(MyBinaryOp::Add)
// ]
let postfix_tokens = convert(expr);
// We don't aim to provide a full explanation of postfix expressions here, but
// the expression can now be evaluated by iterating over postfix tokens,
// pushing and popping values off a stack.
}
许可协议:MIT OR Apache-2.0