您的位置:首页 > 编程语言 > C语言/C++

反向LL(1)预测分析法的简易C++四则表达式计算

2014-04-07 01:32 423 查看
上一篇文章 http://blog.csdn.net/memonoj/article/details/23054439

描述了一个LL(1)的计算器,但实际上它包含着很多的问题。

LL(1)是从左向右读取的,左叶优先推导的分析方法。

作为一个LL(1)分析器,很容易得知的是,最左边的符号最早读,最早出来开始推导,而最后被归纳回S。

LL(1)分析器中,在语法树的同一路径上,越早被读入的内容越早被推导(越晚被归纳)。

而我们正常的四则运算顺序,是从左到右归纳的,例如4*3/2中,乘法会比除法早。

所以说,完成四则计算需要我们将LL(1)的归纳反过来。从右边向左读取,从语法树右叶开始归纳。

于是,便有了这篇《反向LL(1)预测分析法》,实质上就是RR(1)预测分析。

/**
*
* ====================================================
* Introduce:
* ----------------------------------------------------
*  A reverse predictive analysis compiler
*  Using RR(1) predictive analysis method
*
* ====================================================
* Grammar Define:
* ----------------------------------------------------
* Start:
*  exp -> low
*  low -> med | low + med | low - med
*  med -> top | med * top | med / top
*  top -> num | ( low )
* ====================================================
*
*/

#include"iostream"
#include"assert.h"

int low(char*&);
int med(char*&);
int top(char*&);
int num(char*&);

// low -> med | low + med | low - med
int low(char*&p){
int second = med(p);
if(*p=='+'){
return low(--p)+second;
}else if (*p=='-'){
return low(--p)-second;
}else{ // if there is no + or -
return second;
}
}

// med -> top | med * top | med / top
int med(char*&p){
int second = top(p);
if (*p=='/'){
return med(--p)/second;
}else if(*p=='*'){
return med(--p)*second;
}else{ // if there is no /
return second;
}
}

// top ->  num | ( low )
int top(char*&p){
// find the last '(' and replace it with '\0' ,
// and then return the value of low between '(' and ')'
if(*p==')'){

char *pLeft=NULL; // to hold the last ')'
char *pLowStart=p-1; // to show where 'low' start

// get the last '('
for(char*pTemp=pLowStart;*pTemp!='\0';pTemp--){
if(*pTemp=='(') pLeft=pTemp;
}

if(pLeft==NULL) {
assert("Operator '(' Not Found");
}else{
*pLeft='\0';
p=--pLeft;
}

return low(pLowStart);

}else{ // return the number if there is no '('
return num(p);
}
}

int num(char*&p){
int num = 0;
int base = 1;
while( *p>='0' && *p<='9' ){ // digit remains
num+=(*p-'0')*base;
base*=10;
p--;
}
return num;
}

using namespace std;
#define EXP_LEN 127

int main(){
char *exp=new char[EXP_LEN]+1;
exp[0]=0;
while(1){
cin.getline(&exp[1],EXP_LEN);
char *pLast= &exp[ strlen(&exp[1]) ];
cout<<low(pLast)<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息