编译原理实验报告7.docx
- 文档编号:27101216
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:29
- 大小:132.73KB
编译原理实验报告7.docx
《编译原理实验报告7.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告7.docx(29页珍藏版)》请在冰豆网上搜索。
编译原理实验报告7
编译原理实验报告
姓名:
高亮
学号:
080410417
班级:
计算机4班
哈尔滨工业大学(威海)计算机科学与技术学院
实验一词法扫描器设计
一实验目的
通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。
二实验内容
设计一个简单的类C语言的词法扫描器。
三实验要求
(一)程序设计要求
(1)根据附录给定的文法,从输入的类C语言源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算符、分隔符五大类;分发见最后附录。
(2)提供源程序输入界面;
(3)词法分析后可查看符号表和TOKEN串表;
(4)保存符号表和TOKEN串表(如:
文本文件);
(5)遇到错误时可显示提示信息,然后跳过错误部分继续进行分析。
(二)实验报告撰写要求
(1)系统功能(包括各个子功能模块的功能说明);
(2)开发平台(操作系统、设计语言);
Windows系统,C语言
(3)设计方案;
1)主数据流图;
2)主要子程序的流程框图(若有必要);
3)模块结构图;
4)主要数据结构:
符号表、TOKEN串表等。
符号表:
char*keyword[8]={"do","begin","else","end","if","then","var","while"};//保留字
char*operatornum[4]={"+","-","*","/"};//运算符
char*comparison[6]={"<","<=","=",">",">=","<>"};
char*interpunction[8]={",",";",":
=",".","(",")","[","]"};//界限符
(4)。
具体设计过程(包括主控程序、各个功能模块的具体实现)。
字母处理:
charletterprocess(charch)//字母处理函数
{
inti=-1;
charletter[20];
while(isalnum(ch)!
=0)//isalnum:
如果是英文或阿拉伯数字
{
letter[++i]=ch;
ch=fgetc(fp);
};
letter[i+1]='\0';
if(search(letter,1))
{
printf("<%s,->\n",letter);
//strcat(letter,"\n");
//fputs('<'letter'>\n',outp);
}
else
{
printf("
//strcat(letter,"\n");
//fputs(letter,outp);
}
return(ch);
}
数字处理:
charnumberprocess(charch)//数字处理程序
{
inti=-1;
charnum[20];
while(isdigit(ch)!
=0)
{
num[++i]=ch;
ch=fgetc(fp);
}
if(isalpha(ch)!
=0)//如果是字母即为以数字开始的标识符,这是非法的
{
while(isspace(ch)==0)//负责读完这个非法标识符
{
num[++i]=ch;
ch=fgetc(fp);
}
num[i+1]='\0';
printf("错误!
非法标识符:
%s\n",num);
gotou;
}
num[i+1]='\0';
printf("
//strcat(num,"\n");
//fputs(num,outp);
u:
return(ch);
}
主函数:
voidmain()
{
charstr,c;
printf("**********************************词法分析器************************************\n");
//outp=fopen("二元式表.txt","w");
if((fp=fopen("source.txt","r"))==NULL)
printf("源程序无法打开!
\n");
else
{
str=fgetc(fp);
while(str!
=EOF)
{
if(isalpha(str)!
=0)
str=letterprocess(str);
else
{
if(isdigit(str)!
=0)
str=numberprocess(str);
else
str=otherprocess(str);
}
};
printf("词法分析结束,谢谢使用!
\n");
printf("点任意键退出!
\n");
}
c=getch();
}
四实验总结
能正确进行词法分析,遇到非法字符时能够继续执行
五运行结果
附录:
类C语言的词法文法
idLetter
int10Numint10|Num
OP+|-|*|/|>|<|=|(|)|;|‘|==|>=|<=|!
=
Keywordif|then|else|while|do
Lettera|b|c|d|e|f|g|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
Num0|1|2|3|4|5|6|7|8|9|ε
实验二LR语法分析技术
一实验目的
通过设计调试LR语法分析程序,实现根据词法分析的输入TOKEN字,进行文法的语法分析;加深对课堂教学的理解;提高语法分析方法的实践能力。
二实验内容
使用附录中的文法,可以对类似下面的程序语句进行语法分析:
inta;
intb;
intc;
a=2;
b=1;
if(a>b)
c=a+b;
else
c=a-b;
三实验要求
(一)程序设计要求
(1)给出主要数据结构:
分析栈、符号表、语法分析树;
(2)将扫描器作为一个子程序,每次调用返回一个TOKEN;
(3)程序界面:
表达式输入、语法分析树的表示结果(文件或者图形方式);
(二)实验报告撰写要求
(1)系统功能分析与设计(包括各个子功能模块的功能说明);
输入单词符号,进行语法检查,判断源程序是否符合给定文法的语法定义,通过语义分析检查语义,运用语法制导翻译原理,将语法分析所识别的语法范畴变换为中间代码
(四元式)。
(2)开发平台(操作系统、设计语言);
Windows,c++
(3)设计方案:
包括功能模块结构图、主要函数的流程图;
s
(4)主要数据结构:
分析栈、分析表、符号表、语法分析树;
voidSymbolTable_fuction(intaddress,intlentgh,char*type,char*kind);//字符表函数
inttable[8][8]={{1,1,-1,-1,-1,1,-1,1},//+
{1,1,-1,-1,-1,1,-1,1},//-
{1,1,1,1,-1,1,-1,1},//*
{1,1,1,1,-1,1,-1,1},///
{-1,-1,-1,-1,-1,-1,-1,0},//(
{1,1,1,1,0,1,0,1},//)
{1,1,1,1,0,1,0,1},//i
{-1,-1,-1,-1,-1,0,-1,-1}//#
};
/*存储算符优先关系表,先于为,后于或同等优先为-1,其它为表示出错*/
structkeyword//存储关键字,标识符,界限符的NAME及编号
{
char*name;
intkind;
}keyword_ABC[60];
structSymbolTable//字符表结构体
{
intsymbol_address;
intsymbol_length;
char*symbol_type;
char*symbol_kind;
}SymbolTable1[100];
/****存放读入的token的结构体******/
structch_char
{
char*chchar;
structch_char*next;
}*p,*h,*temp,*top;
/****进行分析用的栈结构**********/
structfenxizhan
{
char*starname;
floatval;
structfenxizhan*next;
}*base1,*stact_top,*stact_top_top;
(5)具体设计实现过程(包括主控程序、各个功能模块的具体实现)。
voidanalyze_ABC(FILE*output,char*arry)//识别关键字、标识符、数字
{
inti=0,flag=0;
intcount=0;
if(isalpha(arry[0]))//判断首字母是不是英文字母
{
for(intj=1;j<=33;j++)//关键字查找
{
if(strcmp(keyword_ABC[j].name,arry)==0)//如果与关键字匹配的话
{
printf("%s(%d,__)\n",keyword_ABC[j].name,keyword_ABC[j].kind);//输出关键字的token串
fprintf(output,"%s(%d,__)\n",keyword_ABC[j].name,keyword_ABC[j].kind);//并写入token串文件
flag=1;//判断关键字
SymbolTable_fuction(num2,strlen(keyword_ABC[j].name),"关键字","字符型");//符号表函数调用
break;
}
}
if(flag==0)
{
printf("%s(34,%s)\n",arry,arry);//输出标识符的token串
fprintf(output,"%s(34,%s)\n",arry,arry);//并写入token串文件
SymbolTable_fuction(num2,strlen(arry),"简单变量","字符型");//符号表函数调用
}
}
else//如果首字符不是英文字母
{
for(;i<(int)strlen(arry);i++)
if(isdigit(arry[i]))
count++;
if(count==(int)strlen(arry))
{
printf("%s(35,%s)\n",arry,arry);//输出数字的token串
fprintf(output,"%s(35,%s)\n",arry,arry);//并写入token串文件
SymbolTable_fuction(num2,strlen(arry),"实数","整型");}//符号表函数调用
else{printf("%sisnotstandardsymbol!
\n",arry);
fprintf(output,"%sisnotstandardsymbol!
",arry);
}//提示所要识别的字符没有定义
}
}
voidanalyze_CD(FILE*outfile,char*symbol)//识别界限符、运算符
{
intflag=0;
for(intu=38;u<=60;u++)
{
if(strcmp(keyword_ABC[u].name,symbol)==0)//界限符、运算符查找
{
printf("%s(%d,__)\n",keyword_ABC[u].name,keyword_ABC[u].kind);//输出界限符、运算符的token串
fprintf(outfile,"%s(%d,__)\n",keyword_ABC[u].name,keyword_ABC[u].kind);//并写入token串文件
flag=1;
SymbolTable_fuction(num2,strlen(keyword_ABC[u].name),"界限符和运算符","符号");//符号表函数调用
}
}
if(flag==0)
{
printf("%sisunrecognizablesymbol!
\n",symbol);//输出不符合的字符
fprintf(outfile,"%sisunrecognizablesymbol!
\n",symbol);
}
}
intchangchar__int(char*ch)/*将字符转为数字,以得到算符优先值*/
{
intt;
if(strcmp(ch,"+")==0){t=0;}
elseif(strcmp(ch,"-")==0){t=1;}
elseif(strcmp(ch,"*")==0){t=2;}
elseif(strcmp(ch,"/")==0){t=3;}
elseif(strcmp(ch,"(")==0){t=4;}
elseif(strcmp(ch,")")==0){t=5;}
elseif(strcmp(ch,"#")==0){t=7;}
elset=6;
returnt;
}
voiderror()//错误提示
{
printf("\n");
printf("输入表达式有错误!
\n");
exit(0);
}
voidpush(char*pchar,floatval)/*入栈函数*/
{
stact_top_top=(fenxizhan*)malloc(sizeof(fenxizhan));
stact_top_top->starname=pchar;
stact_top_top->val=val;
stact_top_top->next=stact_top;
stact_top=stact_top_top;
}
floatpop(void)/*出栈函数*/
{
if(strcmp(stact_top->starname,"#")!
=0)
{
data=stact_top->val;
stact_top=stact_top->next;
}
returndata;
}
floatcalculate(floatnumber1,floatnumber2,char*str)//四则运算
{
floatsum;
if(strcmp(str,"+")==0)
sum=number1+number2;
elseif(strcmp(str,"-")==0)
sum=number1-number2;
elseif(strcmp(str,"*")==0)
sum=number1*number2;
elseif(strcmp(str,"/")==0)
{
if(number2==0)
{
printf("错误提示:
除数为零!
");
exit(0);
}
sum=number1/number2;
}
returnsum;//返回结果
}
四实验总结
加深了对语法分析器的理解
五运行结果:
附录:
简单类c语言文法
产生式语义规则
注:
P为文法的开始符号
说明语句部分文法:
P→DS
D→Tid;D|ε
T→int|float
程序语句部分文法:
S→id=E;S.code=E.code||gen(id.place’:
=’E.place)
S→if(C)S1C.true=newlabel;C.false=S.next;
S1.next=S.next;
S.code=C.code||gen(C.true’:
’)||S1.code
S→if(C)S1elseS2
S→while(C)S1doS2
C.true=newlabel;C.false=newlabel;
S1.next=S2.next=S.next;
S.code=C.code||gen(C.true’:
’)||S1.code
||gen(‘goto’S.next)||gen(C.false’:
’)||S2.code;
S→S;S;
C→E1>E2
C.code=E1.code||E2.code||
gen(‘if’E1.place’>’E2.place’goto’C.true)||
gen(‘goto’C.false)
C→E1 gen(‘if’E1.place’<’E2.place’goto’C.true)|| gen(‘goto’C.false) C→E1==E2C.code=E1.code||E2.code|| gen(‘if’E1.place’=’E2.place’goto’C.true)|| gen(‘goto’C.false) E→E1+TE.place=newtemp; E.code=E1.code||T.code|| gen(E.place’: =’E1.place’+’T.place) E→E1–TE.place=newtemp;E.code=E1.code||T.code|| gen(E.place’: =’E1.place’-’T.place) E→TE.place=T.place;E.code=T.code T→FT.place=F.place;T.code=F.code T→T1*FT.place=newtemp; T.code=T1.code||F.code|| gen(T.place’: =’T1.place’*’F.place) T→T1/FT.place=newtemp;T.code=T1.code||F.code|| gen(T.place’: =’T1.place’/’F.place) F→(E)F.place=E.place;F.code=E.code F→idF.place=id.name;F.code=‘‘ F→int10F.place=int10.value;F.code=‘‘ 实验三语义分析及中间代码生成 一实验目的 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译方法。 二实验内容 实现简单的高级语言源程序的语义处理过程。 三实验要求 (一)程序设计要求 (1)目标机: 8086及其兼容处理器 (2)中间代码: 三地址码或者四元式 (3)设计结果: 语法分析树(节点具有属性)、三地址码表、符号表、TOKEN串表 (4)语义分析内容要求: 1)变量说明语句 2)赋值语句 3)控制语句(任选一种) (5)其它要求: 1)将词法分析(扫描器)作为子程序,供语法语义程序调用; 2)使用语法制导的语义翻译方法; 3)编程语言自定; 4)最好提供源程序输入界面; 5)目标代码生成暂不做; 6)编译后,可查看TOKEN串、语法分析树、符号表、三地址码表; 7)主要数据结构: 产生式表、符号表、语法分析树、三地址码表。 所用文法使用实验2中的文法。 附录: 语义分析源程序范例 inta; intb; intc; a=2; b=1; if(a>b) c=a+b; else c=a-b; (二)实验报告撰写要求 (1)系统功能分析与设计(包括各个子功能模块的功能说明); 首先将待编译程序写入TXT文本,接下来经过词法扫描器的扫描和分析,将程序转化为TOKEN链,接下来语法分析器对TOKEN链进行语法分析,产生语法分析树和符号表。 接下来使用语义制导翻译使用语义分析器进行语义分析,生成参数表,函数表,以及四元式的中间代码。 (2)开发平台(开发软硬件环境); WindowsC语言 (3)语义翻译中使用的数据结构; //定义结点类 template { public: link*next; Elemelement; intsign; link(constElem&elementValue,link*nextValue=NULL) { element=elementValue; next=nextValue; sign=-1; } link(link*nextValue=NUll) { next=nextValue; sign=-1; } }; ///////////////////////////////////////////////// //定义堆栈类 template { private: link intsize; public: stack(intsz=DefaultSize) { top=NULL; size=0; } ~stack(){clear();} voidclear() { while(top! =NULL) { link top=top->next; size=0; deletetemp; } } //入栈函数 boolpush(cons
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告