编译技术课程设计.docx
- 文档编号:10142561
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:44
- 大小:115.69KB
编译技术课程设计.docx
《编译技术课程设计.docx》由会员分享,可在线阅读,更多相关《编译技术课程设计.docx(44页珍藏版)》请在冰豆网上搜索。
编译技术课程设计
编译技术课程设计
班级
学号
姓名
指导老师
二零一零年七月
一、目的
<<编译技术>>是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、任务及要求
基本要求:
1.词法分析器产生下述小语言的单词序列
这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:
单词符号
种别编码
助记符
内码值
DIM
IF
DO
STOP
END
标识符
常数(整)
=
+
*
**
,
(
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$DIM
$IF
$DO
$STOP
$END
$ID
$INT
$ASSIGN
$PLUS
$STAR
$POWER
$COMMA
$LPAR
$RPAR
-
-
-
-
-
-
内部字符串
标准二进形式
-
-
-
-
-
-
对于这个小语言,有几点重要的限制:
首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。
例如,下面的写法是绝对禁止的:
IF(5)=x
其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
例如,一个条件语句应写为
IFi>0i=1;
而绝对不要写成
IFi>0i=1;
因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。
这个小语言的单词符号的状态转换图,如下图:
2.语法分析器能识别由加+减-乘*除/乘方^括号()操作数所组成的算术表达式,其文法如下:
E→E+T|E-T|T
T→T*F|T/F|F
F→P^F|P
p→(E)|i
使用的算法可以是:
预测分析法;递归下降分析法;算符优先分析法;LR分析法等。
3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)
三、实现过程说明
给出各题目的详细算法描述,数据结构和函数说明,流程图。
1、词法分析器的流程图
2、语法分析器主程序图
3、中间代码生成器流程图:
四、源程序清单
词法分析器
#include"stdafx.h"
#include"Word.h"
//构造函数,对数据成员初始化,并将关键字以及运算符读入
Word:
:
Word()
{//打开关键字文件
fstreamkeywordfile("keyword.txt");
if(!
keywordfile)
{
cout<<"error!
can'topenkeywordfile!
"< system("pause"); exit (1); } //设置临时变量将关键字、符号文件中的内容存储 stringtempword; inttempencode; stringtempre; inttempvalue; //开始读关键字文件 while(! (keywordfile.eof())) {keywordfile>>tempword>>tempencode>>tempre>>tempvalue; keywordlist.push_back(tempword); keywordencode.push_back(tempencode); keywordre.push_back(tempre); keywordcodevalue.push_back(tempvalue); } //关闭关键字文件 keywordfile.close(); for(inti=0;i {cout< } fstreamsignwordfile("signword.txt"); if(! signwordfile) {cout<<"error! can'topensignwordfile! "< system("pause"); exit (1); } //开始读符号文件 while(! (signwordfile.eof())) { signwordfile>>tempword>>tempencode>>tempre>>tempvalue; signlist.push_back(tempword); signencode.push_back(tempencode); signre.push_back(tempre); signcodevalue.push_back(tempvalue); } //关闭符号文件 signwordfile.close(); for(inti=0;i {cout< } } //将token中的字符串与character中的字符连接作为token中新的字符串 voidWord: : concatentation() {for(inti=0;i<100;i++) {if(token[i]==NULL) {token[i]=s; break; } } } //判断character中的字符是否为字母和数字的布尔函数,是则返回true,否则返回false boolWord: : letter() {if(s<='z'&&s>='a') returntrue; elseif(s<='Z'&&s>='A') returntrue; else returnfalse; } boolWord: : digit() {if(s<='9'&&s>='0') returntrue; returnfalse; } //按token数组中的字符串中的前五项(即判别其是否为保留字),若是保留字则返回它的编码 intWord: : reserve() { intleng;//记录token数组中单词的长度 for(inti=0;i<100;i++)//计算token数组中单词的长度 { if(token[i]==NULL) { leng=i; break; } } for(inti=0;i { for(intj=0;j { if(keywordlist[i][j]! =token[j])//若某个字符不等则终止此次循环 break; if(j+1==keywordlist[i].length())//若比较字符全部相等,则判断两者是否长度相等 { if(leng==keywordlist[i].length()) {returni+1;} else return0; } } } return0; } //将标识符登录到符号表中或将常数登录到常数表中 voidWord: : buildlist() {//设置临时变量将标识符的助记符保存 stringtempword; inttempencode; stringtempre;//标识符助记 inttempvalue; inttempconstre;//常数助记 s=token[0]; if(letter())//第一个字符如果为字母,则将标识符登录到符号表中 {fstreamchartostring("convert.txt"); if(! chartostring) { cout<<"Error! Can'topenconvertfile"< system("pause"); } for(inti=0;i<100;i++) { if(token[i]==NULL) break; else {chartostring< } chartostring< chartostring.close(); chartostring.open("convert.txt"); if(! chartostring) { cout<<"Error! Can'topenconvertfile"< system("pause"); } chartostring>>tempre; chartostring.close(); indentityre.push_back(tempre); tempword="标识符"; tempencode=6; tempvalue=indentityre.size(); indentitylist.push_back(tempword); indentityencode.push_back(tempencode); indentitycodevalue.push_back(tempvalue); fstreamindentityfile("indentityword.txt"); if(! indentityfile) {cout<<"Error! Can'topenindentitywordfile"< system("pause"); } //先将文件指针移到最后去,再写入一个endl indentityfile.seekg(0,ios: : end); indentityfile< indentityfile.seekg(0,ios: : end); indentityfile< indentityfile.close(); } else//token中存储的是常数 { //将token中的字符数字转换为int类型 fstreamchartoint("convert.txt"); if(! chartoint) { cout<<"Error! Can'topenconvertfile"< system("pause"); } for(inti=0;i<100;i++) {if(token[i]==NULL) break; else { chartoint< } } chartoint< chartoint.close(); chartoint.open("convert.txt"); if(! chartoint) {cout<<"Error! Can'topenconvertfile"< system("pause"); exit (1); } chartoint>>tempconstre; chartoint.close(); constlist.push_back(tempword); tempword="常数"; tempencode=7; tempvalue=indentityre.size(); constencode.push_back(tempencode); constre.push_back(tempconstre); constvalue.push_back(tempvalue); fstreamconstdigit("constdigit.txt"); if(! constdigit) { cout<<"Error! Can'topenconstdigitfile! "< system("pause"); exit (1); } //先将文件指针移到最后去,再写入一个endl constdigit.seekg(0,ios: : end); constdigit< constdigit.seekg(0,ios: : end); constdigit< constdigit.close(); cout< } } //出现非法字符,显示错误信息 voidWord: : error() { cout<<"Error! Errorword! "< system("pause"); } voidWord: : signinfor() { //按token数组中的字符串中的前五项(即判别其是否为保留字),若是保留字则返回它的编码 intleng;//记录token数组中单词的长度 for(inti=0;i<100;i++)//计算token数组中单词的长度 { if(token[i]==NULL) { leng=i; break; } } for(inti=0;i { for(intj=0;j { if(signlist[i][j]! =token[j])//若某个字符不等则终止此次循环 break; if(j+1==signlist[i].length())//若比较字符全部相等,则判断两者是否长度相等 { if(leng==signlist[i].length()) { cout< } } } } } //词法分析的函数 voidWord: : run() { cout< fstreamfile("word.txt"); if(! file) { cout<<"error,can'topenfile"< system("pause"); exit (1); } file.unsetf(ios: : skipws); while(s! ='#'&&! file.eof()) { for(inti=0;i<100;i++) { token[i]=NULL; } file>>s; while(s=='') { file>>s; } switch(s) { case'a'; case'b': case'c': case'd': case'e': case'f': case'g': case'h': case'i': case'j': case'k': case'l': case'm': case'n': case'o': case'p': case'q': case'r': case's': case't': case'u': case'v': case'w': case'x': case'y': case'z': while(letter()||digit()) { concatentation();//将当前读入的字符送入token数组 file>>s;//继续读字符,直到字符不为数字或字母为止 } //扫描指针回退一个字符 file.seekg(-1,ios: : cur); code=reserve(); if(! code) {buildlist();} else { cout< } break; case'0': case'1': case'2': case'3': case'4': case'5': case'6': case'7': case'8': case'9': while(digit()) { concatentation();//将当前读入的字符送入token数组 file>>s;//继续读字符,直到字符不为数字为止 } //扫描指针回退一个字符 file.seekg(-1,ios: : cur); buildlist(); break; case'+': concatentation(); signinfor(); break; case'-': concatentation(); signinfor(); break; case'*': concatentation(); signinfor(); break; case'<': concatentation(); file>>s; if(s! ='=') {//扫描指针回退一个字符 file.seekg(-1,ios: : cur); signinfor(); } else { concatentation(); signinfor(); } break; case'=': concatentation(); file>>s; if(s! ='=') { //扫描指针回退一个字符 file.seekg(-1,ios: : cur); signinfor(); } else { concatentation(); signinfor(); } break; case';': concatentation(); signinfor(); break; case'#': cout< cout< cout< "< system("pause"); exit (1); default: error(); } } file.close(); } voidmain() { Wordword; word.run(); system("pause"); } 运行结果: 语法分析器源程序: #include #include #include typedefstruct { charR; charr; intflag; }array; typedefstruct { charE; chare; }charLode; typedefstruct { charLode*base; inttop; }charstack; charstr[80][80],arr[80][80],brr[80][80]; arrayF[20]; intm,kk,p,ppp,FF=1; charr[10]; intcrr[20][20],FLAG=0; charccrr1[1][20],ccrr2[20][1]; voidInitstack(charstack&s)//定义栈 { s.base=newcharLode[20]; s.top=-1; } voidpush(charstack&s,charLodew) { s.top++; s.base[s.top].E=w.E; s.base[s.top].e=w.e; } voidpop(charstack&s,charLode&w) { w.E=s.base[s.top].E; w.e=s.base[s.top].e; s.top--; } intIsEmpty(charstacks) { if(s.top==-1) retur
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 技术 课程设计