//token.h
// token.h: interface for the Ctoken class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_TOKEN_H__877B901A_31EC_480B_888B_228676A239EF__INCLUDED_)
#define AFX_TOKEN_H__877B901A_31EC_480B_888B_228676A239EF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// extern char *oplist;
// extern char *allsplit;
#include<afx.h>
class Ctoken
{
public:
CString GetTokenLeft(LPCTSTR separate);
char split;//上次gettoken的分隔符
int Trimleft(LPCTSTR str);
int GetNextSection();
BOOL GetRP();
int GetOP(LPCTSTR op);
int CP;
char *_Line;
char *_Token;
int TOKENSIZE;
int LINECHAR;
BOOL quotword;
int GetToken(LPCTSTR separate,BOOL fullLRP=FALSE);
Ctoken();
virtual ~Ctoken();
};
#endif // !defined(AFX_TOKEN_H__877B901A_31EC_480B_888B_228676A239EF__INCLUDED_)
//token.cpp
// token.cpp: implementation of the Ctoken class.
//
//////////////////////////////////////////////////////////////////////
#include "token.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Ctoken::Ctoken()
{
TOKENSIZE=1024;
LINECHAR=8192;
CP=0;
_Line=0;
_Token=new char[TOKENSIZE];
split=0;
}
Ctoken::~Ctoken()
{
delete _Token;
}
// char *oplist="~!%^&*_+=-:<>/?|";
// char *allsplit="~!%^&*_+=-:<>/?| \t()[]";
int Ctoken::GetToken(LPCTSTR separate,BOOL fullLRP/*保持()完整*/)
{
split=0;
quotword=0;
int TmpCP;
int i;
char *pBeginStr,*pEndStr;
_Token[0]='\0' ;
while(((_Line[CP] ==' ' )|| (_Line[CP] =='\t')) && (CP < LINECHAR)) CP++ ;
if (CP >= LINECHAR) goto TokError ;
switch(_Line[CP]){
case '"' : // parsing string
pBeginStr=_Line+CP;
pEndStr=strchr(pBeginStr+1,'"');
if( pEndStr != NULL){
CP= pEndStr-_Line+1;
strncat(_Token,pBeginStr+1,pEndStr-pBeginStr-1);
quotword=1;
}
else
{
strcat(_Token,"\"");
CP++;
}
return 1;
break;
default:
break;
};
TmpCP=CP;
i=strlen(_Line);
{
int sl=strlen(separate);
BOOL bsl=0;
int lpcount=0;
while(1)
{
if(_Line[CP]==0)break;
if(fullLRP)
{
if(_Line[CP]=='(')
{
lpcount++;
}
else if(_Line[CP]==')')
{
lpcount--;
}
}
if(lpcount>0)
{
CP++;
continue;
}
bsl=_Line[CP] !=separate[0];
for(int sn=1;sn<sl;sn++)
{
bsl=bsl&&(_Line[CP] !=separate[sn]);
}
if(bsl&&(CP<i))
{
// if((_Line[CP]=='!') )
// break ;
// else
CP++ ;
}
else
{
split=_Line[CP];
break;
}
}
}
if (CP >= i) goto TokError ;
//if (CP >= LINECHAR) goto TokError ;
if((CP-TmpCP) >(TOKENSIZE-1))
{
strncat(_Token,&(_Line[TmpCP]),(TOKENSIZE-1));
CP++;
}
else
{
strncat(_Token,&(_Line[TmpCP]),(CP-TmpCP));
CP++;
}
return TRUE ;
TokError:
strcat(_Token,_Line+TmpCP); // error function
return FALSE ;
}
int Ctoken::GetOP(LPCTSTR op)
{
char*p=_Line+CP;
int oplen=strlen(op);
_Token[0]=0;
int l=0;
int bok=1;
while(*p)
{
bok=1;
for(int i=0;i<oplen;i++)
{
if(*p==op
)
{
_Token[l++]=*p;
bok=0;
break;
}
}
if(bok)
{
_Token[l]=0;
break;
}
p++;
}
_Token[l]=0;
CP=p-_Line;
return 1;
}
BOOL Ctoken::GetRP()
//取得匹配的右括号
{
int count=0;
int l=0;
_Token[0]=0;
while(_Line[CP])
{
if(_Line[CP]=='(')count++;
else if(_Line[CP]==')')count--;
_Token[l++]=_Line[CP];
if(count==-1)
{
_Token[l-1]=0;
CP++;
return 1;
}
CP++;
}
return 0;
}
int Ctoken::GetNextSection()
//取得下一个{}段
{
int count=0;
int l=0;
_Token[0]=0;
while(_Line[CP])
{
if(_Line[CP]==' '||_Line[CP]=='\t')CP++;
else break;
}
if(_Line[CP]!='{')
{
GetToken(";");
return 1;
}
while(_Line[CP])
{
if(_Line[CP]=='{')count++;
else if(_Line[CP]=='}')count--;
_Token[l++]=_Line[CP];
if(count==0)
{
_Token[l-1]=0;
CP++;
return 1;
}
else if(count==-1)return -1;
CP++;
}
return 0;
}
int Ctoken::Trimleft(LPCTSTR str)
{
int l=strlen(str);
BOOL bok=0;
while(_Line[CP])
{
bok=1;
for(int i=0;i<l;i++)
{
if(_Line[CP]==str)
{
CP++;
bok=0;
break;
}
}
if(bok)break;
}
return CP;
}
CString Ctoken::GetTokenLeft(LPCTSTR separate)
{
char*p=_Line+CP-1;
int l=strlen(separate);
while((*p==' '||*p=='\t')&&p>_Line)p--;
char*q=p;
while(q>=_Line)
{
for(int i=0;i<l;i++)
{
if(*q==separate)
{
CString re;
strncpy(re.GetBufferSetLength(p-q),q+1,p-q);
return re;
}
}
q--;
}
if(q<_Line&&CP>0)
{
CString re;
strncpy(re.GetBufferSetLength(CP),_Line,CP);
return re;
}
return "";
}
//cpp.cpp
// #define _DLL
// #define _AFXDLL
// #define _MT
#define _DLL
#define _AFXDLL
#define _MT
#include <afxtempl.h>
#include <stdio.h>
#include "token.h"
int pri(char c)
{
switch(c)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
}
return 0;
}
BOOL isop(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/')return 1;
return 0;
}
BOOL isnum(char*str)
{
int i=strlen(str);
if(i==0)return 0;
for(int j=0;j<i;j++)
{
if(!isdigit(str[j]))return 0;
}
return 1;
}
CStringList opstk;
CStringList valstk;
const char*toks="+-*/()";
void f(char*p)
{
int prepri=0;
CString str;
Ctoken tok;
tok._Line=p;
BOOL re;
while(1)
{
re=tok.GetToken(toks);
if(tok.split=='(')
{
prepri=0;
}
if(isnum(tok._Token))
{
printf("%s",tok._Token);
if(isop(tok.split))
{
int pr=pri(tok.split);
if(pr>prepri)
{
opstk.AddHead((CString)tok.split);
}
else
{
if(opstk.GetCount())printf("%s",opstk.RemoveHead());
}
prepri=pr;
}
else if(tok.split==')')
{
prepri=99999;
if(opstk.GetCount())printf("%s",opstk.RemoveHead());
}
}
else if(isop(tok.split))
{
opstk.AddHead(tok.split);
}
else if(tok.split==')')
{
prepri=99999;
if(opstk.GetCount())printf("%s",opstk.RemoveHead());
}
next:
if(!re)break;
}
while(opstk.GetCount())printf("%s",opstk.RemoveHead());
}
void main()
{
char*str="15*(((9+18)*(4*6))+7)";
f(str);
}