数学表达式通常用中缀表示法表示。出于评估目的,我们可以将其更改为postfix(反向抛光)表示法(使用Shunting-Yard之类的算法),然后使用堆栈评估后缀表示法。
我发现计算器使用这种技术,但今天的现代编译器是否使用它进行算术表达式评估?它是否足够有效或正在使用其他技术(或算法)?
答案 0 :(得分:7)
要回答这个问题,请关注您提到的概念,infix notation
,Shunting-Yard
和evaluation
,然后将它们与编译相关联。
首先,我们需要了解通常计算机如何处理表达式。表达式转换为abstract syntax tree(AST),然后用于创建代码。将树转换为代码的过程各不相同,但AST的行走与评估表达式相同。
1 + 2的AST:
+
/ \
1 2
后缀:1 2 +
通过访问左侧分支1
,来评估这一点
访问右分支2
,
然后将运算符+
应用于两个操作数。
AST为1 * 2 + 3 ^ 4:
+
/ \
^ *
/ \ / \
3 4 1 2
后缀:3 4 ^ 1 2 * +
这是通过评估
访问左分支3^4
,
然后访问它的左分支3
,
然后访问它的右分支4
,
然后访问运营商^
,
并评估3^4
并将其作为`+'的新左分支,即81
然后访问右分支1*2
,
然后访问它的左分支1
,
然后访问它的右分支2
,
然后访问运营商*
,
并评估1*2
并将其作为“+'”的新右分支,即2
然后访问运营商+
,
并评估81+2
并将其作为结果83
现在,中缀符号为syntactic sugar,以便更容易为人类阅读表达式。为了帮助将infix-notation转换为AST,转换算法需要知道运算符的precedence和associativity。该算法还使用堆栈,该堆栈是Shunting-Yard算法的主要关键之一。我所知道的将中缀转换为评估策略的每种方法都以某种方式使用堆栈。
虽然编译器没有像计算器应用程序那样显式地计算表达式,但编译器确实将树的步行转换为将要执行评估的代码。
注意:由于我不了解每种语言的每个编译器,我只能根据一般概念给出答案。没有规则要求遵循这些规则,如果某些编译器跳过AST并从输入代码转到编译代码而不使用AST,我就不会感到惊讶。
此外,由于您提到了编译器,我只讨论了编译代码,而没有涉及脚本语言。
现在回到你的问题:
今天的现代编译器是否使用它来进行算术表达 评价
我不会特别使用Shunting-Yard算法,而是使用堆栈的概念,这是我将要使用的算法的关键概念之一。如果使用算法的概念与使用算法相同,您可以自己选择。
是否足够有效或正在使用其他技术(或算法) 使用
希望你现在知道这个问题的答案。并非Shunting-Yard算法很重要,但是使用堆栈来转换重要的中缀符号的概念是编译器使用的概念。请记住,编译语言通常不仅仅是计算表达式,它们使用类型,处理条件表达式,存储值,以及创建更高类型,如方法/函数,类和模块。