图 8.8 逆波兰表示
程序设计语言中的表示 逆波兰表示
a+b
a+b*c
(a+b)*c
a;=b*c+b*d
ab+
abc*+
ab+c*
abc*bd*+:=
  后缀表示法表示表达式,其最大的优点是易于计算机处理表达式。常用的算法是使用一个栈,自左至右扫描算术表达式(后缀表示),每扫描到运算对象,就把它推进栈;扫描到运算符,若该运算符是二目的,则对栈顶部的两个运算对象实施该运算,并将运算结果代替这两个运算对象而进栈;若是一目运算符,则对栈顶元素执行该运算,并以运算结果代替该元素进栈,最后的结果留在栈顶。
  例如 B@CD*+(它的中缀表示为-B+C*D,使用@表示一目减)的计值过程为:
  1. B进栈;
  2. 对栈顶元素施行一目减运算,并将结果代替栈顶,即-B置于栈顶;
  3. C进栈;
  4. D进栈;
  5. 栈顶两元素相乘,两元素退栈,相乘结果置栈顶;
  6. 栈顶两元素相加,两元素退栈,相加结果进栈,现在栈顶存放的是整个表达式的值。
  由于后缀式表示上的简洁和计值的方便,特别适用于解释执行的程序设计语言的中间表示,也方便具有堆栈体系的计算机的目标代码生成。
  逆波兰表示很容易扩充到表达式以外的范围。在图8.8中已见到了赋值语句的后缀表示的例子。只要遵守运算对象后直接紧跟它们的运算符的规则即可。比如把转语句GOTO L写为"L jump",运算对象L为语句标号,运算符jump表示转到某个标号。再比如条件语句if E then S1 else S2可表示为:ES1S2¥,把if then else看成三目运算符,用¥来表示。又如数组元素A[〈下标表达式1〉,…〈下标表达式n〉]可表示为〈下标表达式1〉〈下标表达式2〉……〈下标表达式n〉A subs,运算符Subs表示求数组的下标。
  当然,这些扩充的后缀表示的计值远比后缀表达式的计值复杂得多,要注意对新添加的运算符的含义正确处理。以图8.8中的赋值语句为例,当计算到∶=时,执行的是将表达式B*C+B*D的值送到变量a,所以,而在执行完赋值后,栈中并不产生结果值,这与算术的二目运算符是不一样的,另外,因为需要的是a的地址,而不是a的值,这也必须注意到。