武汉理工大学编译原理实验报告.docx

上传人:b****3 文档编号:10863725 上传时间:2023-05-28 格式:DOCX 页数:23 大小:87.23KB
下载 相关 举报
武汉理工大学编译原理实验报告.docx_第1页
第1页 / 共23页
武汉理工大学编译原理实验报告.docx_第2页
第2页 / 共23页
武汉理工大学编译原理实验报告.docx_第3页
第3页 / 共23页
武汉理工大学编译原理实验报告.docx_第4页
第4页 / 共23页
武汉理工大学编译原理实验报告.docx_第5页
第5页 / 共23页
武汉理工大学编译原理实验报告.docx_第6页
第6页 / 共23页
武汉理工大学编译原理实验报告.docx_第7页
第7页 / 共23页
武汉理工大学编译原理实验报告.docx_第8页
第8页 / 共23页
武汉理工大学编译原理实验报告.docx_第9页
第9页 / 共23页
武汉理工大学编译原理实验报告.docx_第10页
第10页 / 共23页
武汉理工大学编译原理实验报告.docx_第11页
第11页 / 共23页
武汉理工大学编译原理实验报告.docx_第12页
第12页 / 共23页
武汉理工大学编译原理实验报告.docx_第13页
第13页 / 共23页
武汉理工大学编译原理实验报告.docx_第14页
第14页 / 共23页
武汉理工大学编译原理实验报告.docx_第15页
第15页 / 共23页
武汉理工大学编译原理实验报告.docx_第16页
第16页 / 共23页
武汉理工大学编译原理实验报告.docx_第17页
第17页 / 共23页
武汉理工大学编译原理实验报告.docx_第18页
第18页 / 共23页
武汉理工大学编译原理实验报告.docx_第19页
第19页 / 共23页
武汉理工大学编译原理实验报告.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

武汉理工大学编译原理实验报告.docx

《武汉理工大学编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《武汉理工大学编译原理实验报告.docx(23页珍藏版)》请在冰点文库上搜索。

武汉理工大学编译原理实验报告.docx

武汉理工大学编译原理实验报告

学生学号

实验课成绩

武汉理工大学

学生实验报告书

 

实验课程名称《编译原理》

开课学院计算机科学与技术学院

指导老师姓名饶文碧

学生姓名

学生专业班级软件

 

2014—2015学年第1学期

 

实验课程名称:

编译原理

实验项目名称

词法分析器的设计

实验成绩

实验者

专业班级

软件

组别

同组者

实验日期

第一部分:

实验分析与设计(可加页)

一、实验内容描述(问题域描述)

1.问题描述:

对于常用高级语言(如Pascal、C语言)的各类单词进行词法分析。

2.实验内容:

完成对某一种常用高级语言(如Pascal、C语言、PL/0语言)的各类单词进行词法分析,即对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词;并把其转换成属性字输出。

3.实验要求:

(1)选择常用高级程序设计语言(如Pascal、C语言、PL/0语言)的源程序作为词法分析对象。

(2)根据教学要求和学生具体情况,从上列语言之一中选取它的一个适当大小的子集,可以选取一类典型单词,也可以尽可能使各种类型的单词都能兼顾到。

其基本要求是:

对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词;并把其转换成属性字输出。

 

二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)

 

1.待分析的简单语言的词法:

(1)关键字:

mainvoidreturnifendthenelseint

所有的关键字都是小写。

(2)运算符和界符:

{},;<<=<>===>>=:

=++=--=**=//=

#()

(3)其他单词是标志符(ID)和整形常数(NUM),通过以下正规式定义:

ID=letter(letter|digit)*NUM=digitdigit*

(4)空格空白、制表符和换行符组成。

空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

 

2.各种单词符号对应的种别码(针对于较为熟悉的c语言)

单词符号

种别码

 

单词符号

种别码

main

1

=

18

void

2

==

19

return

3

>

20

if

4

>=

21

end

5

:

22

then

6

:

=

23

else

7

+

