【问题标题】:The Interpreter and Reverse Polish Notation解释器和逆波兰符号
【发布时间】:2015-11-27 14:00:35
【问题描述】:

使用高级语言,解释器/编译器的工作是在执行之前将数学表达式从中缀表示法转换为后缀或前缀。事实上,中缀表达式是否需要进行转换才能“处理”?我试图了解“幕后”发生的事情。不过,我对堆栈的概念及其与 RPN 的使用很好。

【问题讨论】:

  • 您是在询问特定的语言或硬件架构吗?通常程序栈与你在 RPN 中得到的操作数栈完全没有关系。
  • 我试图理解 PN 的意义。虽然这是表示表达式的另一种方式,但它为什么存在 - 计算机是否要求表达式为 PN 格式?对不起,如果这个问题有点模棱两可。
  • 他们不需要这样,不,但是 RPN 形式的表达式很容易使用值堆栈进行评估,并且也比传统表达式更简单地转换为本机代码。跨度>

标签: computer-science postfix-notation


【解决方案1】:

(反转与否)波兰表示法不被计算机内部使用:它完全是为人类使用的。它之所以受欢迎,是因为它是一种表示电子计算器相当复杂的算术表达式的方法,当时它们还不够复杂,无法理解运算符优先级和括号,就像今天的计算器一样。使用这些计算器“长大”的工程师已经习惯了以这种方式思考,所以很自然地,通用计算机上的第一个计算器程序也以同样的方式工作。

当您用编程语言编写表达式时,解析器(理解该语言的解释器或编译器的部分)将该表达式转换为一棵树,其中树的每个节点都是一个操作,而该树的每个子节点都是一个操作node 是表达式的操作数。例如,

f(3 + 4)

可能是一个“函数调用”节点,它的第一个子节点是名称f,第二个子节点是一个“add”节点。 “add”节点的子节点是“literal”节点(即值),其值为 3 和 4。

这棵树被称为抽象语法树 (AST),因为它的结构与语言的语法是分开的(即语法被抽象掉了)。在像 gcc 这样可以理解几种不同语言的编译器中,每种语言的解析器都会生成相同类型的 AST,而原始语言是使用 RPN,还是数学风格的中缀表示法,或者只使用函数调用都无关紧要。

解析器然后将其提供给后端。在解释器中,后端将一次只评估每个节点,很可能从底部开始。也就是说,首先它将“add”节点及其子节点替换为值 7,然后查找名为 f 的函数,然后将“函数调用节点”及其子节点替换为函数调用的结果。

编译器将树转换为指令序列。在此示例中,它们可能类似于:

将 3 加载到寄存器 0
将 4 加载到寄存器 1
添加寄存器 0 和 1,并将答案放入寄存器 0
跳转到 f 的代码,它的参数需要在寄存器 0 中
使用寄存器 0 中的结果

显然,这些指令并没有那么冗长:它们是用汇编语言编写的,这通常特定于目标体系结构(您正在为其编译的计算机类型)。我不会展示整个汇编程序,但添加指令可能如下所示:

add r0, r0, r1

编译器的最后一步是汇编器,它将汇编程序的每条指令翻译成一个数字,实际的CPU可以理解。

其中没有 RPN 或操作数堆栈。您听到的有关程序使用的“堆栈”(例如本网站名称中的那个)是一个(某种)自动增长的内存区域。程序可以使用它来存储太大而无法放入寄存器的东西,或者会被函数调用清除的东西(因为被调用的函数想要使用您正在使用的寄存器)。

已经有CPU architectures that actually did use a stack,CPU 的汇编语言看起来有点像 RPN。 PostScript 使用的“虚拟机”是一个例子,Lisp Machines 是/曾经是一个真正的硬件例子。不过,当今流行的 CPU 架构都没有以这种方式工作。

【讨论】:

  • 您的整个指令示例实际上是遵循逆波兰表示法。正如您所指出的,每条指令本身都是前缀波兰表示法(不是中缀表示法)。
  • @hylitiz 有点相似,但主要区别在于波兰语或反向波兰语中,您可以直接将操作链接在一起,例如1 2 + 4 * 将 1 和 2 相加,然后将结果乘以 4。在我的汇编语言示例中,每一行都是写入特定寄存器的单个操作。将结果分配给寄存器在汇编语言形式中是明确的,这是组合操作的唯一方式。
  • 是的,我同意,它非常相似。在那种汇编语言形式中,我们可以将并列(一行接一行)定义为表达式的链式操作吗?那样的话,不是又变成波兰语了吗?
  • @hyiltiz 并非如此,因为在基于寄存器的体系结构中,由每个操作命名的寄存器决定了它们如何连接。例如add r0 1 2; add r1 3 4; sub r0 r0 r1 执行 (1+2) - (3+4),如果您交换前两条指令,它也会执行相同的操作。等效的 RPN 是 1 2 + 3 4 + -,但 3 4 + 1 2 + - 是 (3+4) - (1+2)。
【解决方案2】:

这完全取决于特定语言的设计 - 只要确保计算的正确性,无论它们是以中缀、后缀还是其他方式完成的。

【讨论】:

  • 谢谢,所以我想我想了解波兰表示法的必要性
  • @tommyd456 好吧,wiki 有一些很好的解释:en.wikipedia.org/wiki/…
猜你喜欢
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多