#include <iostream.h>
#include <fstream.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
const long stakmaxsize=6000;
int flag;
const char keyword[][20]={{'i','n','t'},{'v','o','i','d'},{'i','f'},
{'c','h','a','r'},{'b','o','o','l'},{'b','r','e','a','k'},{'c','a','s','e'},
{'c','a','t','c','h'},{'c','o','n','s','t'},{'f','o','r'},{'e','l','s','e'},
{'c','o','n','t','i','n','u','e'},{'c','l','a','s','s'},{'w','h','i','l','e'},
{'d','o'},{'g','o','t','o'},{'f','l','o','a','t'},{'d','o','u','b','l','e'},
{'l','o','n','g'},{'s','w','i','t','c','h'},{'f','r','i','e','n','d'},{'s','t','a','t','i','c'},
{'p','u','b','l','i','c'},{'p','r','i','v','a','t','e'},{'p','r','o','t','e','c','t','e','d'},
{'r','e','t','u','r','n'},{'i','n','l','i','n','e'},{'t','r','y'},{'s','t','r','u','c','t'}};
char Ischeck[]={' ','\n','+','-','*','(',')','{','}',
';','=','\"',',','&','[',']','!',':','<','>','\'','/'};
bool isCheck(const char& ch)
{
for(int i=0;i<27;i++)
if(ch==Ischeck[i]) return true;
return false;
}
struct stack
{
char stak[stakmaxsize];
int top;};
void initstak(stack& s)
{s.top=-1;}
void clearstak(stack& s)
{s.top=-1;}
void push(stack& s,const char& item)
{if(s.top==stakmaxsize-1)
{
cerr<<"溢出"<<endl;
exit(1);}
s.top++;
s.stak[s.top]=item;
}
bool isKeyword(stack& s)
{
for(int i=0;i<29;i++)
if(!strcmp(s.stak,keyword[i]))
return true;
return false;
}
void printout(stack& s)
{
if(isKeyword(s))
cout<<"关键字:"<<s.stak<<endl;
else
cout<<"标识符:"<<s.stak<<endl;
}
void digitpush(stack& s,const char& item)
{
if(s.top==stakmaxsize-1)
{cerr<<"溢出"<<endl;
exit(1);}
s.top++;
s.stak[s.top]=item;
}
void Getchar(FILE *fp,char& ch)
{
ch=fgetc(fp);
if(ch=='\n')
flag++;
}
void digitprint(stack& s)
{cout<<"数:"<<s.stak<<endl;}
void check(char *fname)
{ FILE *fp;
bool watch=false,checked=true;
flag=1;
if((fp=fopen(fname,"r"))==NULL)
{cerr<<"文件"<<"\'"<<fname<<"\'"<<"找不到"<<endl;
getchar();
exit(1);}
stack a;
initstak(a);
char ch;
Getchar(fp,ch);
while(!feof(fp))
{if(ch==' '||ch=='\n')
{Getchar(fp,ch);
checked=true;
continue;}
else
if(checked && (isalpha(ch)||ch=='_'))//判断是否为字母,是字母返回1,否则返回0,checked查看上次有没有输入错误。
{
while(isalnum(ch)||ch=='_')//判断是否是字母和数字的组成,是返回1,否则返回0
{ if(isCheck(ch))
break;
push(a,ch);
Getchar(fp,ch);
if(feof(fp))
{push(a,'\0');
printout(a);
fclose(fp);
getchar();
exit(0);
}
}
if(isCheck(ch))
{
push(a,'\0');
printout(a);
clearstak(a);
}
else
{
cout<<"错误位置"<<flag<<endl;
checked=false;
clearstak(a);
continue;
}
}
else
if(isdigit(ch) && checked)//判断是否为数字。是返回1,否则返回0,checked表示检查上次输入有没有错误
{
while(isdigit(ch)||ch=='.')
{if(ch=='.')
watch=true;
if(isCheck(ch))
break;
digitpush(a,ch);
Getchar(fp,ch);
if(feof(fp))
{digitprint(a);
fclose(fp);
getchar();
exit(0);}
}
if(isCheck(ch))
{
if(watch)
{
cout<<"";
watch=false;
digitpush(a,'\0');
digitprint(a);
clearstak(a);
}
else
{
cout<<"整形";
digitpush(a,'\0');
digitprint(a);
clearstak(a);
}
}
else
{
cout<<"错误位置"<<flag<<endl;
checked=false;
clearstak(a);
continue;
}
}
else if(checked)
{
switch(ch)
{
case'=': Getchar(fp,ch);
if(ch=='=')
{
cout<<"算符 "<<"=="<<endl;
Getchar(fp,ch);
checked=true; break;}
else
{
cout<<"算符 "<<"="<<endl;
checked=true;break;}
case'+': Getchar(fp,ch);
if(ch=='=')
{cout<<"算符 "<<"+="<<endl;
Getchar(fp,ch);
checked=true;break;}
else
if(ch=='+')
{cout<<"算符 "<<"++"<<endl;
Getchar(fp,ch);checked=true;break;}
else
{cout<<"算符 "<<"+"<<endl;
checked=true;break;}
case'*': Getchar(fp,ch);
if(ch=='=')
{cout<<"算符 "<<"*="<<endl;
Getchar(fp,ch);checked=true;break;}
else
{cout<<"算符 "<<"*"<<endl;
checked=true;break;}
case'/': cout<<"算符:"<<"/"<<endl;
Getchar(fp,ch);checked=true;break;
case'-': Getchar(fp,ch);
if(ch=='=')
{cout<<"算符 "<<"-="<<endl;
Getchar(fp,ch);checked=true;break;}
else
if(ch=='-')
{cout<<"算符 "<<"--"<<endl;
Getchar(fp,ch);
checked=true;break;}
else
{cout<<"算符 "<<"-"<<endl;
checked=true;break;}
case'!': Getchar(fp,ch);
if(ch=='=')
{cout<<"算符 "<<"!="<<endl;
Getchar(fp,ch);checked=true;break;}
else
{cout<<"算符 "<<"!"<<endl;
checked=true;break;}
case'>': Getchar(fp,ch);
if(ch=='=')
{cout<<"算符 "<<">="<<endl;
Getchar(fp,ch);checked=true;break;}
else
{cout<<"算符 "<<">"<<endl;
checked=true;break;}
case'<': Getchar(fp,ch);
if(ch=='=')
{cout<<"算符 "<<"<="<<endl;
Getchar(fp,ch);checked=true;break;}
else
{cout<<"算符 "<<">"<<endl;
checked=true;break;}
case'(':cout<<"边界符"<<"("<<endl;Getchar(fp,ch);checked=true;break;
case')':cout<<"边界符"<<")"<<endl;Getchar(fp,ch);checked=true;break;
case'{':cout<<"边界符"<<"{"<<endl;Getchar(fp,ch);checked=true;break;
case'[':cout<<"边界符"<<"["<<endl;Getchar(fp,ch);checked=true;break;
case'}':cout<<"边界符"<<"}"<<endl;Getchar(fp,ch);checked=true;break;
case']':cout<<"边界符"<<"]"<<endl;Getchar(fp,ch);checked=true;break;
case';':cout<<"边界符"<<";"<<endl;Getchar(fp,ch);checked=true;break;
case',':cout<<"边界符"<<","<<endl;Getchar(fp,ch);checked=true;break;
case'%':cout<<"算符"<<"%"<<endl;Getchar(fp,ch);checked=true;break;
case'#':cout<<"算符"<<"#"<<endl;Getchar(fp,ch);checked=true;break;
case'&':cout<<"算符"<<"&"<<endl;Getchar(fp,ch);checked=true;break;
case':':cout<<"算符"<<":"<<endl;Getchar(fp,ch);checked=true;break;
case'\'':cout<<"算符"<<"\'"<<endl;Getchar(fp,ch);checked=true;break;
case'\"':cout<<"算符"<<"\""<<endl;Getchar(fp,ch);checked=true;break;
case'\\': Getchar(fp,ch);
if(ch=='n')
{ cout<<"算符"<<"\\n"<<endl;
Getchar(fp,ch);checked=true;break;}
else
{cout<<"算符"<<"\\"<<endl;checked=true;break;}
case'\n':break;
case' ': break;
default: cout<<"错误在第"<<flag<<"行"<<endl;
checked=false;Getchar(fp,ch);
}
}
else Getchar(fp,ch);
}
if(feof(fp))
{
fclose(fp);
//getchar();
exit(1);
}
}
void main()
{
char filename[10];
cout<<"-------------------------------------------------------------------"<<endl;
cout<<"编译原理词法分析器程序,请正确输入你的文件名,注意文件格式,谢谢:)"<<endl;
cout<<"-------------------------------------------------------------------"<<endl;
cout<<"请输入文件名和路径 : ";
cin>>filename;
check(filename);
}