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

来源:互联网 发布:e4a连接数据库 编辑:程序博客网 时间:2024/06/05 00:07

上一篇文章 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 - medint 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 / topint 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 remainsnum+=(*p-'0')*base;base*=10;p--;}return num;}using namespace std;#define EXP_LEN 127int 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;}}
0 0