c - 如何将三元运算符合并到优先级攀升算法中?

标签 c parsing expression grammar operator-precedence

我遵循了 this webpage 上“优先攀登”部分给出的解释。使用具有各种一元前缀和二元中缀运算符的优先级攀升算法来实现算术评估器。我还想包括三元运算符(即三元条件运算符 ?:)。

网页上给出的算法使用了如下语法:

E --> Exp(0) 
Exp(p) --> P {B Exp(q)} 
P --> U Exp(q) | "(" E ")" | v
B --> "+" | "-"  | "*" |"/" | "^" | "||" | "&&" | "="
U --> "-"

如何将三元运算符合并到此语法中?

最佳答案

具体来说,我以C/C++/Java的?:为例

在那些语言中,?: 运算符似乎允许 ?: 之间的任何有效表达式,包括由 构成的表达式?: 本身以及由运算符组成的运算符,其优先级低于 ?: 的优先级,例如=,(例如:a ? b = c : d, a ? b , c : d, a ? b ? c : d : e).

这表明您应该以与 () 完全相同的方式对待 ?: 而解析表达式。当你解析出 时? expr :,它整体上是一个二元运算符。所以,你解析 ( expr )? expr : 同理,但前者是表达式,后者是二元运算符(内嵌表达式)。

现在 ? expr : 是二元运算符(a ?-expr-: b 在“二元性”方面与 a * b 没有区别),你应该是能够像您已经支持的任何其他二元运算符一样支持它。

就我个人而言,我不会费心将 ?: 拆分成它们自己的独立二元运算符。最后,它仍然是一个三元运算符,它必须链接到 3 个操作数,并在表达式评估期间作为一个整体考虑。如果您正在按照问题中提到的文章中的方法创建 AST,那么您就可以了,?: 有一个左子节点,一个右子节点(与任何其他二进制文件一样运算符),另外还有一个中间子节点。

?-expr-: 整体的优先级应该是低的。不过,在 C/C++(和 Java?)中,它并不是最低的。由您决定您想要它成为什么。

到目前为止,我们还没有介绍 ?: 的关联性。在 C/C++ 和 Java 中,?-expr-: 与赋值运算符 = 一样是右结合的。同样,由您决定是使其左结合还是保持右结合。

还有这个:

E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^"
U --> "-"

应该变成这样:

E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^" | "?" E ":"
U --> "-"

关于c - 如何将三元运算符合并到优先级攀升算法中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13681293/

相关文章:

c - 如何对指向 char 的指针数组进行排序

php - 如何使用 PHP Simple HTML DOM Parser 在 HTML 文件中找到最后一个 <div class>?

javascript - 定义内联 javascript 表达式的替代方法

asp.net-mvc - ASP.NET MVC 和 Expression XAML - 如何集成?

c++ - 为什么以下 while 循环使用 AND 而不是 OR

c - WinHttpSendRequest 返回 ERROR_INVALID_PARAMETER

c - 主函数包含对 exit() 和 pthread_exit() 的调用。这两个调用在执行时的效果会有什么不同?

C# DateTime 解析国际文化

parsing - 组合的解解析器/解析器生成器

c++ - 链接上 undefined symbol ___gxx_personality_v0