pointer计数指针
pointer.h
#ifndef _pointer_h
#define _pointer_h
template<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)=
....
如果有语法错误,会终止