Reverse Polish Expression in Compilation Principle (Flow of Operation Variables in Data Flow Diagram)

Expressions are generally composed of operands and operators. For example, in arithmetic expressions, the operator is usually placed in the middle of the two operands.
This is called an Infix Expression, like A+B.
Another mathematical notation was proposed by Polish mathematician Jan Lukasiewicz, which has two representations:
Write the operator before the operand, called Polish Expression (Polish Expression) or prefix expression (Prefix Expression), such as +AB;
Writing the operator after the operand is called a Reverse Polish Expression or a Suffix Expression, such as AB+;

Among them, Reverse Polish expressions are widely used in compilation technology.


algorithm:
1. Convert an infix expression to a postfix expression algorithm:
1. Scan an infix expression from left to right.
2. If the operand is read, judge the type of the operand and store the operand into the operand stack
3. If the operator is read
  (1)  If the operator is left parenthesis "(", it is directly stored in the operator stack.
  (2) If the operator is a closing bracket ")", the operator in the operator stack is output to the operand stack until the opening bracket is encountered.
  (3) The operator is a non-bracket operator:
      (a) If the operator at the top of the operator stack is a parenthesis, it is directly stored in the operator stack.
      (b) If the precedence is higher than or equal to the operator at the top of the operator stack, it is directly stored in the operator stack.
      (c) If the precedence of the operator is lower than the operator at the top of the operator stack, output the operator at the top of the stack to the operand stack and push the current operator onto the operator stack.
4. When there are still operators in the operator stack after the expression is read, the operators are sequentially taken out to the operand stack until the operator stack is empty.

The so-called standard expressions such as "A+B", which are mathematically called infix expressions (Infix Notation), are due to:

The operator symbol is in the middle of two operands .

      Its advantage: it  is only: with two simple operations, stacking and popping, the operation of any ordinary expression (expressions containing only: +-*/ and ()) can be done .

      Its basic operation method  : if the current character is a variable or a number, it will be pushed onto the stack; if it is an operator, the two elements on the top of the stack will be popped for the corresponding operation, and the result will be pushed into the stack. is the result.

      Why is it said that the reverse Polish formula is efficient for generating machine codes : Because the reverse Polish formula is very easy to process by a computer. The reason is this. Example:

     3 32 + 5 3 * -
  12 34 2 - * 8 /
  The above two equations seem strange at first glance, don't they? They are a notation for expressions - reverse Polish expressions.
  Now, prepare a very narrow cylinder with a bottom (actually a stack). Make a few more circular pieces of paper, and write "3", "32", "+", "5", "3", "*", and "-" on the pieces of paper in turn. Remember, each piece of paper is either written with only one number, or Just write a single operator and put them in the order above. Okay, now listen to me carefully, pick up the small circular pieces of paper one by one in order, and repeat the following rules:
  1. If you are holding a number, don't say much, just put it directly into the cylinder ;
  2. If you're holding an operator, don't put it in. First take two numbers from the cylinder (of course, the top one is taken first, the cylinder is very thin), then perform the operation specified by the operation symbol on these two numbers, and write the result on a new piece of paper, and then Put it in the barrel. For example, if you are holding a "+", you need to take out "32" and "3" in turn, add them to get "35", and write "35" on a new piece of paper (now "34" and "35" 12" can be thrown away), and put this new piece of paper into the cylinder.
  You can stop when there is only one number in the cylinder, which I guess is 20, and yes, that's the value of the expression!
  What we have just manipulated is actually a "stack". A stack is a data structure with one property - LIFO - Last Input First Output. You can only take from the top, and when you put it, you can only put it on the top. The action of putting in is called "pushing", and taking out is called "popping". Later, you can think of the stack as a stack of plates, or the small cylinders and small pieces of paper mentioned above, the stack is that simple!
  Although the reverse Polish expression looks cumbersome, it is actually very useful in computers. Computers don't know how to multiply and divide before adding and subtracting, first inside parentheses and then outside parentheses, it will turn the expression you input into a reverse Polish expression, and it can continuously execute the above two fixed rules until it calculates the result and tells you. , the compiler reads the reverse Polish expression in the order from left to right during processing, and directly pushes the operand into the stack when encountering the operator. When the operator encounters the operator, it extracts the next two objects from the stack for calculation. This process is exactly in line with Principles of Computer Computing. Therefore, the reverse Polish method is very suitable for computer processing.


      An algorithm to convert an infix expression into a reverse Polish algorithm :  Combined with a specific example, the analysis is as follows:

a) give an infix expression 1*(2+3)

 

