编译原理课程设计报告-----词法分析器篇
(根据C语言的部分词法构成规则)
1、 相关说明以及源代码
本程序实现对C语言进行词法分析,能够识别关键字、标识符、运算符号、标点符号、整形数字和浮点数,除此之外还能够识别词法错误。是可以作为一个编译原理课程的很好的参考价值,以及可以直接作为该课程的课程设计报告使用,如果在此功能上加如语法分析功能语义分析功能,就可以作为大学毕业设计论文。
//制作者:窦志刚
//制作工具:Microsoft Visual C++6.0
//制作日期:2004.4.26-2004.4.29
#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++;
if(feof(fp))
{
fclose(fp);
getchar();
exit(1);
}
}
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))
//判断是否为字母,是字母返回1,否则返回0,checked查看上次有没有输入错误。
{
while(isalnum(ch))
//判断是否是字母和数字的组成,是返回1,否则返回0
{ if(isCheck(ch))
break;
push(a,ch);
Getchar(fp,ch);
}
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(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);
}
}
void main()
{
char filename[10];
cout<<“-------------------------------------------------------------------”<<endl;
cout<<“编译原理词法分析器程序,请正确输入你的文件名,注意文件格式,谢谢:)”<<endl;
cout<<“-------------------------------------------------------------------”<<endl;
cout<<"请输入文件名和路径 : ";
cin>>filename;
check(filename);
}