编译原理课程设计报告-----词法分析器篇

编译原理课程设计报告-----词法分析器篇
(根据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);
}

这是我现在在大学学习编译原理时的一个’词法分析器’的实践报告,本程序实现对C语言进行词法分析,能够识别关键字、标识符、运算符号、标点符号、整形数字和浮点数,除此之外还能够识别词法错误。是可以作为一个编译原理课程的很好的参考价值,以及可以直接作为该课程的课程设计报告使用,如果在此功能上加如语法分析功能语义分析功能,就可以作为大学毕业设计论文。

本人从构思到上机调试共用了4天的时间,在这四天里我体验到,编程是一种能力,但调试能力也是一个很重要的能力,愿学习编程的人从中能明白点,更希望能够将此程序继续改进以增强其功能。我的mail:ddzg2004@163.com希望与广大编程爱好者交流!