编译课设 2.docx
《编译课设 2.docx》由会员分享,可在线阅读,更多相关《编译课设 2.docx(13页珍藏版)》请在冰豆网上搜索。
编译课设2
1.课程设计题目名称
语法高亮转换软件
2.课程设计任务目的与任务
在集成化编译环境(IDE)中,如C++或C语言的源代码中,通过识别不同的关键字从而对相应关键字实现高亮显示,但是在HTML语言中,由于不存在识别关键字的功能,故无法实现对关键字的高亮显示功能。
现在我们需要设计一个软件,输入cpp文件后通过软件使它生成一个HTML文件。
而且,在这个HTML文件中可以实现语法的高亮显示。
3.设计思想和实现方法
a)源文件的输入和目标文件的输出
使用fstream类下的open函数,即打开文件功能,逐个读入源文件的字符,然后逐个输出到HTML文件中。
本设计使用语句:
file1=fopen(inDir,"w");
即打开inDir.html,然后通过“w”写入功能函数将读入字符逐个写入到inDir.html文件当中。
字符分类问题
字符的分类问题是本设计的基本问题。
对于不同作用的字符,应该用不同的颜色将其分别显示。
在C或者C++中的字符大概可以分为以下几类:
字符集,标识符,关键字,文字,操作符(运算符),分隔符,空白符等。
其中标识符和关键字都可以当作关键字处理,其他的字符则按自己的种类及功能进行分类。
根据本设计要求,我将字符分为三类:
字符串,注释和关键字。
字符串用红色显示,注释绿色表示,关键字蓝色显示。
b)不同种类字符的识别问题
很显然,本设计的实现关键就是识别各种不同种类的字符串。
本设计共要识别三种不同的字符,字符串、注释和关键字。
识别关键字:
定义一个数组,将C++中常用的关键字表示符存于数组中。
接受一个字符串时,和数组中的元素比较,如果有相同的,则表示为关键字,蓝色显示。
识别注释:
注释分为行注释和块注释。
行注释用//表示,块注释用/*…*/表示。
当接受的第一个字符为/时,判断接受的第二个字符,如果为/为行注释,则//之后包括//和换行符之前的内容均用绿色显示。
如果接受的第二个字符为*并且不是字符串,则表示为块注释,/*和*/之间的数字包括/*、*/均用绿色显示。
识别字符串:
被“”引号括起来的字符为字符串,用红色显示。
但在显示字符串时候应特别注意转义字符。
4.程序说明
/**
*CPP程序转换
*输入:
cpp文件
*输出:
html文件
*字符串变红
*注释变绿
*关键字变蓝
**/
#include
#include
#include
usingnamespacestd;
#defineLENGTH63
//关键字列表,将c++中常用关键字存于数组KeyWord中
char*KeyWord[LENGTH]=
{"asm","default","float","operator","static_cast","union","auto","delete","for","private","struct","unsigned","bool","do","friend","protected","switch","using","break","double","goto",public","template","virtual","case","dynamic_cast","if","register","this","void","catch","else","inline","reinterpret_cast","throw","volatile","char","enum","int","return","true","wchar_t","class""explicit","long","short","try","while","const","export","mutable","signed","typedef","const_cast","extern","namespace","sizeof","typeid","continue","false","new","stat","include","define"};
/*定义Red,Blue,Green变量用来在html文件中将文字内容显示成红色、蓝色和绿色*/
char*Red="";
char*Tail="";
char*Blue="";
char*Green="";
//////对照_ch是不是关键字
boolisKeyWord(char*_ch)
{
for(inti=0;i{
if(!
strcmp(_ch,KeyWord[i]))
returntrue;
}
returnfalse;
}
/*初始化源文件,如果初始化成功,复制文件到inDir,否则提示输入“请输入要转换的文件名,读入文件存于inDir。
*/
voidmain(intargc,char*argv[])
{
charinDir[30];
//初始化文件
try
{
strcpy(inDir,argv[1]);
}
catch(...)
{
cout<<"请输入要转换的文件名:
";
cin>>inDir;
}
fstreamrfile;//创建文件/rfile
fstreamwfile;//创建文件wfile
rfile.open(inDir);//将文件inDir写入到文件rfile中
strcat(inDir,".html");//为文件inDir增加后缀.html
//利用fopen函数写功能将inDir文件内容写入到file1中
FILE*file1=fopen(inDir,"w");
wfile.open(inDir);
cout<<"创建文件"<//文件头
wfile<<"
";
wfile<<"";
charstrWord[100]="";//读入字符的缓冲数组
charstrWrite[100]={0};//写入文件的缓冲数组
charch;
intisEx=0;//0为不注释1为行注释2为块注释
intisStr=0;//0为正常1为字符串
/////////////////循环读出并处理文件///////////////
while(!
rfile.eof())
{
ch=rfile.get();
inti=0;
/*判断是否为关键字,若为关键字则用蓝色字体输出*/
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')//如果首字母是字母,则
//读出整个单词
{
while(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_')
{
strWord[i++]=ch;
ch=rfile.get();
}
rfile.seekg(-1,ios:
:
cur);//退格
strWord[i]='\0';
if(isKeyWord(strWord)&&isEx==0&&isStr==0)
wfile<else
wfile<}
/*利用switch语句判别字符串和注释*/
elseswitch(ch)
{
case'#':
{
ch=rfile.get();
if(isEx==0&&isStr==0&&ch>='a'&&ch<='z')
wfile<elsewfile<<"#";
rfile.seekg(-1,ios:
:
cur);
break;
}
case'\"':
//判断字符串
{
rfile.seekg(-2,ios:
:
cur);
if(rfile.get()!
='\\'&&isEx==0)//判断是不是转义后的
if(isStr==0)
{
isStr=1;
wfile<<"\""<}
else
{
isStr=0;
wfile<}
else
wfile<<"\"";
rfile.get();
}
case'':
wfile<<" ";break;//加空格标签
case'\n':
{if(isEx==1)
{
isEx=0;
wfile<<"";
}
wfile<<"
\n";
break;//加换行标签
"\"
}
case'<':
wfile<<"<";break;//加<
case'>':
wfile<<">";break;//>
case'/':
{//判断注释
ch=rfile.get();
if(ch=='/'&&isEx==0&&isStr==0)//行注释
{
isEx=1;
wfile<break;
}
elseif(ch=='*'&&isEx==0&&isStr==0)//块注释
{
isEx=2;
wfile<break;
}
else
{
wfile<<"/";
rfile.seekg(-1,ios:
:
cur);//回退一个字符
break;
}
}
case'*':
{
ch=rfile.get();
if(ch=='/'&&isEx==2&&isStr==0)//块注释结尾
{
isEx=0;
wfile<<"*/";//闭合标签
break;
}
else
{
wfile<<"*";
rfile.seekg(-1,ios:
:
cur);
break;
}
}
default:
wfile<}
}
//文件尾
wfile<<"";
wfile<<"";
cout<<"完成转换!
!
\n";
}
5.程序运行结果
编写cpp文件,并以wd.cpp保存
执行程序,输出html文件,运行结果如下:
可以看出关键字用蓝色显示,字符串用红色显示,注释用绿色显示。
满足题目要求。
6.测试报告
编写cpp文件用于测试,文件名为wd.cpp
执行程序,提示输入要转换的文件名,输入wd.cpp并按回车键,程序显示创建文件wd.cpp.html完成转换。
打开wd.cpp.html,可以看到它的内容即是wd.cpp文件的语法高亮显示。
测试过程如下图所示:
ccc.cpp.html文件用html语言表示为:
#include <iostream.h>   //包含CIN,COUT 头文件
class test       //定义一个类
{
public:
test();
~test(){};
private:
int i;
};
test:
:
test()     //定义类中的构造函数
{
i=25;
cout<<" here is the program output.\n"
cout<<" let us generate some stuff...\n"
for(int ctr=0;ctr<10;ctr++)
{
cout<<" counting at" <<ctr<<" \n"
}
}
test anobject;     //生成一个类对象
main()
{
return 0;
}
经测试,程序满足设计要求,能完成指定功能,测试成功!
7.存在问题及分析
字符分类问题
很显然,本设计的实现关键就是字符的分类问题。
对于不同作用的字符,应该用不同的颜色将其分别显示。
在C或者C++中的字符大概可以分为以下几类:
字符集,标识符,关键字,文字,操作符(运算符),分隔符,空白符等。
其中标识符和关键字都可以当作关键字处理,其他的字符则按自己的种类及功能进行分类。
好的分类为他们的高亮显示提供了一个前提条件,让他们的功能既不会因为分类不具体而冲突也不会因为分得太细而使得某些功能没有实现,这使得了本设计的实现成为了可能,做好分类问题就相当于成功了一半。
根据本设计要求,我将字符分为三类:
字符串,注释和关键字。
字符串用红色显示,注释绿色表示,关键字蓝色显示。
但是由于时间有限和本人水平有限,还不是特别细致,在以后的设计中应该再逐步完善。
转换为html文件的问题
html语句和c++语句不同,必须是闭合的语句。
在输出一段文字后必须加上""才能完成相应的功能。
所以在输出时候应特别注意,每句末尾要加上""。
html语言中的一些符号的表示和c++不同,输出时候应注意转换为heml语言中的符号。
转义字符
应注意区别注释和字符串中的转义字符。
转义字符需要加上/,此时应该区别转义字符和注释,否则会引起错误,误将本应该按普通字符输出的转义字符按照字符串或者注释输出,引起错误。
8.总结及体会
通过这次的编译原理课程设计,使我明白只有把知识运用到实践中,才能真正把握知识。
程序设计是在将课本知识融会贯通的基础上,灵活运用,才能设计出符合要求的程序。
设计中需要不断思考,发现问题,解决问题,不断完善程序,设计出最好的程序。
对于本设计,要求设计一个简单的编译器以实现C++源文件在向HTML文件转换的过程中的关键字高亮显示的功能。
对于设计者来说,虽然题目不是那么复杂,但是要是将课本所学的知识转化成相应的实际应用软件却不是一件很容易的事情。
本设计的设计思想相对简单,只需将关键字、字符串、注释符等分类,然后通过识别不同类型的字符串,用相应的颜色显示即可。
但是,如何声明判别,怎样分类,却实在让设计者头痛。
经过不断的探讨,我终于成功完成了本次任务。
编译原理不同于一般集成环境的设计语言,它具有很强的抽象性。
这就要求我们在设计过程中要真正理解编译器是如何构造,如何实现功能的,而这相对普通程序设计语言在难度和抽象程度上有了很大的提升。
当然这也能使我们对程序设计语言的设计和实现由更深刻的理解。
对和程序设计语言相关的理论知识有了更深层次的了解。
编译原理是一门深奥的学科,从课堂上我们学到的并非知识的全部,课程设计为我们提供了一次自我学习的机会。
通过查找资料,我发现课本上的知识还不够深入,要想真正掌握这门课程,还应该多涉猎一些与之有关的其他方面的书籍,这样才能在拓展知识面的同时提高自己的能力。
在不断的学习过程中,我认识到编译原理作为一门计算机专业的基础课程,不是单独存在的,它和其它的课程有着紧密的联系。
所以在学习编译原理的同时,我们还应该注意他和其它课程的结合的地方,多涉猎相关知识,这样才能真正学好这门课程。
这次的课程设计不仅锻炼了我们的动手和动脑的能力,更让我体会到了理论与实践相联合的重要行,理论并不等于实践,光有理论是绝对不行的,但是在实践的过程中我们必须以理论为根据,才能在这一个层次上更好的把理论应用到实践中去,这次的课设使我真正的懂得了理论只是实践的基础,只有进一步的实践才能更好的运用理论。
所以在以后的学习和生活中都会好好的把理论和实践相结合才能达到真的懂一个问题。
程序设计应力求新颖,所以今后还应该不断提高创新意识与能力,不能拘泥于一种设计方案,争取设计出最。
参考文献
[1]李建中姜守旭,《编译原理》,机械工业出版社
[2]陈意云张昱,《编译原理》,高等教育出版社
[3]王雷刘志成周晶,《编译原理课程设计》,机械工业出版社
附录:
测试文件:
#include//包含CIN,COUT头文件
classtest//定义一个类
{
public:
test();
~test(){};
private:
inti;
};
test:
:
test()//定义类中的构造函数
{
i=25;
cout<<"hereistheprogramoutput.\n";
cout<<"letusgeneratesomestuff...\n";
for(intctr=0;ctr<10;ctr++)
{
cout<<"countingat"<}
}
testanobject;//生成一个类对象
main()
{
return0;
}
评语
评阅人:
日期: