上一个计算器有bug,还是用语法制导的方法计算表达式,这个没有bug,用的是LL(1)表达式文法,以=号结束
来源:互联网 发布:免费玻璃排版软件 编辑:程序博客网 时间:2024/06/05 00:21
pointer计数指针
pointer.h
#ifndef _pointer_h#define _pointer_htemplate<class T> class pointer { public: pointer():ptr(NULL),pCnt(new int(0)){} pointer(T* src):ptr(src),pCnt(new int(1)) { } pointer(const pointer<T>& src):ptr(src.ptr),pCnt(src.pCnt) { ++(*pCnt); } pointer<T>& operator=(const pointer<T>& rhs) { if(ptr != rhs.ptr) { Release(); ptr = rhs.ptr; pCnt = rhs.pCnt; ++*pCnt; } return (*this); } T* operator->() { return ptr; } const T* operator->()const { return ptr; } T& operator*() { return (*ptr); } const T& operator*()const { return (*ptr); } ~pointer() { Release(); } public: T* ptr; int *pCnt; void Release() { if(--*pCnt == 0) { delete ptr; delete pCnt; } } }; #endif
表达式节点有两种,符号节点和数字节点
express_node.h
#ifndef _express_node_h#define _express_node_h #include<iostream>using std::cout; class node{public: node(){} virtual float getNum(){return -1;} virtual char getChar(){return '#';} virtual ~node(){ //cout<<"~node\n"; //system("pause"); } }; class char_node:public node{ char sym;public: char_node(char c):sym(c){} void setChar(char c){sym=c;} virtual char getChar(){return sym;} virtual ~char_node(){ //cout<<"~char_node\n"; //system("pause"); }}; class num_node:public node{ float num;public: num_node(float n):num(n){} void setNum(float n){num=n;} virtual float getNum(){return num;} virtual ~num_node(){ //cout<<"~num_node\n"; //system("pause"); }}; #endif
主函数
main.cpp
#include<vector>#include<memory> #include<stack> #include<iostream> #include"express_node.h"#include"pointer.h" using namespace std;void E();void Ts();void T();void Ps();void P(); void error(){ cout<<"语法错误\n"<<endl;system("pause");exit(1); } bool isNum(pointer<node> a){ return dynamic_cast<num_node*>(&(*a))!=NULL;} bool isChar(pointer<node> a){ return dynamic_cast<char_node*>(&(*a))!=NULL; } void print1(node* a){ if(dynamic_cast<char_node*>(a)!=NULL){ cout<<dynamic_cast<char_node*>(a)->getChar()<<endl; } else{ cout<<dynamic_cast<num_node*>(a)->getNum()<<endl; } } void print2(node& a){ if(dynamic_cast<char_node*>(&a)!=NULL){ cout<<dynamic_cast<char_node*>(&a)->getChar()<<endl; } else{ cout<<dynamic_cast<num_node*>(&a)->getNum()<<endl; } } void print4(pointer<node>& a){ if(dynamic_cast<char_node*>(&(*a))!=NULL){ cout<<dynamic_cast<char_node*>(&(*a))->getChar()<<endl; } else{ cout<<dynamic_cast<num_node*>(&(*a))->getNum()<<endl; } } vector<pointer<node> > v;vector<pointer<node> >::iterator current;stack<float> s; void GenCode(char c){ //cout<<"生成中间代码\n"; float p1=s.top();s.pop();//cout<<"弹出"<<p1<<endl; float p2=s.top();s.pop();//cout<<"弹出"<<p2<<endl; switch(c){ case '+': s.push(p2+p1); //cout<<"相加 "; //cout<<"压入"<<p1+p2<<endl; break; case '-': s.push(p2-p1); //cout<<"相减 "; //cout<<"压入"<<p2-p1<<endl; break; case '*': s.push(p2*p1); //cout<<"相乘 "; //cout<<"压入"<<p1*p2<<endl; break; case '/': s.push(p2/p1); //cout<<"相除 "; //cout<<"压入"<<p2/p1<<endl; break; } } void match(char c){ //cout<<"match(char)\n"; //system("pause"); if(isChar(*current)){ if((*current)->getChar()==c){ //cout<<"匹配"<<c<<endl; current++; return; } else{ //cout<<((*current)->getChar())<<"不匹配"<<endl; error(); } } else{ error(); } } void E(){ //cout<<"E()\n"; if(isChar(*current)){ //system("pause");cout<<"当前值为字符\n"; if((*current)->getChar()=='('){ //cout<<"当前值为字符'('\n"; T();Ts(); } else{error();} } else{ if(isNum(*current)){ //system("pause");cout<<"当前值为数字\n"; T();Ts(); } else{ error(); } } //cout<<"退出E()\n"; } void Ts(){ //cout<<"Ts()\n"; if(isChar(*current)){ //system("pause");cout<<"当前值为字符\n"; if((*current)->getChar()=='#' || (*current)->getChar()==')'){ //cout<<"当前值为字符#或)\n"; } else{ if((*current)->getChar()=='+'){match('+');T();GenCode('+');Ts();} else{ if((*current)->getChar()=='-'){ match('-');T();GenCode('-');Ts(); } else{ error(); } } } } else{ error(); } //cout<<"退出Ts()\n"; } void T(){ //cout<<"T()\n"; if(isChar(*current)){ //system("pause");cout<<"当前值为字符\n"; if((*current)->getChar()=='('){P();Ps();} else{error();} } else{ if(isNum(*current)){ //system("pause");cout<<"当前值为数字\n"; P();Ps(); } else{error();} } //cout<<"退出T()\n"; } void Ps(){ //cout<<"Ps()\n"; if(isChar(*current)){ //system("pause");cout<<"当前值为字符\n"; if((*current)->getChar()=='+' || (*current)->getChar()=='-' || (*current)->getChar()=='#' || (*current)->getChar()==')'){ //cout<<"当前值为字符+或-或#或)\n"; } else{ if((*current)->getChar()=='*'){match('*');P();GenCode('*');Ps();} else{ if((*current)->getChar()=='/'){match('/');P();GenCode('/');Ps();} else{error();} } } } else{error();} //cout<<"退出Ps()\n"; } void P(){ //cout<<"P()\n"; if(isNum(*current)){ //system("pause");cout<<"当前值为数字\n"; s.push((*current)->getNum()); //cout<<"压入"<<((*current)->getNum())<<endl; current++; } else{ if(isChar(*current)){ //system("pause");cout<<"当前值为字符\n"; if((*current)->getChar()=='('){match('(');E();match(')');} else{error();} } } //cout<<"退出P()\n"; } int main(){ //while(1){ //while(!s.empty()){s.pop();} //while(v.size()!=0){v.clear();} string str; cin>>str;//输入字符串,以#号结束 //如 (1+3)*(2-4/1)# //如 (-0.3)*(2+2)# if(str.at(0)=='+' || str.at(0)=='-'){str="0"+str;} int pos=0; while((pos=str.find('+',pos))!=string::npos && str.at(pos-1)!=')'){ if(!isdigit(str.at(pos-1))){ str.insert(pos,"0");pos+=1; } pos++; } pos=0; while((pos=str.find('-',pos))!=string::npos && str.at(pos-1)!=')'){ if(!isdigit(str.at(pos-1))){str.insert(pos,"0");pos+=1;} pos++; } //cout<<"processed :"<<str<<endl; const char* iter=str.c_str(); iter=str.c_str(); while(*iter!='\0'){ if(*iter=='+' || *iter=='-' || *iter=='*' || *iter=='/' || *iter=='=' || *iter=='(' || *iter==')'){ if(*iter=='='){v.push_back(pointer<node>(new char_node('#')));} else{ v.push_back(pointer<node>(new char_node(*iter))); } iter++; } else{ float f=atof(iter); v.push_back(pointer<node>(new num_node(f))); while((*iter>='0' && *iter<='9') || *iter=='.'){iter++;} } } //cout<<"total parts : "<<v.size()<<endl; //for_each(v.begin(),v.end(),print4); current=v.begin(); E(); match('#'); if(!s.empty()){cout<<s.top()<<endl;} //char c; //cout<<"继续?y/n\n";cin>>c;if(c=='n')break; //} system("pause");}用的是表达式文法
E -> T Ts
Ts -> null
Ts -> +T Ts
Ts -> -T Ts
T -> P Ps
Ps -> null
Ps -> * P Ps
Ps -> / P Ps
P -> C
P -> (E)
程序中输入如
(9-2)/2=
(-3)/(4-2)=
....
如果有语法错误,会终止
- 上一个计算器有bug,还是用语法制导的方法计算表达式,这个没有bug,用的是LL(1)表达式文法,以=号结束
- 基于LL(1)文法实现的简单计算器
- TortoiseSVN还是有Bug的
- 一个基于LL(1)的简易C++四则表达式计算
- LL(1)文法代码(有一定的纠错能力)
- 基于文法分析的表达式计算器的实现
- 是Bug,还是Bug?
- 这个是eXosip 的BUG吗?!!!
- 自顶向下语法分析方法:LL(1)文法的判别
- 用C# WinForm写的一个简单的计算器程序(可以输入复杂的表达式),欢迎大家指出Bug
- 是mysql的bug还是个别现象?
- iOS 11计算器1+2+3=24真的是bug么?
- 关于iBatis中的错误提示(必须以> 或 />结尾,有时并不是你的结尾没有以 />结束,而是这个标签里面有问题!!)(更重要的是sqlMap的修改手段!!!)
- LL(1)的一个文法分析
- LL(1)文法的判别[00原创]
- 是不是所有的文法都可以化为LL(1)文法?
- jdk正则表达式的一些BUG
- EL表达式fn:endsWith函数的bug
- 发送邮件编程原理
- 数据库大作业
- HTML Application
- Java数据库设计14个技巧
- Java常用术语解释
- 上一个计算器有bug,还是用语法制导的方法计算表达式,这个没有bug,用的是LL(1)表达式文法,以=号结束
- 两个数组a[n],b[n]重新排列后,两数组的和的差最小
- [JAVA]使用Eclipse从下载到编写一个实例全过程
- VS2008 VS2010发布网站时如何产生固定命名的 Dll 文件
- 【并查集】食物链
- 新一代搜索引擎WolframAlpha
- MFC DllMain
- LFS(3)
- 【并查集】冗余关系