#convert #tokens #expression #postfix #infix #reverse #operand

fixit

将中缀(人类可读)表达式标记转换为后缀(逆波兰表示法)顺序

2 个版本

0.1.1 2022 年 12 月 21 日
0.1.0 2022 年 12 月 20 日

#1821 in 算法

MIT/Apache

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

无运行时依赖