编译技术课程设计实验报告.docx
- 文档编号:9667498
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:49
- 大小:262KB
编译技术课程设计实验报告.docx
《编译技术课程设计实验报告.docx》由会员分享,可在线阅读,更多相关《编译技术课程设计实验报告.docx(49页珍藏版)》请在冰豆网上搜索。
编译技术课程设计实验报告
《编译原理》课程设计实验报告
姓名:
谢龙恩
学号:
U200817970
班级:
软件工程0805
指导教师:
胡福林
日期:
2010年11月10日
实验题目:
用C语言对下述文法和单词表定义的语言设计编制一个编译器。
(1)单词符号及种别表
单词符号
种别编码
单词值
main
1
int
2
float
3
double
4
char
5
if
6
else
7
do
8
while
9
l(l|d)*
10
内部字符串
(+|-|ε)d*(.dd*|ε)(e(+|-|ε)dd*|ε)
20
二进制数值表示
=
21
+
22
-
23
*
24
/
25
(
26
)
27
{
28
}
29
30
;
31
>
32
>=
33
<
34
<=
35
==
36
!
=
37
(2)语法结构定义
<程序>:
:
=main()<语句块>
<语句块>:
:
=‘{‘<语句串>’}’
<语句串>:
:
=<语句>{;<语句>};
<语句>:
:
=<赋值语句>|<条件语句>|<循环语句>
<赋值语句>:
:
=ID=<表达式>
<条件语句>:
:
=if<条件><语句块>[else<语句块>]
<循环语句>:
:
=do<语句块>while<条件>
<条件>:
:
=<表达式><关系运算符><表达式>
<表达式>:
:
=<项>{+<项>|-<项>}
<项>:
:
=<因子>{*<因子>|/<因子>}
<因子>:
:
=ID|num|(<表达式>)
num:
:
=(+|-|ε)数字*(.数字数字*|ε)(e(+|-|ε)数字数字*|ε)
ID:
:
=字母(字母|d数字)*
字母:
:
=a|b|c…|z|A|B|C…|Z
数字:
:
=0|1|2…|9
<关系运算符>:
:
=<|<=|>|>=|==|!
=
实验目的:
1、通过该课程设计,熟练应用编译原理的基本理论和方法
2、学会用C/C++高级程序设计语言设计一个编译器的技术
3、加深对编译原理的分析理论的理解,培养动手实践能力
4、通过设计、编制、调试一个编译器,掌握其设计方法和技术,提高解决实际问题的综合素质
实验要求:
处理用户提交的符合上述文法的源代码序列,生成四元式中间代码或X86平台上的目标代码。
实验步骤:
(1)画出识别上述语言单词的状态转换图
(2)用C/C++语言编写词法分析程序(应考虑能被语法分析程序调用)
(3)预处理,去除注释、多余空格、回车换行符等
(3)设计实现语法分析程序(调用上述词法程序分析单词)
(4)设计构造属性文法及中间代码序列结构
(5)采用语法制导翻译法,完成语义分析程序设计,生成四元式中间代码
(6)或将生成的四元式中间代码转换成X86平台上的目标代码
(7)设计若干用例,上机测试并通过所设计实现的编译器
实验方案设计与实现:
总体设计思想
经过分析,由于存在冲突项目,上述文法的语法分析无法使用LR(0)分析法,但是上述文法却满足LL
(1)文法,故其语法分析可以采用递归下降分析法。
故在实验二语法分析的基础上,每当成功识别一个非终结符,根据属性文法的要求采取相应的语义动作,在此过程中可以生成相应的四元式。
因此本实验的重点在于四元式结构的定义和生成四元式。
详细算法设计
数据结构:
存储已被识别出单词的结构体
四元式定义
四元式链表
辅助功能模块:
分配临时变量
回填
语法分析模块:
识别每一个终结符,并同时根据语义需要生成四元式
流程框图:
识别单词流程图(对应scanner())
拼数流程图(对于manageNumberWithoutSign())
递归下降分析法中识别非终结符的伪码:
Word*element()
{
如果当前单词是数字或标号
{
生成一个包含上述单词信息的word;
识别下一个单词;
返回上述word的指针;
}
否则如果当前单词是左括号
{
识别下一个单词;
word=expression();
如果当前单词是右括号
{
识别下一个单词;
返回word;
}
否则报错;
}
否则报错;
返回空指针;
}
Word*item()
{
arg1=element();
while当前单词是乘除
{
识别下一个单词;
arg2=element();
获得临时变量
生成新四元式并加入四元式链表中;
arg1=临时变量;
}
returnarg1;
}
Word*expression()
{
arg1=item();
while当前单词是加减
{
识别下一个单词;
arg2=element();
获得临时变量
生成新四元式并加入四元式链表中;
arg1=临时变量;
}
returnarg1;
}
voidcondition()
{
arg1=expression();
如果当前单词是比较运算符
{
识别下一个单词
arg2=expression();
生成新四元式并加入四元式链表中;
}
否则报错;
}
voidassignSentence()
{
如果当前单词是标号
{
识别下一个单词;
如果当前单词是浮点数
{
生成新四元式并加入四元式链表中;
}
否则报错;
}
否则报错;
}
voidconditionSentence()
{
如果当前单词是if
{
识别下一个单词;
condition();
回填true入口;
添加goto判断为假应执行的语句块的四元式;//:
=A
sentenceBlock();
如果当前单词是else
{
添加判断为真时避开执行为假时语句块的goto四元式;//:
=B
回填A;
识别下一个单词;
sentenceBlock();
回填B;
}
else
{
回填A;
}
}
else
{
error();
}
}
voidloopSentence()
{
如果当前单词是do
{
识别下一个单词
记录下一个四元式编号;
sentenceBlock();
如果当前单词是while
{
识别下一个单词
condition();
生成goto四元式,并把记录的四元式编号填入
}
否则报错;
}
否则报错;
}
voidsentence()
{
如果当前单词是标号
{
assignSentence();
}
否则如果当前单词是if
{
conditionSentence();
}
否则如果当前单词是do
{
loopSentence();
}
否则报错;
}
voidsentenceSeries()
{
do
{
sentence();
如果当前单词是;
{
识别下一个单词;
}
否则报错;
}while(当前单词不是‘}’);
}
voidsentenceBlock()
{
如果当前单词是{
{
识别下一个单词;
sentenceSeries();
如果当前单词是}
{
识别下一个单词;
}
否则报错;
}
否则报错;
}
voidprogram()
{
如果当前单词是main
{
识别下一个单词;
如果当前单词是(
{
识别下一个单词;
如果当前单词是)
{
识别下一个单词;
sentenceBlock();
}
否则报错;
}
否则报错;
}
否则报错;
}
函数相关说明:
intisDigit(charc)判断给定字符是否是数字
intisLetter(charc)判断给定字符是否是字母
intisBlank(charc)判断给定字符是否是空白字符
voidgotoUnblankChar()读到第一个非空字符
voidgetLabelOrKey()读出标识符或者变量名
voidreserve()判断标识符是否是关键字
intisVar()判断当前单词是否是符号数或者标识符
intisRelationOperator()判断当前单词是否关系运算符
voidmanageNumberWithoutSign()拼符号数
voidscanner()识别单词
voidgetProgram()从控制台读入源代码
voidgetProgramFromFile()从文件读入源代码
voidlink(Ptqptq)//向四元式链表尾添加一个四元式
voidprintQuaternion()//打印四元式
Word*getNewTempVariety()//返回一个临时变量
Word*getLabel(inti)//返回一个记录回填位置的单词
voiderror()//错误处理
Word*element();//识别因子
Word*item();//识别项
Word*expression();//识别表达式
voidcondition();//识别条件
voidassignSentence();//识别赋值语句
voidconditionSentence();//识别条件语句
voidloopSentence();//识别循环语句
voidsentence();//识别语句
voidsentenceSeries();//识别语句序列
voidsentenceBlock();//识别语句块
voidprogram();//识别程序
输入与输出(包括出错处理)
源程序通过文件输入,控制台上显示
输出:
语法正确与否,如果正确输出四元式,否则输出错误的地方附近的语句和错误的单词;
程序运行结果:
语法正确时
语法错误时
编译器使用说明:
在VisualC++6.0中运行,输入文件在C盘的program.txt文件下,使用前需要新建该文件并在该文件中输入源程序。
实验心得体会:
学了这么长时间的编译原理,总是感觉很多有东西虽然知道是什么原理,却并不清楚具体怎么实现。
这次实验给了一个机会,本想好好做一做实验,做一个实用的编译器。
可惜时间太短了,甚至连目标代码还没有来得及翻译,实验课已经结束。
不过这可以理解,上课和实验的时间比较有限,真正的学习是在课程结束后的实践。
源程序清单:
//编译技术课程设计.cpp:
定义控制台应用程序的入口点。
//作者:
谢龙恩
#include"stdafx.h"
#include
#include
//***************************辅助判断小函数**********************
intisDigit(charc)//是否是数字
{
if(47 return1; else return0; } intisLetter(charc)//是否是字母 { if(64 return1; else return0; } intisBlank(charc)//是否是空白字符 { if(c=='\r'||c=='\n'||c==''||c=='\t') return1; else return0; } /****************************全局变量和函数*********************///作者: 谢龙恩 //一些最大长度限制 #definemaxProgramLength10000//程序最长长度限制 #definemaxWordLength20//单词最长长度限制 #definemaxSignLength3 charprog[maxProgramLength];//源程序 voidgetProgramFromScreen()//源程序输入 { printf("请输入程序: \n"); intp=0; charc; do { c=getchar(); prog[p++]=c; }while(c! ='#'); } voidgetProgramFromFile()//源程序输入 { FILE*fp; fp=fopen("C: \\program.txt","r");//C: \\Users\\x\\Desktop intp=0; charc; if(fp! =NULL) { c=fgetc(fp); while((c! ='#')&&(c! =EOF)) { prog[p++]=c; c=fgetc(fp); } prog[p++]='#'; fclose(fp); printf("源码: \n%s\n",prog); } else { printf("文件打开失败\n"); printf("pressanykeytoexit"); getchar(); exit(0); } } /****************************词法分析要求 ***********************//作者: 谢龙恩 main1 int2 float3 double4 char5 if6 else7 do8 while9 l(l|d)*10 (+|-|ε)dd*(.dd*|ε)(e(+|-|ε)dd*|ε)20 =21 +22 -23 *24 /25 (26 )27 {28 }29 30 ;31 >32 >=33 <34 <=35 ==36 ! =37 *****************************************************************/ //******************************词法分析变量********************* typedefstructWORDCONTENT//存储词的内容 { doublei;//可能的值 charstring[maxWordLength];//源字符串 }WordContent; typedefstructWORD//识别的单词的全部信息 { inttype;//单词的类型 WordContentvalue;//单词的内容 }Word; //关键字 #definekeysNunber9 char*key[keysNunber]={"main","int","float","double","char","if","else","do","while"}; Wordword;//读出的单词 charc;//当前字符 intp;//源程序中指针指向的位置 intn;//单词中指针指向的位置 //******************************词法分析辅助函数****************** intisVar()//判断是否是变量 { if(word.type==10||word.type==20) { return1; } else { return0; } } intisRelationOperator() { if(word.type>31&&word.type<38) { return1; } else { return0; } } voidgotoUnblankChar()//读到第一个非空字符 { c=prog[p++]; while(isBlank(c)) { c=prog[p++]; } } voidgetLabelOrKey()//读出标识符或者变量名 { while(isLetter(c)||isDigit(c)) { word.value.string[n++]=c; c=prog[p++]; } p--; word.value.string[n++]='\0'; } voidreserve()//判断是否是关键字 { word.type=10; for(intk=0;k { if(strcmp(word.value.string,key[k])==0) { word.type=k+1; break; } } } voidmanageNumberWithoutSign() { c=prog[p++]; while(isDigit(c)) { word.value.string[n++]=c; c=prog[p++]; } p--; c=prog[p]; if(c=='.') { word.value.string[n++]=c; p++; if(isDigit(prog[p])) { c=prog[p++]; while(isDigit(c)) { word.value.string[n++]=c; c=prog[p++]; } p--; } else { word.type=-1; word.value.string[n++]='\0'; return; } } if(prog[p]=='e') { word.value.string[n++]=prog[p]; p++; if(prog[p]=='+'||prog[p]=='-') { word.value.string[n++]=prog[p]; p++; } if(isDigit(prog[p])) { c=prog[p++]; while(isDigit(c)) { word.value.string[n++]=c; c=prog[p++]; } p--; } else { word.type=-1; word.value.string[n++]='\0'; return; } } word.type=20; word.value.string[n++]='\0'; word.value.i=atof(word.value.string); } //******************************词法分析************************** voidscanner() { n=0; gotoUnblankChar(); if(isDigit(c)) { p--; manageNumberWithoutSign(); } elseif(isLetter(c)) { getLabelOrKey(); reserve(); } else { word.value.string[n++]=c; switch(c) { case'=': if(prog[p++]=='=') { word.type=36; word.value.string[n++]='='; } else { word.type=21; p--; } word.value.string[n++]='\0'; break; case'+': if(isDigit(prog[p])&&! isVar()) { manageNumberWithoutSign(); break; } else { word.type=22; word.value.string[n++]='\0'; break; } case'-': if(isDigit(prog[p])&&! isVar()) { manageNumberWithoutSign(); break; } else { word.type=23; word.value.string[n++]='\0'; break; } case'*': word.type=24; word.value.string[n++]='\0'; break; case'/': word.type=25; word.value.string[n++]='\0'; break; case'(': word.type=26; word.value.string[n++]='\0'; break; case')': word.type=27; word.value.string[n++]='
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 技术 课程设计 实验 报告