我在搜索有关将三元运算符转换为反向波兰表示法 (RPN) 的信息时遇到了这个问题,所以虽然我没有可靠的实现来实现?:
具有优先爬升的运算符,但我确实认为我可以提供一些线索使用两个堆栈将?:
运算符转换为 RPN ......这类似于您给出的网页中的 Shutting Yard 算法。
(编辑)我必须指出我在这里所做的不是很有效(必须评估三元运算符的两个分支),但要演示?:
在现有框架中合并新运算符 ( ) 是多么容易( RPN 转换代码)(通过声明?
和:
两个最低优先级)。
我想从一些示例开始,说明如何?:
根据我的解析器将表达式 with 转换为 RPN ...我添加了两个运算符而不是一个,?
and :
,但我认为这不会有很大的不同,因为:
并且?
将永远放在一起(RPN和原始表达式具有相同数量的令牌更方便)。在示例中,您可以看到它是如何工作的。
示例 1:1 + ((0+1) ? 2 : 3 + 8) + 4
RPN:1
0
1
+
2
3
8
+
:
?
+
4
+
现在让我们评估 RPN。
1 - 将第一个元素推入堆栈,我们遇到了第一个二元运算符:
1
0
1
和 operator +
,我们添加顶部 2 个元素,将堆栈变成1
1
2 - 然后再推三个元素,我们遇到了第二个二元运算符:
1
1
2
3
8
+
------>1
1
2
11
3 - 现在我们有:
和?
。这实际上告诉我们选择后续分支(堆栈顶部的第二个最顶部元素2
)或替代分支(堆栈顶部11
的元素) . 由于谓词为 1(真),我们选择 2 并丢弃 11。解析器弹出 3 个元素(谓词/结果/替代)并推回选择的元素(在本例中为结果分支),因此堆栈变为1
1
2
4 - 消耗剩余的元素:
1
2
+
------>3
3
4
+
------>7
示例 2:1 + ((0+0+0?0:0) ? 2 : (3 + 8)) + 4
RPN:1
0
0
+
0
+
0
0
:
?
2
3
8
+
:
?
+
4
+
评估:
开始:
1
0
0
+
0
+
0
0
:
?
2
3
8
+
:
?
+
4
+
将 0 加到 0 后:
1
0
0
+
0
0
:
?
2
3
8
+
:
?
+
4
+
将 0 加到 0 后:
1
0
0
0
:
?
2
3
8
+
:
?
+
4
+
第一个:?
选择后0
:
1
0
2
3
8
+
:
?
+
4
+
添加 3 和 8 后:
1
0
2
11
:
?
+
4
+
?:
选择11后:
1
11
+
4
+
添加 1 和 11 后:
12
4
+
最后:
16
这可能表明可以将表达式?:
转换为反向波兰符号。正如网页所说,RPN 和 AST 是等价的,因为它们可以相互转换,三元运算符应该能够以类似的方式通过 Precedence Climbing 实现。
需要做的一件事似乎是?:
运算符的“优先级”(或优先级)。我在尝试 RPN 转换时实际上遇到了它。我给了问号和冒号最低优先级:
正如您从上面的示例中看到的那样,每当我们要执行?:
时,优先分支和替代分支和谓词应该已经被评估,产生一个数字。这是由优先级保证的。
以下是优先级(优先级)表。
!
~
> *
/
%
> +
-
> &
> ^
> |
> &&
> ||
> ?
>:
?
and的:
优先级最低,在 1?2+3:4+5 这样的表达式中表示,?
并且:
永远不会接受它们周围的操作数。
?
出现:
在RPN之前。据我了解,这只是一种设计选择,因为甚至不一定必须首先拆分为 2 个运算符。:
?
:
?
希望这可以帮助..
参考:http ://en.cppreference.com/w/cpp/language/operator_precedence