后进者先出,先进者后出,这就是数据结构中的”栈”。栈是一种相当简单的数据结构,但应用十分广泛,例如编程语言中的函数调用栈
、浏览器的前进后退功能。本文讲的是栈的另一个常见应用场景,编译器利用栈实现表达式求值
。初次见到这种实现思路的时候,我不禁叫绝,一个简单的栈还能玩出花。
例如,一个简单的四则运算:10+20*2-30/3
。人脑算出这个表达式的结果很简单。但是计算机只认识简单的机器指令。那么我们怎么将这个”复杂”的表达式编译成更接近机器的语言呢?
实际上,编译器就是通过两个栈来实现的。其中一个保存操作数的栈,另一个是保存运算符的栈。我们从左向右遍历表达式,当遇到数字,我们就直接压入操作数栈;当遇到运算符,就与运算符栈的栈顶元素进行比较。
如果比运算符栈顶元素的优先级高,就将当前运算符压入栈;如果比运算符栈顶元素的优先级低或者相同,从运算符栈中取栈顶运算符,从操作数栈的栈顶取 2 个操作数,然后进行计算,再把计算完的结果压入操作数栈,继续比较。
具体代码如下:
package main
// TODO: practice/golang/main/stackCalculator.go