编译原理实验报告:实验一编写词法分析程序 语义分析实验报告

 并将其指针

 并将其指针 pint 加 1;另一个名为 error ,当出现错误时,调用这个过程,

 编译原理实验报告

 实验名称:

 实验一编写词法分析程序

 实验类型:

 验证型实验

 指导教师:

 何中胜

 专业班级:

 13软件四

 姓 名:

 丁越

 学 号:

 电子邮箱:

 实验地点:

 秋白楼B720

 实验成绩:

 日期:2016年3月18 日

 一、实验目的 通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析 程序所用的工具自动机,进一步理解自动机理论。掌握文法转换成自动机的技术及有穷自动机实现的方 法。确定词法分析器的输出形式及标识符与关键字的区分方法。加深对课堂教学的理解;提高词法分析 方法的实践能力。通过本实验,应达到以下目标:

 1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。

 2、掌握词法分析的实现方法。

 3、上机调试编出的词法分析程序。

 二、实验过程

 以编写PASCAL子集的词法分析程序为例

 1. 理论部分

 (1)主程序设计考虑 主程序的说明部分为各种表格和变量安排空间。

 数组 k 为关键字表,每个数组元素存放一个关键字。采用定长的方式,较短的关键字 后面补空格。

 P 数组存放分界符。为了简单起见,分界符、算术运算符和关系运算符都放在 p 表中

 (编程时,还应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。

 id 和 ci 数组分别存放标识符和常数。

 instring 数组为输入源程序的单词缓存。

 outtoken 记录为输出内部表示缓存。

 还有一些为造表填表设置的变量。

 主程序开始后,先以人工方式输入关键字,造 k 表;再输入分界符等造 p 表。

 主程序的工作部分设计成便于调试的循环结构。每个循环处理一个单词;接收键盘上 送来的一个单词;调用词法分析过程;输出每个单词的内部码。

 ⑵词法分析过程考虑 将词法分析程序设计成独立一遍扫描源程序的结构。其流程图见图 1-1。

 图 1-1

 该过程取名为 lexical ,它根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,

 产生类号:以字符 k表示关键字;i表示标识符;c表示常数;p表示分界符;s表示运算符(编程时类 号分别为 1 , 2,3, 4,5)。

 对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有 该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组 id 中,将常数

 变为二进制形式存入数组中 ci 中,并记录其在表中的位置。

 lexical 过程中嵌有两个小过程: 一个名为 getchar ,其功能为从 instring 中按顺序取出一个字符,

 输出错误编号

 2.实践部分

 所有识别岀的单词都用两个字节的等长表示,称为内部码。第一个字节为 t,第二个字节为i。t为

 单词的种类。关键字的 t=1 ;分界符的t=2 ;算术运算符的t=3 ;关系运算符的t=4 ;无符号数的t=5;

 标识符的t=6 o i为该单词在各自表中的指针或内部码值。表 1-1为关键字表;表1-2为分界符表;表

 1-3为算术运算符的i值;表1-4为关系运算符的i值。

 关键字表

 指针丨

 关键字

 0

 BEGIN

 1

 DO

 2

 ELSE

 3

 EN

 4

 IF

 5

 THEN

 6

 VAR

 7

 WHILE

 表1-1

 分界符表

 指针丨

 分界符

 0

 1

 2

 o

 3

 : =

 4

 (

 5

 )

 6

 :

 7

 II

 表1-2

 算术运算符

 指针丨

 算术运算符

 10H

 +

 11H

 -

 20H

 *

 21H

 /

 表1-3

 关系运算符

 指针l

 关系运算符

 OOH

 <

 01H

 <=

 02H

 —

 03H

 >

 04H

 >—

 05H

 <>

 表1-4

 常数表和标识符表是在编译过程中建立起来的。其 i值是根据它们在源程序中出现的顺序确定的另外可以根据PascaI语言子集中岀现其它单词情况进行自行修改以上表格。

 最后编写程序进行词法分析,判断目标在哪个表中并进行显示。

 三、实验结果

 1.测试数据

 数据共分为3组,分别如下:

 第一组数据

 var i,j,k:i nteger;

 begin

 i:=5;

 j:=6;

 k:=i+j;

 write("k=",k);

 End.

 第二组数据

 var i,sum:i nteger;

 begin

 sum:=0;

 for i:=1 to 10 do

 begin

 sum:=sum+i;

 en d;

 write In ("sum=",sum);

 End.

 第三组数据 var weight,price:real; begin

 write("please input weight: ");

 readln(weight);

 if weight<10

 then

 price=5;

 else

 price=5+(weight-10)*;

 writeln("price=",price);

 End.

 这三组数据都是通过文件“”读入到程序中,通过程序一一读取文件中的数据进行分析,程序分析 时要注意所属的类型。

 2. 测试结果 以上三组数据测试结果通过控制台显示,显示时要根据表进行分类,不同的表有不同的标号,具体 显示如图 1-1 , 1-2 ,1-3 ,和1-4 所示:

 第一组数据

 图 1-2

 第二组数据

 图 1-3

 第三组数据

 图 1-4

 图 1-4 (接图 1-5 )

 四、讨论与分析

 实验结果的每一条数据可分为两个部分。第一个部分是识别出的单词部分,第二个部分(小括号内 的部分)则显示了单词在表中的位置,括号内第一个数字表示是第几张表,第二个数字代表单词在表的 位置。

 实验结果与预期结果一致。

 该实验证明了通过其他语言来编译一种语言的词法分析器是可行的。

 实验结果说明了词法分析是作为相对独立的阶段来完成的。在词法分析过程中,编译程序是通过操 作系统从外部介质中读取源程序文件中的各个字符的。同时,为正确地识别单词,有时还需进行超前搜 索和回退字符等操作。

 因此,为了提高读盘效率和便于扫描器进行工作,通常可采用缓冲输入的方案,即在内存中设置一 个适当大小的输入缓冲区,让操作系统直接将磁盘上的源程序字符串分批送入此缓冲区中,供扫描器进 行处理。

 五、附录: 关键代码部分如下: bool isKey( string str, int &syn) /* 判断是否为关键字,若是传回相应关键码的种别名 */

 {

 int i;

 for(i=0; i<7; i++)

 {

 if(str == key[i])

 {

 syn = i + 1;

 return true;

 }

 }

 return false;

 }

 bool isLetter(char c) .

 // 列举出现在表 2,3,4 中的字符进行分析,此处略

 }

 }

 }

 int main()// 主函数

 {

 FILE *fileP;

 fileP = fopen("", "r");// 读文件

 cout << " 词法分析如下 " << endl;

 analyse(fileP);// 调用函数 analyse

 return 0;

 }

 六、实验者自评 总的来说,实验过程还算顺利,遇到的一系列问题都得到比较好的解决,当然分析器还有很大的改

 进空间,这里只是简单的依照给定的图实现了 PASCAL子集的词法分析。虽说如此,但是最后能够完成还

 是感觉是不太容易的。

 通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟

 根据识别语言单词的状态转换图, 使用某种高级语言 (例悉了构造词法分析程序的手工方式的相关原理,

 根据识别语言单词的状态转换图, 使用某种高级语言 (例

 如C语言)直接编写此法分析程序。

推荐访问:实验 词法 编译 编写 原理