24

int

8

+=

25

Letter(letter|digit)

9

-

26

digitdigit*

10

-=

27

{

11

*

28

}

12

*=

29

13

/

30

;

14

/=

31

<

15

#

32

<=

16

33

<>

17

 

34

3.实验源代码如下:

#include

#include

#include

#include

//头文件库

charTOKEN[30];

char*table[9]={"","main","void","return","if","end","then","else","int"};

//定义关键字

externintlookup(char*);

externvoidout(int,char*);

externvoidreport_error(void);

//函数及全局变量声明

/*extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。

另外,extern也可用来进行链接指定*/

intlookup(char*TOKEN)

{

intm,i;

for(i=1;i<8;i++)

{

if((m=strcmp(TOKEN,table[i]))==0)

//table中关键字匹配

returni;

}

return0;

}

//关键字匹配函数,返回关键字在表中的位置,空出空格

voidout(intc,char*TOKEN)

{

printf("(%d,%s)\n",c,TOKEN);

}

//输出在表中位置和读取的字符

voidreport_error()

{

printf("error!

\n");

}

//输出没有考虑的情况

voidscanner(FILE*fp)

{

charTOKEN[30]={'\0'};

charch;

inti,c;

ch=fgetc(fp);

//获取字符,指针fp并自动指向下一个字符

if(isalpha(ch))

//判断该字符是否是字母

{

TOKEN[0]=ch;

ch=fgetc(fp);

i=1;

while(isalnum(ch))

//判断该字符是否是字母或数字

{

TOKEN[i]=ch;

i++;

ch=fgetc(fp);

}

TOKEN[i]='\0';

fseek(fp,-1,1);

//回退一个字符

c=lookup(TOKEN);

if(c==0)

out(9,TOKEN);

//输出标识符号,定编号为9

else

out(c,TOKEN);

//输出表中编号和关键字

}

elseif(isdigit(ch))

//判断是否是数字

{

TOKEN[0]=ch;

ch=fgetc(fp);

i=1;

while(isdigit(ch))

{

TOKEN[i]=ch;

i++;

ch=fgetc(fp);

}

//判断是否是连续数字

TOKEN[i]='\0';

fseek(fp,-1,1);

out(10,TOKEN);

//输出数字,定编号为10

}

else

{

TOKEN[0]=ch;

switch(ch)

{

case'{':

out(11,TOKEN);

break;

case'}':

out(12,TOKEN);

break;

case',':

out(13,TOKEN);

break;

case';':

out(14,TOKEN);

break;

case'<':

ch=fgetc(fp);

//读取下一个字符,判断<,<=,<>(空标签)

if(ch=='=')

{

TOKEN[1]=ch;

out(15,TOKEN);

}

//判断<=

elseif(ch=='>')

{

TOKEN[1]=ch;

out(17,TOKEN);

}

//判断<>空标签

else

{

fseek(fp,-1,1);

out(16,TOKEN);

}

//判断小于号<

break;

case'=':

ch=fgetc(fp);

if(ch=='=')

{

TOKEN[1]=ch;

out(19,TOKEN);

}

else

{

fseek(fp,-1,1);

out(18,TOKEN);

}

break;

//判断=,==

case'>':

ch=fgetc(fp);

//读取下一个字符,判断>,>=

if(ch=='=')

{

TOKEN[1]=ch;

out(21,TOKEN);

}

else

{

fseek(fp,-1,1);

out(20,TOKEN);

}

break;

case':

':

ch=fgetc(fp);

//读取下一个字符,判断:

:

=,若是关键词写入case或者?

则必要

if(ch=='=')

{

TOKEN[1]=ch;

out(23,TOKEN);

}

else

{

fseek(fp,-1,1);

out(22,TOKEN);

}

break;

case'+':

ch=fgetc(fp);

//读取下一个字符,判断+,+=

if(ch=='=')

{

TOKEN[1]=ch;

out(25,TOKEN);

}

else

{

fseek(fp,-1,1);

out(24,TOKEN);

}

break;

case'-':

ch=fgetc(fp);

//读取下一个字符,判断-,-=

if(ch=='=')

{

TOKEN[1]=ch;

out(27,TOKEN);

}

else

{

fseek(fp,-1,1);

out(26,TOKEN);

}

break;

case'*':

ch=fgetc(fp);

//读取下一个字符,判断*,*=

if(ch=='=')

{

TOKEN[1]=ch;

out(29,TOKEN);

}

else

{

fseek(fp,-1,1);

out(28,TOKEN);

}

break;

case'/':

ch=fgetc(fp);

//读取下一个字符,判断/,/=

if(ch=='=')

{

TOKEN[1]=ch;

out(31,TOKEN);

}

else

{

fseek(fp,-1,1);

out(30,TOKEN);

}

break;

case'#':

out(32,TOKEN);

break;

case'(':

out(33,TOKEN);

break;

case')':

out(34,TOKEN);

break;

//判断#(头文件)

default:

report_error();

break;

}

}

}

//扫描函数

intmain(void)

{

FILE*fp;

charch;

if((fp=fopen(".\\tk.txt","r"))==NULL)

//取当前目录下的tk.txt文件的第一个字符

{

fprintf(stderr,"erroropening!

\n");

//格式化输出到流

//错误打印到屏幕上Bydefault,standardinputisreadfromthekeyboard,whilestandardoutputand//standarderrorareprintedtothescreen

exit

(1);

//非0,非正常退出

}

do

{

ch=fgetc(fp);

if(ch=='$')

break;

//作为文件结尾

elseif(ch=='')

scanner(fp);

//空格略过

else

{

fseek(fp,-1,1);

scanner(fp);

}

//扫描

}while(ch!

='$');

system("pause");

return0;

}

三、主要仪器设备及耗材

PC,VisualC++6.0

 

第二部分:

实验调试与结果分析(可加页)

一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)

按照要求编写完代码之后,首先检查一下有没有错误语法错误,然后编译连接运行,重复输出多种表达式及c语言代码,寻找出错误并且改正,力求输出到边到脚,考虑多种情况来保证代码的完善性。

由于c语言中头文件等需要用到#符,则本程序以$作为结尾符号。

二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)