b) The system first defines two first-in-last-out stacks: operation symbol stack (referred to as push in), and postfix expression output symbol stack (referred to as out of stack)

 

c) The system reads infix expressions from left to right

 

d) Read the number and push it directly into the stack (out)

 

e) Read the first operator and push it directly onto the stack (in)

 

f) Read in "(" and directly push it into the stack (in).  After reading several times according to the above rules, if the data of the two stacks are: in [*,( ] ; out [1,2], start reads the second operator "+" and compares it with the top- of-stack operator "(" in the push (in),

g) Operators at the operator level higher than the top of the stack are directly pushed into the stack, and those lower than or equal to the top of the stack should be pushed (in) and unstacked (ie, popped), and pushed into the stack (out) one by one .


f)最后读取")"时要找到入栈in中最近的"(",将其前面所有符号全部按后进先出的顺序压入出栈,并解压,"("与")"抵消。此时两栈的数据为:in 1,2,3,+ ; out *

 

g)系统读取中缀表达式结束后将入栈in中的所有符号按后进先出的顺序全部解压,并依次压入出栈out中,最后出栈的结果就应该为1,2,3,+,*

 

h)按先进先出的顺序将出栈out解压得到后缀标准表达式1,2,3,+,*

 

两个堆栈先后数据情况:

In

out

 

1

*

1

*,(

1

*,(

1,2

*,(,+

1,2

*,(,+

1,2,3

*

1,2,3,+

 

1,2,3,+,*

 

将中缀表达式转换成逆波兰表达式过程中,特别要注意对于中缀标到式中括号的处理

1、要注意的,如果算符是"(",无论入栈中栈顶级别(只看栈顶)为何直接入栈,所以,“(”的等级

    只用于对其后入栈的算符进行优先级比较,在“(”入栈时是无视优先级的。(博主强烈提醒!!!!!!!!!!!!!!!!!!!)

2、在遇到")"时候找到最后进入的"(",并把"("前面所有的符号都压入出栈。不能仅凭运算符的级别来判断。


将一个 逆波兰式 倒转回 中缀表达式 的算法:

   这个就相当简单了,就是一个机械的入堆栈出堆栈的操作,

1)设置一个堆栈,将逆波兰式从左到右开始进行出入堆栈操作,还以上例为例:1,2,3,+,*

2)遇到数字直接压栈;例如,上例逆波兰先进行三次入栈操作,堆栈的格局是: 1,2,3(栈顶);

3)遇到算符,将堆栈中的两个数字出栈。 如,读到+号后,2,3出栈,进行运算。注意,出栈时先出栈的元素是右算子,后出栈的是左算子,上例是2+3,不是3+2;

4)将运算的结果作为新的算子,压入堆栈中。如运算结果(2+3)入栈,堆栈格局:1,(2+3);

5)反复1-4的操作,得到的中序表达式就是: 1*(2+3);

   中序表式生成的逆波兰式唯一吗?:

是唯一的,和固定形式的中序表达式一一对应,但,请注意这个概念,

例如: a+(b-c)*d 和 (b-c)*d+a 和 a+d*(b-c) 的是完全一样的。但是,他们的中序形式不同,

产生的逆波兰式必然是不同的。

      a+(b-c)*d : abc-d*+

      (b-c)*d+a :   bc-d*a+

      a+d*(b-c) : adbc-*+

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326355766&siteId=291194637