一个基于LL(1)的简易C++四则表达式计算

来源:互联网 发布:mac保存书签 编辑:程序博客网 时间:2024/06/05 09:08

前一段时间去某机试考场玩,刚好遇到这道题。

当时不记得逆波兰符号法了,于是随手写了个LL(1)的,其实的确简易很多。

不过那时候还留了一个4*3/4=0的bug没解决,今天突然想起就顺便完善了一下。

后记 仔细看了一下之后发现这个*的优先级提高并不可行。看来LL就没办法解决这个问题了么?

再后记:正解:RR(1)预测分析法:http://blog.csdn.net/memonoj/article/details/23063147

//============================================================================// Name        : test.cpp// Author      : Memono// Version     : 0.1// Description : A LL(1) compiler for integer calculating expression//============================================================================/** * * This compiler uses LL(1) method to handle the integer * calculating expression. It is much simpler and much * easier to understand, to remember, and to realize, * comparing to the stack methods such as the * Inverse Poland Symbolic Method。 * * Remarkably, expressions of '*' & '/' are separated * in order to solve expresses like "4*3/4". The result * should be 3. Without this treatment, the result will * be 0, caused by an unexpected combination of "3/4". * This treatment arises the prior of operator '*' to * avoid this kind of combinations. * * ==================================================== * Grammar Define: * ==================================================== * Start: *  exp -> low *  low ->  med |  med + low | med - low *  med -> high | high / med * high ->  top |  top * high *  top ->  num | ( low ) * ==================================================== * */#include"iostream"#include"assert.h"int low(char*&);int med(char*&);int high(char*&);int top(char*&);int num(char*&);// low ->  med |  med + low | med - lowint low(char*&p){int first = med(p);if(*p=='+'){return first+low(++p);}else if (*p=='-'){return first-low(++p);}else{ // if there is no + or -return first;}}// med -> high | high / medint med(char*&p){int first = high(p);if (*p=='/'){return first/med(++p);}else{ // if there is no /return first;}}// high ->  top |  top * highint high(char*&p){int first = top(p);if(*p=='*'){return first*high(++p);}else{ // if there is no *return first;}}// 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 *pRight=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==')') pRight=pTemp;}if(pRight==NULL) {assert("Operator ')' Not Found");}else{*pRight='\0';p=++pRight;}return low(pLowStart);}else{ // return the number if there is no '('return num(p);}}int num(char*&p){int num = 0;while( *p>='0' && *p<='9' ){ // digit remainsnum*=10;num+=*p-'0';p++;}return num;}using namespace std;#define EXP_LEN 128int main(){char *exp=new char[EXP_LEN];while(1){cin.getline(exp,EXP_LEN);cout<<low(exp)<<endl;}}

0 0