/*
* 程序功能:判断一字符串属于何种常量类型,浮点数、十进制整数、十六进制数
* 还是二进制数
* 实现原理:分别根据各种类型常量的特征码判断
* 作者: BUG_lauo
* 日期: 2009-7-1
*/
#include<iostream>
#include<string>
#include<list>
using namespace std;
enum CONSTANT_TYPE{DOUBLE,DECINT,HEXINT,BININT,ERRORKIND=-1};
CONSTANT_TYPE kind_of_var(string str)//识别是否为标准类型常量
{
int len=str.length();
if(len==0) return ERRORKIND;//长度为零,返回错误代码
for(int i=0;i<len;i++)
if(str[i]>='A'&&str[i]<='Z')
str[i]+='a'-'A';
if(len>=2&&str[0]=='0'&&str[1]=='x')//如果是十六进制数
{
if(len==2) return ERRORKIND;
for(int i=2;i<len;i++)
if(!(isdigit(unsigned char (str[i]))||str[i]<='f'&&str[i]>='a'))//如果不是数字或者a-f组成,则返回错误代码
return ERRORKIND;
return HEXINT;
}
else if(str[len-1]=='b')//如果是二进制常量
{
for(int i=0;i<len-1;i++)
if(!(str[i]=='0'||str[i]=='1'))
return ERRORKIND;//错误的二进制常量
return BININT;
}
else
{
int i=(str[0]=='-'?1:0);
for(;i<len;i++)
if(!isdigit(unsigned char(str[i]))) break;
if(i==len) return DECINT;//为标准的十进制整数
/*
以下将判断是否为正确的浮点数
*/
list<int> dot,e,sign;//.点号 e号 -号
int dot_num=0,e_num=0,sign_num=0;
for(i=0;i<len;i++)
switch(str[i])
{
case '.':dot_num++;dot.insert(dot.end(),i);break;
case 'e':e_num++;e.insert(e.end(),i);break;
case '-':sign_num++;sign.insert(sign.end(),i);break;
default: if(!isdigit(unsigned char(str[i]))) return ERRORKIND;
}
list<int>::iterator dot_i=dot.begin(),dot_end=dot.end();
list<int>::iterator e_i=e.begin(),e_end=e.end();
list<int>::iterator sign_i=sign.begin(),sign_end=sign.end();
if(e_num>=2) return ERRORKIND;//出现多个e
if(e_num==0)
{
if(sign_num>1||dot_num>1) return ERRORKIND;//如果在非科学计数法的情况下,出现多个. -则表明出错
if(sign_num==1&&(*sign_i)!=0) return ERRORKIND;//出现负号都不在首字符位置
return DOUBLE;//如果正确,则返回正确类型标识符
}
if(e_num==1)//存在e表明使用了科学计数法
{
if(sign_num>2||dot_num>=2) return ERRORKIND;//如果多于两个负号或者.号大于等于两个
if(sign_num==1&&((*sign_i)!=0&&(*sign_i)!=(*e_i)+1)) return ERRORKIND;//如果只有一个负号,应该出现在第一位,或者e之后
if(sign_num==2&&(*sign_i)!=0) return ERRORKIND;//如果出现两个负号,第一个负号却不在第一位,出错
if(sign_num==2&&(*sign_i)!=(*e_i)+1) return ERRORKIND;//第二个负号应该出现在e之后
if(dot_num==1&&(*dot_i)>(*e_i)) return ERRORKIND;//如果逗号出现在e之后,则表明出错
return DOUBLE;
}
}
return ERRORKIND;
}
string get_code(CONSTANT_TYPE k)
{
switch(k)
{
case ERRORKIND:return "error!";break;
case DOUBLE:return "double";break;
case DECINT:return "decint";break;
case BININT:return "binint";break;
case HEXINT:return "hexint";break;
}
}
int main()
{
cout<<get_code(kind_of_var("0x1000ef"))<<endl;
cout<<get_code(kind_of_var("013333b"))<<endl;
cout<<get_code(kind_of_var("01000111b"))<<endl;
cout<<get_code(kind_of_var(".333.e-10"))<<endl;
cout<<get_code(kind_of_var("3-4.333e-111"))<<endl;
cout<<get_code(kind_of_var(".333e-10"))<<endl;
cout<<get_code(kind_of_var("-1.333e1-3"))<<endl;
cout<<get_code(kind_of_var("1-3.333e-13"))<<endl;
cout<<get_code(kind_of_var("0xABCDEFZ"))<<endl;
cout<<get_code(kind_of_var("0XABCD10034"))<<endl;
cout<<get_code(kind_of_var("-19348589"))<<endl;
cout<<get_code(kind_of_var("-134e1000"))<<endl;
cout<<get_code(kind_of_var("-14abcd"))<<endl;
cout<<get_code(kind_of_var("-000000"))<<endl;
cout<<get_code(kind_of_var("-8374837-39489384"))<<endl;
cout<<get_code(kind_of_var("-8374837e-3941111114444"))<<endl;
}
/*
hexint
error!
binint
error!
error!
double
error!
error!
error!
hexint
decint
double
error!
decint
error!
double
*/
if(sign_i!=sign_end) sign_i++;