表达式求值算法
算符优先法:
根据这个运算优先关系的规定来实现对表达式的编译或解释执行的。
算数四则运算规则:
先乘除,后加减;,
从左算到右;
先括号内,后括号外;
任何一个表达式都是由操作数、运算符和界限符组成的,称之为单词。其中运算符和界限符统称为算符
算符间的优先关系
+ | - | * | / | ( | ) | # | |
---|---|---|---|---|---|---|---|
+ | > | > | < | < | < | > | > |
- | > | > | < | < | < | > | > |
* | > | > | > | > | < | > | > |
/ | > | > | > | > | < | > | > |
( | < | < | < | < | < | = | |
) | > | > | > | > | > | > | |
# | < | < | < | < | < | = |
为了实现算符优先算法,可以使用两个工作栈。一个称为OPTR,用以寄存运算符;另外一个称做OPND,用以寄存操作数或运算结果;
算法的基本思想如下:
首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;
依次读入表达式中的每一个字符,若是操作数则进入OPND栈,若是运算符和OPTR栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕。(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。
求值过程:
OperandType EvaluateExpression(){
//算数表达式求值的算符优先算法。
//设OPTR和OPND分别为运算符栈和运算数栈。
//OP为运算符集合
InitStack (OPTR);
Push(OPTR,'#');
InitStack(OPND);
c=getchar();
while(c!='#' || GetTop(OPTR)!='#'){
if(!In(c,OP)){
Push(OPND,c);
c=getchar();
}else{
switch(Precede(GetTop(OPTR),c)){
case '<'://栈顶元素优先权低
Push(OPTR,c);
c=getchar();
break;
case '='://脱括号并接收下一字符
Pop(OPTR,x);
c=getchar();
break;
case '>'://退栈并将运算结果入栈
Pop(OPTR,theta);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,Operate(a,ttheta,b));
break;
}//switch
}
}//while
return GetTop(OPND);
}//EvaluateExpression
其中,Precede函数是判定运算符栈的栈顶运算符与读入的运算符之间优先关系的函数;
Operate是进行二元运算的函数,如果是编译表达式,则产生这个运算的一组相应指令并返回存放结果的中间变量;如果是解释执行表达式,则直接进行该运算,并返回运算结果。