(1)输入:

输出

(2)输入

输出

三.实验小结、建议及体会

词法分析(英语:

lexicalanalysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。

进行词法分析的程序或者函数叫作词法分析器(Lexicalanalyzer,简称Lexer),也叫扫描器(Scanner)。

词法分析器一般以函数的形式存在,供语法分析器调用。

在本次实验中,通过对代码的编写,完善和调试,我逐渐深刻地明白了编译原理的工作流程,是怎样一步一步地解析一种高级语言到中间代码的。

同样的转化思想可以应用到生活的方方面面,语言或者说事物的本质才会被慢慢挖掘出来。

实验课程名称:

编译原理

实验项目名称

赋值语句的翻译程序设计

实验成绩

实验者

专业班级

组别

同组者

实验日期

第一部分:

实验分析与设计(可加页)

一、实验内容描述(问题域描述)

1.实验目的

(1)通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

(2)选择最有代表性的语法分析方法,如递归子程序法;选择对各种常见程序语言都具备的语法结构,如赋值语句,特别是表达式,作为分析对象。

2.实验准备

微机CPUP4以上,256M以上内存,安装好C语言,或C++,或VisualC++.

3.实验时间

4学时

4.实验内容

构造表达式部分的语法分析器。

分析对象〈算术表达式〉的BNF定义如下:

<表达式>:

:

=[+|-]<项>{<加法运算符><项>}

<项>:

:

=<因子>{<乘法运算符><因子>}

<因子>:

:

=<标识符>|<无符号整数>|‘(’<表达式>‘)’

<加法运算符>:

:

=+|-

<乘法运算符>:

:

=*|/

<关系运算符>:

:

==|#|<|<=|>|>=

5.实验要求

将实验一“词法分析”的输出结果,作为表达式语法分析器的输入,进行语法解析,

对于语法正确的表达式,报告“语法正确”;    

对于语法错误的表达式,报告“语法错误”,指出错误原因。

把语法分析器设计成一个独立一遍的过程。

语法分析器的编写方法采用递归子程序法。

6.输入输出

输入:

PL/0表达式,用实验一的输出形式作为输入。

例如:

对于PL/0表达式,(a+15)*b用下列形式作为输入:

(lparen,()

(ident,a)

(plus,+)

(number,15)

(rparen,))

(times,*)

(ident,b)

输出:

对于语法正确的表达式,报告“语法正确”;

对于语法错误的表达式,报告“语法错误”,指出错误原因。

二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)

