P139,程序5-4
利用递归解析前缀表达式
小Tips:前缀表达式、中缀表达式、后缀表达式
普通的计算机表达式就是中缀表达式,操作数在两侧,操作符在中间,例如
(a+b)∗(c+d)
前缀表达式和后缀表达式是编译器中常用的中间转换模式,由波兰数学家J.Lukasiewicz发明,也称为波兰式和逆波兰式。前缀表达式的操作符在前面,后面为两个操作数,例如
∗+ab+cd
,后缀表达式则刚刚相反,例如
ab+cd+∗
。前缀表达式很容易用递归写词法分析。
int eval()
{
if(sz[pos] == ' ') ++ pos;
if(sz[pos] == '+')
{
++ pos;
return eval() + eval();
}
if(sz[pos] == '*')
{
++ pos;
return eval() * eval();
}
int ret = 0;
while(sz[pos] >= '0' && sz[pos] <= '9')
{
ret = ret * 10 + sz[pos] - '0';
++ pos;
}
return ret;
}
倒过来的后缀表达式写法:
int suffix()
{
if(sz[pos] == ' ') -- pos;
if(sz[pos] == '+')
{
-- pos;
return suffix() + suffix();
}
if(sz[pos] == '*')
{
-- pos;
return suffix() * suffix();
}
int ret = 0, mul = 1;
while(sz[pos] >= '0' && sz[pos] <= '9')
{
ret += mul * (sz[pos] - '0');
mul *= 10;
-- pos;
}
return ret;
}
当然,后/中缀表达式还能这么写:
int dig()
{
int ret = 0;
while(sz[pos] >= '0' && sz[pos] <= '9')
{
ret = ret * 10 + sz[pos ++] - '0';
}
return ret;
}
int term()
{
if(sz[pos] >= '0' && sz[pos] <= '9')
return dig();
++ pos; // read (
int op0 = term();
char op = sz[pos ++];
int op1 = term();
++ pos; // read )
if(op == '+')
return op0 + op1;
else
{
return op0 * op1;
}
}