扩展分流码算法以支持条件三元运算符

时间:2016-02-24 17:36:34

标签: ternary-operator conditional-operator shunting-yard

如何扩展分流码算法,这最初是为二元运算符支持条件三元运算符(“a?b:c”)? 我在这里没有看到答案,我有一个,所以我发布了它。

2 个答案:

答案 0 :(得分:3)

我这样做的方法是添加三个新的运算符:

  • “?” ternary-open-if
  • “:”ternary-else
  • ternary-closed-if

在阅读初始表达式时,只会直接创建前两个 但是,输出中只存在第三个(初始表达式的RPN) 每当“?”时,三元组open-if就会被置于运算符堆栈中看到了。
三元 - 其他永远不会被放在堆栈上。相反,堆栈是poped直到找到三元open-if,然后三元open-if被替换为三元闭合if(因此表明我们在条件运算符的else部分)。登记/> 所有三个运营商都优先于所有其他运营商(更高的意义是他们在其他运营商之后进行评估) 三元-if运算符具有相同的优先级和正确的关联性(如在C中),这意味着三元 - 如果永远不会导致另一个三元组的流行 - 如果。 三元 - 其他的优先级高于三元组,并且它的关联性是无关紧要的(因为它永远不会被放在堆栈上)。因此,当遇到三元开放时 - 如果它将如前所述将其转换为封闭的那个 当遇到三元封闭时 - 如果它会弹出它。

示例(三元封闭 - 如果标注为“?:”):

  • “a?b:c” - >
    “a b c?:”
  • “a?b:x?y:z” - >
    “a b x y z?:?:”
  • “a?x?y:z:b” - >
    “a x y z?:b?:”

这种方法比实现方法更难解释,并且它确实对算法稍作修改,因此如果有人有更简单的解决方案,请发布它。

答案 1 :(得分:0)

对于仍在此处搜索的任何人,也可以将条件三元运算符实现为具有三个参数的IF函数:

IF([boolean], [expr_if_true], [expr_if_false])

例如,要通过扩展调车码算法将IF(5 > 4, 9, 8)转换为反向波兰符号,请执行以下操作:

+-------+---------------------------------------------------+--------------+----------------+
| Token | Action                                            | RPN Output   | Operator stack |
+-------+---------------------------------------------------+--------------+----------------+
| IF    | Push token to stack                               |              | IF             |
| (     | Push token to stack                               |              | IF (           |
| 5     | Add token to output                               | 5            | IF (           |
| >     | Push token to stack                               | 5            | 15 ( >         |
| 4     | Add token to output                               | 5 4          | IF ( >         |
| ,     | Pop from stack onto output until left parenthesis | 5 4 >        | IF (           |
| 9     | Add token to output                               | 5 4 > 9      | IF (           |
| ,     | Pop from stack onto output until left parenthesis | 5 4 > 9      | IF (           |
| 8     | Add token to output                               | 5 4 > 9 8    | IF (           |
| )     | Pop from stack onto output until left parenthesis | 5 4 > 9 8    | IF             |
| end   | Pop entire stack onto output                      | 5 4 > 9 8 IF |                |
+-------+---------------------------------------------------+--------------+----------------+

后缀评估为:

+-------+------------------------------------------------------------------------------------------+-------+
| Token | Action                                                                                   | Stack |
+-------+------------------------------------------------------------------------------------------+-------+
| 5     | Push to stack                                                                            | 5     |
| 4     | Push to stack                                                                            | 4     |
| >     | Pop from stack twice (5, 4), evaluate (5 > 4) and push onto stack                        | TRUE  |
| 9     | Push onto stack                                                                          | 9     |
| 8     | Push onto stack                                                                          | 8     |
| IF    | Pop from stack thrice (TRUE, 9, 8), evaluate (IF TRUE THEN 9 ELSE 8) and push onto stack | 9     |
+-------+------------------------------------------------------------------------------------------+-------+