实验基本原理:

采用递归子程序法分析输入表达式的语法。

实验源代码如下:

#include

#include

//头文件

charread();

voidwrite();

charlookhead;

voidE();

voidT();

voidG();

voidS();

voidF();

voidmatch(charch);

voiderror();

//函数声明

charstring[10];

inttop;

//全局变量

intmain()

{

write();

//写入实验一的结果数据

lookhead=read();

//读取数据

E();

//递归子程序法语法分析

puts(string);

printf("为合法字符串!

\n");

//按要求输出判断结果

system("pause");

return0;

}

voidE()

{

printf("E->TG\n");

T();

G();

}

voidG()

{

if(lookhead=='+')

{

printf("G->+TG\n");

match('+');

T();

G();

}

elseif(lookhead=='-')

{

printf("G->-TG\n");

match('-');

T();

G();

}

else

{

printf("G->ε\n");

}

}

//+,-符号的语法分析判断

voidT()

{

printf("T->FS\n");

F();

S();

}

voidS()

{

if(lookhead=='*')

{

printf("s->*FS\n");

match('*');

F();

S();

}

elseif(lookhead=='/')

{

printf("S->/FS\n");

match('/');

}

else

{

printf("S->ε\n");

}

}

//乘除符号的语法分析判断

voidF()

{

if(lookhead=='(')

{

printf("F->(E)\n");

match('(');

E();

match(')');

}

elseif(lookhead=='i')

{

match('i');

}

else

error();

}

//(,)和字符的语法分析判断

voidmatch(charch)

{

lookhead=read();

}

//读取下一字符串

voidwrite()

{

intx;

chary,str[100];

top=0;

printf("请输入待分析字符串序列:

\n");

do

{

gets(str);

sscanf(str,"(%d,%c)",&x,&y);

string[top]=y;

top++;

}while(y!

='$');

string[--top]='\0';

top=0;

}

//按要求输入字符串

charread()

{

charcha;

cha=string[top];

top++;

returncha;

}

//挨个读字符串

voiderror()

{

puts(string);

printf("为非法字符串!

\n");

system("pause");

exit(0);

}

//出错处理,按要求输出

三、主要仪器设备及耗材

PC,MiscrosoftVisualC++6.0

第二部分:

实验调试与结果分析(可加页)

一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)

编写完代码之后,首先检查一下有没有简单的语法错误登,然后编译连接运行,通过dos自带的复制粘贴,输入实验一的结果,得到实验二的语法分析过程和结果。

秉着简洁明了的原则,本程序能识别表达式即可,故输入实验一结果一得到的代码。

最后用(1,$)来结束输入。

二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)

输入

分析结果

 

三、实验小结、建议及体会

语法分析是词法分析的下一个阶段。

语法分析的任务是识别单词符号是否符合给定的语法规则。

语法分析所依据的是语言的语法规则,即描述程序结构的规则。

通过语法分析确定输入串是否构成一个语法上正确的程序。

通过本次的程序编写和调试,我深刻明白了语法分析的原理和过程。

本程序采用的递归子程序法相对简单直观,易于构造,但要求比较苛刻,必须满足LL

(1)文法,且递归调用较多,考虑得不大全面,未能输出错误原因。

需要改进的路还很长。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2