分流码算法用于将表达式从中缀转换为后缀表示法(反向波兰表示法),以便编译器更容易评估它们。例如,2 + 3 * 2
将转换为2 3 2 * +
. 在Wikipedia中,提到该算法被许多应用程序使用,包括
任何面向堆栈的编程语言,例如:Forth、Factor、PostScript 页面描述语言、Befunge、Joy
我看不到 C# 甚至任何流行的高级语言。那么,C# 是否将这种算法用于表达式?如果不是,C# 编译器如何编译和评估表达式?
是的,C# 被转换为面向堆栈的编程语言——IL。当编译器将表达式转换为内部语言时,它会生成一个遵循 RPN 的操作列表。
比如这个方法
int x(int a, int b, int c, int d) {
return a+b*(c+d);
}
被转换为这种内部语言(请参阅评论以了解正在发生的事情):
IL_0001: ldarg.0 // Push a on the stack
IL_0002: ldarg.1 // Push b on the stack
IL_0003: ldarg.2 // Push c on the stack
IL_0004: ldarg.3 // Push d on the stack
IL_0005: add // Add d+c, push the result
IL_0006: mul // Multiply (d+c) by b
IL_0007: add // Add b*(d+c)+a
正如你所看到的,操作数被压入堆栈的顺序使得通过从表达式的后面到前面的工作可以方便地执行操作 - 正是文章解释它的方式。
转换的确切算法取决于编译器(严格来说,最终结果也取决于编译器,因为有多种方法可以将表达式转换为有效的 RPN 序列),但 RPN 的基本思想就在那里。