当前位置:文档之家› 编译原理综合性实验:词法分析的设计

编译原理综合性实验:词法分析的设计

编译原理综合性实验:词法分析的设计
编译原理综合性实验:词法分析的设计

《编译原理》综合性实验一:

词法分析的设计

实验目的:掌握词法分析的概念,设计方法,熟悉高级语言中词法的定义,词法分析程序的编写。

实验要求:在6学时内实现SAMPLE语言的词法分析器,要求用VC窗口界面实现。

实验内容:分为3次实验完成。

1.1词法分析器的结构和主要任务

【输入输出接口】

图1-1 词法分析器的输入输出界面

词法分析程序的主要任务是从左到右扫描每行源程序,拼成单词,换成统一的内部表示(token)输出,送给语法分析器。具体包括:

–组织源程序的输入;

–按规则拼单词,并转换成二元形式;

–滤掉空白符,跳过注释、换行符及一些无用的符号(如字符常数的引号)

–进行行列计数,用于指出出错的行列号,并复制出错部分;

–列表打印源程序;

–发现并定位词法错误;

–生成符号表。token文件和符号表用作语法分析的输入部分

【条件限制】

本实验可以作如下假定:

(1)假定SAMPLE语言采用自由格式书写;

(2)可以使用注解,用/*……*/或者{……}标识,但注解不能插在单词内部,注解要

在一行内结束,若一行结束,没有遇到注释后面的结束标记,自动认为注释也结

束;

(3)一行可以有多个语句,一个语句也可以分布在多行中,单词之间和语句之间可以

插入任意空格,单词中间不能有空白符号,单词中间也不能有回车换行符,即单

词不能跨行书写;

(4)关键字都是保留字。

1.2 词法分析程序的总体设计

图1-2 词法分析程序的顶层数据流图

图1-2是词法分析程序的顶层数据流图,即是词法分析程序的输入输出界面图,由此可以看出词法分析程序的功能就是从源程序中读入一个个字符,依据一定的构词规则,识别出各类有用的单词。其中源程序清单和错误信息从屏幕、打印机或文件输出,其余文件均以顺序文件的形式输出到外存储器上,以供下一阶段使用。由此可以得到更详细的数据流图,如图1-3。

图1-3 词法分析程序的详细数据流图

在上面的数据流图中,各个加工处理完成的功能如下:

加工1.1(读一行并打印):收到读下一行命令后,从源程序读入一行,装入缓冲区,行计数,并打印。在这里需要注意的是,回车换行在源程序(文本文件)中用两个字符0D0AH 来表示,而用高级语言(C语言)读入内存后,就用一个字符0AH来表示,这是在用高级

语言编写词法分析器时常被忽略导致错误的原因。

加工1.2(读一非空字符):收到读一字符命令后,从缓冲区读人一非空字符,列计数。若缓冲区已空,则再读—行,列计数置0。

加工1.3(分类):根据单词的首字符以决定对不同类单词的处理。

加工1.4(识别标识符);当输入字母时,开始识别标识符或关键宇,边拼写边从缓冲区读入下一符号,当读入一非字母数字符号时,标识符识别完成,但已多读入一个符号,所以列记数回退。然后查关键字表,判断拼出的符号串是否为关键字。若是关键字,输出其种别码。否则识别的单词就是标识符,同时输出标识符及其种别码。

加工1.5(识别常数):当输入数字时,开始识别整数或实数。边拼写边读入下一符号,当遇到“.”时,还要继续拼写该常数(实数情况)。如果遇到E,要识别带指数的常数,当遇到其它非数字符号时,数字常数拼写完毕,列计数也要退1。输出常数及其种别码。

加工1.6(处理注解);当输入“/”时,开始识别注解或除号,若是注解时,最后两个连续读出的符号是“*/”,不需再读下一符号,列计数不变。当判定是除号“/”时,已多读入一字符,列计数—1,输出“/”的种别码。

加工1.7(识别分界符):识别其它界符,对于<、>、:、|、·等符号,还需要再读入下一符号,判别是否为双界符。若不是,列计数—1,输出单词的种别码。

加工1.8(识别文字常数):当输入引号时,引号忽略,开始拼写字符常数,不断拼读下一符号,搜索下一个引号,当读入第二个引号时,字符常数拼写结束。最后列计数不减1,然后输出该常数。

以上加工1.4~1.8都需要从缓冲区A每次读出一个字符,进行列计数。由于假定每个单词不跨行,所以不用考虑从源程序中读出下一行到缓冲区的功能。

加工1.9(输出TOKEN):对各种界符与关键字输出其相应的二元式(TOKEN),对常数与标识符则让它流入下一个加工。

加工2(查填符号表):如果是标识符或字符常数,首先查看名字栏和类型栏(字符常数的类型栏中填有“字符常数”,标识符栏的类型栏空白)判断有无同名和同类型的入口。如果有同名入口P1,则把P1作为TOKEN的自身值填入它的二元式中;如果不同名,则将字符中存入字符串表中,把它的长度和在字符串表中的开始位置及其类型(标识符为空白)填入符号表的新入口P中,并把P作为TOKEN的自身值填入的二元式中。

对数字常数的处理如下:先查符号表V AL栏,若发现相同的常数则直接输出其二元式。若表内无相同的常数,则将数字常数填入符号表内,在TYPE栏内填入整型或实型,然后输出其二元式。二元式中包含该常数在符号表中的入口。

1.3 词法分析程序的详细设计

图1-3的数据流图属于输入-变换-输出形式的变换型数据流图,但加工1.3—1.9构成了典型的事务处理型数据流图。根据数据流图,可以得到词法分析程序的总体框架,如图1-4。

图1-4 词法分析器的程序框架

1.4 实验步骤

【步骤一编写词法分析的总控程序】

(1) 编写词法分析的主函数scanner()

词法分析的总控程序就是图2-4的程序框架。词法分析中要使用的函数将逐步在下面

的三个实验中分别实现。要实现词法分析的功能,必须按照总控程序的安排,在适当的位置进行调用,当所有的函数都实现了,就构成了一个完整的词法分析程序。主函数的描述如下:

a.打开输入源文件,设置行计数器为0;

b.如果源文件没有结束,读入一行到string,行计数+1,设置列计数器为0;

c.如果缓冲区非空,将缓冲区中的符号串分割为一个一个的单词,否则转b。(区分一个

单词结束的方法是:从缓冲区读入一个非空字符,列计数+1,继续读入字符(每读入一个字符,列计数+1),直到一个单词读完(单词结束的标志是单词分隔符,如空格符号、空白符号、换行符和界符等,但单词的分隔符不属于该单词,读入的符号串是否可以构成一个正确的单词,要根据单词的构成规则来判断,不同类别的单词其构词规则不一样,这样就可以根据不同类别的单词的的识别函数来判断相应的单词构成是否有错误。单词的类别是根据读入的该单词的首字符来判断的,可以单独写一个分类函数,根据首字符判断该单词属于关键字、标识符、常数、运算符和界符中的哪一类)。

d.将识别出来的单词及其种别码写入Token字表中。

e.根据单词的类别,进行不同的后期处理,如果是标识符或常数,需要将其唯一值填入

符号表中。

g.如果源文件已结束,关闭打开的源文件。

f.打印token字表和符号表到相应的文件中;

(2) 编写分类函数sort()

单词分为标识符、常数、关键字、运算符和界符,单词必须分类进行识别。根据读入该单词的第一个字符进行分类,判断该单词是属于哪一类。如图2-4,根据单词的分类结果调用相应的识别函数识别一个单词是否正确。

int sort(char ch)/* 传入参数ch为已读入的单词的第一个字符,据此进行分类*/ {

if ( isdigit(ch) ) return 常数;/*如果第一个字符是数字,则是数;*/

else if (isalpha(ch)) return 标识符;/*如果第一个字符是字母,则是标识符

或关键字*/

else if (ch == '/') return 注释; /*如果读入的是/,则可能是注释和除号*/

else if (ch =='\'') return 字符常数; 如果第一个字符是’,则是字符常数;

else if (isdelimeter(ch)) return 界符; /*如果出现了定义中的其它符号,

则是界符*/

else return OTHER; /*否则出错处理,出现不识别的字符*/

}

(3) 实验思考题

1.为什么要编写分类函数,在词法分析器中起什么作用?

2.词法分析的功能是什么?你编写的词法分析程序完成了哪些功能?你认为还有哪些功能是应该实现而你没有实现的功能?

3.词法分析程序能给出哪些错误?

4.符号表的作用是什么?

5.词法分析器是如何定位错误的?

【步骤二定义符号表编写查找和插入函数】

(1) 定义关键字和界符表

每一种已经定义的语言的关键字和界符都是固定的,为了给出单词的种别码,我们在编写SAMPLE语言的词法分析器时采取关键字和界符一符一种,标识符、整型常数、实型常数、字符型常数分别给一个种别码,再根据其值定义判断。Sample语言中的单词(关键字、界符、数的类型)的种别码如表1-1。

表1-1 SAMPLE语言单词的编码

类别

单词种别码

单词种别码

单词种别码program 1 not 21 ; 39 var 2 and 22 , 40 integer 3 or 23 ‘ 41 bool 4 + 24 “ 42 real 5 - 25 // 43 char 6 * 26 /* 44 const 7 / 27 */ 45 begin 8 < 28 ; 46 if 9 > 29 ( 47 then 10 <= 30 ) 48 else 11 >= 31

. 49 while 12 = 32

do 13

:= 33

repeat 14 整常数35

id 34

until 15 实常数36

for 16 字符常数37

关键字

to 17 常

布尔常数38

在C/C++语言中,这些表格可以使用结构数组定义,在pascal中可以使用记录数组定义,也可以使用其它方法来定义,如直接定义成链表的形式,可根据所设计的总体结构自行选择定义方法,具体内容可以根据程序编写的方式采取初值输入方式或后期使用时再输入的方式。

上述表格可以定义成一个整体,也可以分成关键字、界符和各种常数表等多个部分分别定义。如在C语言中定义关键字如下:

struct entry { /*定义结构*/

char word[10]; /* 单词本身 */

int token; /* token 值 */

};

struct entry

keyword[]={"and",1,"array",2,"begin",3,"bool",4,"call",5,"case",6,

"char",7,"do",9,"else",10 }; /*存放该语言能识别的关键字*/

(2) 编写查找函数iskeyword(char * str)和isdelimeter(char * str)判断

给定的符号串是否是关键字和界符

iskeyword(char * str)函数的功能是:在上述给定的关键字表中查找指定的字符串str是否存在,若存在,返回其种别码(token值),否则返回0。

查找函数可以使用顺序查找,也可以使用折半查找。

例如:使用顺序查找方法查找给定单词key是否是关键字的函数原型和算法描述如下:

int iskeyword (char * str)/*设keyword为所有关键字列表*/

/*该函数返回0表示str不是关键字,不为0 表示str是关键字*/

{

(关键字表没有结束)

while

if (str = keyword[i].word )

返回keyword.token; /* 表示str是关键字 */

else i++;

返回0; /* 表示str不是关键字 */

}

同样编写查找是否是界符的函数isdelimeter()。

(3) 定义符号表

编译过程中编译程序需要不断汇集和反复查证出现在源程序中各种名字的属性和特征等有关信息。这些信息通常记录在符号表中。符号表中的每一项一般包含两部分:名字,与此名字有关的信息,如类型,种属,值等。符号表主要在词法或语法分析阶段生成,可能用于语义检查、产生中间代码以及最终生成目标代码等不同阶段。

当从源程序中识别出一个标识符或常数,就要检查符号表中是否已经存在该标识符或常数,若不存在,就应将其加入符号表,若存在就不加入。符号表可以和常数表合在一起,这可能增加查填符号表的复杂性。也可以将符号表、常数表分开建立,方便查填。

定义SAMPLE语言的符号表的格式如下表,其中name项包含两个内容,一个是单词本身,一个是它的长度。可以直接将单词放在名字栏,也可以另外使用一个字符串数组,将单词本身放在字符串中,在符号表中填入该单词在字符串中的指针。

NAME TOKEN TYPE KIND V AL ADDR

example 7 34 整简变

符号表可以使用结构数组来实现,也可以使用链表来实现。

(4) 编写查找符号表的函数isexist_sym(char *str),查找指定的字

符串是否已在符号表中

当识别出的单词是字符常数、实常数、整型常数或标识符时,就应该查找该字符串是否在符号表中已存在,如果不存在,就需将它加入符号表中。查找方法可以是顺序查找或折半查找,这取决于符号表的组织方式。如果符号表按照单词在文件中出现的先后顺序放入符号表中,只能采取顺序查找,如果单词在放入符号表中按照单词的大小顺序排列,可以使用折半查找方法。

使用顺序查找方法查找sym是否存在与符号表symbol中的函数描述如下:

int isexist_sym(char *str) /* 假定symbol数组是符号表*/

{

(符号表没有结束)

while

if (str = symbol[i].name) 返回i; /*表示已查到*/

否则返回0; /*表示没有查找到*/

}

(5) 编写填入符号表的函数ins_sym(char *str, int token)

若上述第(4)步中查找某字符串str不在符号表中,就将给定的字符串填入符号表。填入方法可以采用顺序增加序号的方法加入到表的尾部,也可以采用排序的方法将其按顺序填入某个位置,采取什么方式将直接影响查找方法。

将字符串sym填入符号表symbol的函数描述如下:

ins_sym(char *str, int token) /*将字符串str插入符号表symbol中*/

{

找到符号表的最后一条记录;

symbol[i].name = str;

symbol[i].token = token;

设置symbol[i]的其它属性;

}

(6) 编写将符号表的内容写到文件中的函数write_sym

在多遍扫描的编译程序中,词法分析作为单独的一遍扫描。生成的符号表需要在下一个阶段中再使用,因此在词法分析运行完毕,应该将符号表的内容写入文件中,以便在语法或语义分析阶段再次读入,或者将符号表的内容显示在屏幕上。将符号表的内容写入文件的方式是在按符号表中现有内容的顺序,逐行打印。函数描述如下:

write_sym() /* 将符号表symbol中的内容写入文件*/

打开输出的符号表sym_file文件,用fp指向;

while (表没有结束) {

fprintf (fp, “%s %d ”, symbol[i].name, symbol[i].token);

/*可以将符号表一行中的名字,类型,种属,值等写入文件*/

i++;

}

关闭符号表文件;

}

(7) 定义一个token字表

当使用多遍扫描方式编写编译程序时,词法分析后必须生成一个单词表,格式如下,每当从源文件中识别出一个单词,不管是关键字、标识符、常数或界符,找到其种别码后,都应将它填入token字表(token_table)中。

word(单词本身)token(单词的种别)

同样可以使用结构数组或链表定义。

(8) 编写一个向token字表中填入内容的函数ins_token(char *str, int

token)

每当从源文件中识别出一个单词,找到其种别码后,按顺序填入到token字表中。填入函数描述类似于符号表的填入,只是只能采用顺序填入,每次填入时总是填入表的尾部。

ins_token(char *str, int token) /* 将str放入到token_table中 */

{

token_table[lastline].word

str;

=

token;

token_table[lastline].token

=

lastline

/*lastline表示生成的当前单词序号*/

+1;

=

lastline

/*可以使用全局变量来记录*/

}

(9) 编写一个函数,将token字表的内容写到文件中的函数

write_token

词法分析的结果就是生成相应的token文件,它将作为语法分析的输入。因此,必须将上述的token_table表输出到文件中。

函数原型及算法描述如下:

write_token( )

打开输出的token文件,用fp指向;

while (表没有结束) {

fprintf(fp,”%s %d”,token_table[i].word, token_table[i].token);

i++;

}

关闭token文件;

}

(10) 实验思考题

1.查找给定的字符串是否在关键字表中有哪些方法?并说明其优缺点?

2.你是如何比较一个字符串是否是关键字的?

3.关键字表必须定义为结构数组吗?还可以如何定义?

4.符号表的作用是什么,如何定义符号表,对符号表有哪些基本操作?

5.Token文件的作用是什么,需要包含哪些信息?

6.符号表和token文件中的内容有哪些相同和不同点?

【步骤三单词识别函数的编写】

(1) 编写识别标识符的函数recog_id(char ch)

若第一个字符是字母,从缓冲区的当前位置开始读入字符,读到不是字母或数字的符号为止,识别它是否是一个标识符(或关键字)。识别方法可以使用状态转换图,也可以使用正规式技术,还可以用其它方式自己编写。通过识别,若不能构成标识符,提示出错信息;若是,再利用实验二的结果查找该字符串是否是关键字,若是关键字,返回关键字的种别码;若不是关键字,返回标识符的种别码。

对于识别较为复杂的标识符的模块,可以先画出该单词的状态转换图或语法图,然后再根据状态图给出模块详细说明,标识符的状态转换图如下:

图中0表示初态,双圈表示的状态是终态。当有引出“其它”字样的弧,表示读入了一个除该状态所有别的弧上的符号外,另外一个在字符集内的符号。有时可能需要回退该符号。

下面是从一个字符串中识别一个标识符的算法描述:

recogid(char ch) /* ch 为给定字符串的第一个字符*/

{

char state='0';

while (state!=2 ){

switch (state){

case '0':/*若当前是0状态,若读入一个字母,转向1状态*/

if (isalpha(ch)) state='1'; else error();

break;

case '1': /*若当前是1状态,若读入字母或数字,仍为1状态*/

if ( isalnum(ch) && (i<8) ) state='1';

else { state = 2;

colno--; /*退回当前读入的字符*/

}

}

ch = string[colno++]; /*将下一个符号读入ch中*/

}

}

(2) 编写识别数的函数recogdig(char ch)

对给定的字符串(不含空白),识别它是否是数,若不是,提示出错信息;若是,识别是整数、小数、或是指数,分别返回相应代码和字符串本身。

数分为多种,下面是识别不带正负号,带指数的实常数的状态转换图:

其它

根据这个状态转换图可以编写识别实常数的识别函数。算法描述如下:

int recogdig(char ch)/*识别常数(含整数和实数)*/

{

char state='0'; /*初始状态为0*/

while (state!=7) {

switch (state){

case '0': if (isdigit(ch)) state='1'; else error(); break;/*读入一个数字*/

case '1': if (isdigit(ch)) state='1';/*仍然读入数字*/

else if (ch =='.') state='2'; /*读入小数点,识别实数*/

else if ((ch =='e') ||(ch=='E')) state='4'; /*读入e或E,带指数*/

else { /* 已识别完整数,返回 */

colno--;

返回整数类型;

}

break;

case '2': if (isdigit(ch)) state='3'; /* 读入数字*/

error();

else

break;

case '3': if (isdigit(ch)) state='3'; /* 读入数字*/

else if ((ch=='E') || (ch=='e')) state ='4'; /*读入e或E,指数*/

else { /* 已识别完带小数的实数,返回 */

colno--;

返回实数类型;

}

break;

case '4': if (isdigit(ch)) state='6'; /*读入数字*/

else if (issign(ch)) state = '5'; /*读入+,-符号*/

error();

else

break;

case '5': if (isdigit(ch)) state='6'; /*读入数字*/

error();

else

break;

case '6': if (isdigit(ch)) state='6'; /*读入数字*/

else {/* 已识别完带指数的实数,返回 */

colno--;

state = 7;

返回实数类型;

}

}

str[colno++];/*读入下一个符号*/

ch

=

}

}

(3) 编写识别界符的函数recogdel

对给定首字符的字符串(不含空白),识别它是否是界符(单界符和双界符),若不是,提示出错信息;若是,识别是单界符和双界符,分别返回单界符和双界符相应的代码和字符串本身。

类似于查找是否是关键字,该函数从界符表中查找某字符串是否存在即可。函数可以参照前面的(1)进行编写。

(4) 编写识别字符常数的函数recogstr

对给定首字符(‘)的字符串(不含空白),识别它是否是字符常数,若不是,提示出错信息;若是,去掉两边的单引号,返回剩下的字符串和字符常数的代码。字符常数的状态转换图如下,从读入的第一个符号’开始表明是字符常数:

函数描述如下:

int recogstr (char ch) /* 进入此函数时,ch 为单引号*/

{

char state='0'; /*初始状态*/

while (state!=2)

{ switch (state) {

case '0': state='1'; break; /*由于进入此函数时,ch 为单引号,

所以不需再读入*/

case '1': if (ch=='\'') return colno;/*读到最后的一个单引号,结束*/

/*

否则一直是常数部分 */

state='1';

else

}

ch = string[colno++]; /* 读取下一个符号*/

}

}

(5) 编写识别并去掉注释的函数handlecom

带注释的字符串是以/*开始,*/结束的字符串,若是这种形状,去掉它,识别的状态转换图如下:

函数描述如下:

handlecom(char ch, int token)/*ch 为首先读入的/符号,token为返回值*/

{

读入一个符号;

if ( 该符号为* ) {

do {

读入一个符号放入ch1;

} while ( (ch1!= ‘*’) && 字符串没有结束)

if ( ch1 !不是行结束标志) {

读入下一个符号ch1;

if ch1 = ‘/’,则结束处理,token为‘’;

}

else

注释只在一行中有效,行结束也认为注释结束*/

‘’;

/*

token

=

}

返回token 为除号,并给出其种别码;

}

(6) 实验思考题

1.状态转换图有什么特点,如何画状态转换图?

2.你是如何判断一个给定的字符串是否是标识的?

3.分类编写的各个函数之间有什么关系?何时调用这些函数?

1.5 输入数据

输入源程序名称:Example.src

/*this is a sample program writing in sample language*/

program example1;

/*used for illustrating compiling process*/

var

a,b,c:integer;

x:char;

begin

if (a+c*3 > b) and (b>3) then c:=3;

x:=2+(3*a)-b*c*8;

if (2+3 >a) and (b>3) and (a>c) then c:=3;

for x := 1+2 to 3 do b:=100;

while a>b do c:=5;

repeat a:=10; until a>b;

end.

1.6 结果输出

下面是对上述输入源程序进行词法分析得到token文件(部分内容)和符号表的内容:Token表的内容如下:

program

example1

;

var

a

,

b

,

c

:

integer

;

……

;

……

end

.

符号表的内容如下:

(34, example1 )

(34, a )

(34, b )

(34, c )

(34, x )

(35, 3 )

(35, 2 )

(35, 8 )

(35, 1 )

(35, 100 )

(35, 5 )

(34, d )

(35, 15 )

(34, t )

(35, 10 )

编译原理实验--词法分析器

编译原理实验--词法分析器 实验一词法分析器设计 【实验目的】 1(熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。 2(复习高级语言,进一步加强用高级语言来解决实际问题的能力。 3(通过完成词法分析程序,了解词法分析的过程。 【实验内容】 用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符 串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字, 运算符,标识符,常数以及界符)输出。 【实验流程图】

【实验步骤】 1(提取pl/0文件中基本字的源代码 while((ch=fgetc(stream))!='.') { int k=-1; char a[SIZE]; int s=0; while(ch>='a' && ch<='z'||ch>='A' && ch<='Z') { if(ch>='A' && ch<='Z') ch+=32; a[++k]=(char)ch; ch=fgetc(stream); } for(int m=0;m<=12&&k!=-1;m++) for(int n=0;n<=k;n++) {

if(a[n]==wsym[m][n]) ++s; else s=0; if(s==(strlen(wsym[m]))) {printf("%s\t",wsym[m]);m=14;n=k+1;} } 2(提取pl/0文件中标识符的源代码 while((ch=fgetc(stream))!='.') { int k=-1; char a[SIZE]=" "; int s=0; while(ch>='a' && ch<='z'||ch>='A' && ch<='Z') { if(ch>='A' && ch<='Z') ch+=32; a[++k]=(char)ch; ch=fgetc(stream); } for(int m=0;m<=12&&k!=-1;m++) for(int n=0;n<=k;n++) { if(a[n]==wsym[m][n]) ++s; else s=0; if(s==(strlen(wsym[m]))) {m=14;n=k+1;} } if(m==13) for(m=0;a[m]!=NULL;m++) printf("%c ",a[m]);

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

编译原理实验报告实验名称:实验一编写词法分析程序 实验类型:验证型实验 指导教师:何中胜 专业班级: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中按顺序取出一个字符,并将其指针pint加1;另一个名为error,当出现错误时,调用这个过程, 输出错误编号。 2.实践部分

编译原理词法分析器语法分析器实验报告

编译技术 班级网络0802 学号3080610052姓名叶晨舟 指导老师朱玉全2011年 7 月 4 日

一、目的 编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。 二、任务及要求 基本要求: 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 其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。 再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为

实验1-3-《编译原理》词法分析程序设计方案

实验1-3 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式; 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 三、实验要求 1.能对任何S语言源程序进行分析 在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。 2.能检查并处理某些词法分析错误 词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。 本实验要求处理以下两种错误(编号分别为1,2): 1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。 2:源程序文件结束而注释未结束。注释格式为:/* …… */ 四、保留字和特殊符号表

编译原理实验词法分析实验报告

编译技术实验报告 实验题目:词法分析 学院:信息学院 专业:计算机科学与技术学号: 姓名:

一、实验目的 (1)理解词法分析的功能; (2)理解词法分析的实现方法; 二、实验内容 PL0的文法如下 …< >?为非终结符。 …::=? 该符号的左部由右部定义,可读作“定义为”。 …|? 表示…或?,为左部可由多个右部定义。 …{ }? 表示花括号内的语法成分可以重复。在不加上下界时可重复0到任意次 数,有上下界时可重复次数的限制。 …[ ]? 表示方括号内的成分为任选项。 …( )? 表示圆括号内的成分优先。 上述符号为“元符号”,文法用上述符号作为文法符号时需要用引号…?括起。 〈程序〉∷=〈分程序〉. 〈分程序〉∷= [〈变量说明部分〉][〈过程说明部分〉]〈语句〉 〈变量说明部分〉∷=V AR〈标识符〉{,〈标识符〉}:INTEGER; 〈无符号整数〉∷=〈数字〉{〈数字〉} 〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉} 〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉}; 〈过程首部〉∷=PROCEDURE〈标识符〉; 〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉 〈赋值语句〉∷=〈标识符〉∶=〈表达式〉 〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END 〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉 〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉} 〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉} 〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')' 〈加法运算符〉∷=+|- 〈乘法运算符〉∷=* 〈关系运算符〉∷=<>|=|<|<=|>|>= 〈条件语句〉∷=IF〈条件〉THEN〈语句〉 〈字母〉∷=a|b|…|X|Y|Z 〈数字〉∷=0|1|2|…|8|9 实现PL0的词法分析

编译原理词法分析和语法分析报告+代码(C语言版)

词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 2.2 各种单词符号对应的种别码: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图: 主程序示意图如图3-1所示。其中初始包括以下两个方面: ⑴关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 3.2 扫描子程序的算法思想: 首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

编译原理C语言词法分析器

编译原理 C语言词法分析器 一、实验题目 编制并调试C词法分析程序。 a.txt源代码: ?main() { int sum=0 ,it=1;/* Variable declaration*/ if (sum==1) it++; else it=it+2; }? 设计其词法分析程序,能识别出所有的关键字、标识符、常数、运算符(包括复合运算符,如++)、界符;能过滤掉源程序中的注释、空格、制表符、换行符;并且能够对一些词法规则的错误进行必要的处理,如:标识符只能由字母、数字和下划线组成,且第一个字符必须为字母或下划线。实验要求:要给出所分析语言的词法说明,相应的状态转换图,单词的种别编码方案,词法分析程序的主要算法思想等。 二、实验目的 1、理解词法分析在编译程序中的作用; 2、掌握词法分析程序的实现方法和技术; 3、加深对有穷自动机模型的理解。 三、主要函数 四、设计 1.主函数void main ( )

2. 初始化函数void load ( ) 3. 保留字及标识符判断函数void char_search(char *word) 4. 整数类型判断函数void inta_search(char *word) 5. 浮点类型判断函数void intb_search(char *word)

6. 字符串常量判断函数void cc_search(char *word) 7. 字符常量判断函数void c_search(char *word) 同4、5函数图 8.主扫描函数void scan ( ) 五、关键代码 #include #include

编译原理词法分析实验报告

词法分析器实验报告 一、实验目的 选择一种编程语言实现简单的词法分析程序,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 各种单词符号对应的种别码: 表各种单词符号对应的种别码 词法分析程序的功能: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根

据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 主程序示意图: 主程序示意图如图3-1所示。其中初始包括以下两个方面: ⑴关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 扫描子程序的算法思想: 首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn 用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告

实验一 一、实验名称:词法分析器的设计 二、实验目的:1,词法分析器能够识别简单语言的单词符号 2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。 三、实验要求:给出一个简单语言单词符号的种别编码词法分析器 四、实验原理: 1、词法分析程序的算法思想 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 2、程序流程图 (1 (2)扫描子程序

3

五、实验内容: 1、实验分析 编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。 2 实验词法分析器源程序: #include #include #include int i,j,k; char c,s,a[20],token[20]={'0'}; int letter(char s){ if((s>=97)&&(s<=122)) return(1); else return(0); } int digit(char s){ if((s>=48)&&(s<=57)) return(1); else return(0); } void get(){ s=a[i]; i=i+1; } void retract(){ i=i-1; } int lookup(char token[20]){ if(strcmp(token,"while")==0) return(1); else if(strcmp(token,"if")==0) return(2); else if(strcmp(token,"else")==0) return(3); else if(strcmp(token,"switch")==0) return(4); else if(strcmp(token,"case")==0) return(5); else return(0); } void main() { printf("please input string :\n"); i=0; do{i=i+1; scanf("%c",&a[i]);

编译原理实验词法分析语法分析

本代码只供学习参考: 词法分析源代码: #include #include #include using namespace std; string key[8]={"do","end","for","if","printf","scanf","then","while"}; string optr[4]={"+","-","*","/"}; string separator[6]={",",";","{","}","(",")"}; char ch; //判断是否为保留字 bool IsKey(string ss) { int i; for(i=0;i<8;i++) if(!strcmp(key[i].c_str(),ss.c_str())) return true; return false; } //字母判断函数 bool IsLetter(char c) { if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))) return true; return false; } //数字判断函数 bool IsDigit(char c) { if(c>='0'&&c<='9') return true; return false; } //运算符判断函数 bool IsOptr(string ss) { int i; for(i=0;i<4;i++) if(!strcmp(optr[i].c_str(),ss.c_str())) return true ; return false; } //分界符判断函数 bool IsSeparator(string ss) { int i; for(i=0;i<6;i++) if(!strcmp(separator[i].c_str(),ss.c_str()))

编译原理词法分析和语法分析报告+代码(C语言版)

信息工程学院实验报告(2010 ~2011 学年度第一学期) 姓名:柳冠天 学号:2081908318 班级:083

词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 := + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 2.2 各种单词符号对应的种别码: 表2.1 各种单词符号对应的种别码 2.3 词法分析程序的功能: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 3.1 主程序示意图:

编译原理实验报告2词法分析程序的设计

实验2 词法分析程序的设计 一、实验目的 掌握计算机语言的词法分析程序的开发方法。 二、实验内容 编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。 三、实验要求 1、根据以下的正规式,编制正规文法,画出状态图; 标识符<字母>(<字母>|<数字字符>)* 十进制整数0 | ((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*) 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和界符+ - * / > < = ( ) ; 关键字if then else while do 2、根据状态图,设计词法分析函数int scan( ),完成以下功能: 1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词, 2)以二元式形式输出单词<单词种类,单词属性> 其中单词种类用整数表示: 0:标识符 1:十进制整数 2:八进制整数 3:十六进制整数 运算符和界符,关键字采用一字一符,不编码 其中单词属性表示如下: 标识符,整数由于采用一类一符,属性用单词表示 运算符和界符,关键字采用一字一符,属性为空 3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。 四、实验环境 PC微机 DOS操作系统或Windows 操作系统 Turbo C 程序集成环境或Visual C++ 程序集成环境 五、实验步骤 1、根据正规式,画出状态转换图;

编译原理词法分析器语法分析课程设计报告书

《编译原理》 课程设计 院系信息科学与技术学院 专业软件工程 年级 2011级 学号 20112723 姓名林苾湲 西南交通大学信息科学与技术学院 2013年 12月

目录 课程设计1 词法分析器 (2) 1.1 设计题目 (2) 1.2 设计容 (2) 1.3 设计目的 (2) 1.4 设计环境 (2) 1.5 需求分析 (2) 1.6 概要设计 (2) 1.7 详细设计 (4) 1.8 编程调试 (5) 1.9 测试 (11) 1.10 结束语 (13) 课程设计2 赋值语句的解释程序设计 (14) 2.1 设计题目 (14) 2.2 设计容 (14) 2.3 设计目的 (14) 2.4 设计环境 (14) 2.5 需求分析 (15) 2.6 概要设计 (16) 2.7 详细设计 (16) 2.8 编程调试 (24) 2.9 测试 (24) 2.10 结束语 (25)

课程设计一词法分析器设计 一、设计题目 手工设计c语言的词法分析器(可以是c语言的子集)。 二、设计容 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 三、设计目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 四、设计环境 该课程设计包括的硬件和软件条件如下: 4.1.硬件 (1)Intel Core Duo CPU P8700 (2)存4G 4.2.软件 (1)Window 7 32位操作系统 (2)Microsoft Visual Studio c#开发平台 4.3.编程语言 C#语言 五、需求分析 5.1.源程序的预处理:源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。 5.2.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。单词符号可以划分成5中。 (1)标识符:用户自己定义的名字,常量名,变量名和过程名。 (2)常数:各种类型的常数。 (3) 保留字(关键字):如if、else、while、int、float等。 (4) 运算符:如+、-、*、<、>、=等。 (5)界符:如逗号、分号、括号等。 5.3.将所有合法的单词符号转化为便于计算机处理的二元组形式:(单词分类号,单词自身值);以图形化界面显示出来。 5.4.可选择性地将结果保存到文件中。 六、概要设计 6.1.数据类型 6.1.1.单词的分类:本词法分析器演示的是C语言的一个子集,故字符集如下:

编译原理实验(词法分析)

编译原理实验报告 实验一 实验题目:词法分析 指导老师:任姚鹏 专业班级:计算机科学与技术系网络工程方向1002班姓名:xxxx

2013年 4月13日 实验类型__验证性__ 实验室_软件实验室三__ 一、实验项目的目的和任务: 了解和掌握词法分析的方法,编程实现给定源语言程序的词法分析器,并利用该分析器扫描源语言程序的字符串,按照给定的词法规则,识别出单词符号作为输出,发现其中的词法错误。 二、实验内容: 1.设计一个简单的程序设计语言(语言中有若干运算符和分界符;有若干关健字;若干标识符及若干常数) 2.确定编译中使用的表格、词法分析器的输出形式、标识符与关键字的区分方法。 3.把词法分析器设计成一个独立的过程。 三、实验要求: 1.从键盘上输入源程序; 2.处理各单词,计算个单词的值和类型; 3.输出个单词名、单词的值和类型。 四、实验代码 #include #include char file[1024]; int length=0; int index; char keywords[][10]={"auto","short","int","long","float", "double","char","struct","union","enum", "typedef","const","unsigned","signed","extern", "register","static","volatile","void","default", "if","else","switch","case","for", "do","while","goto","continue","break", "sizeof","return"}; char limits[]={'(',')','[',']','{','}',',',';'}; char operators[]={'+', '-', '*', '/', '%', '>','<','&','|','^', '~','!','='}; //13 int IsChar(char ch) //是否是字符 { if ( (ch>='a'&&ch<='z') || (ch>='A'&&ch<='Z')) return 1; return 0;}

编译原理词法分析器

一、实验目的 了解词法分析程序的两种设计方法:1.根据状态转换图直接编程的方式;2.利用DFA 编写通用的词法分析程序。 二、实验内容及要求 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 2.编写DFA模拟程序 算法如下: DFA(S=S0,MOVE[][],F[],ALPHABET[]) /*S为状态,初值为DFA的初态,MOVE[][]为状态转换矩阵,F[] 为终态集,ALPHABET[] 为字母表,其中的字母顺序与MOVE[][] 中列标题的字母顺序一致。*/ { Char Wordbuffer[10]=“”//单词缓冲区置空 Nextchar=getchar();//读 i=0; while(nextchar!=NULL)//NULL代表此类单词 { if (nextcha r!∈ALPHABET[]){ERROR(“非法字符”),return(“非法字符”);} S=MOVE[S][nextchar] //下一状态 if(S=NULL)return(“不接受”);//下一状态为空,不能识别,单词错误 wordbuffer[i]=nextchar ;//保存单词符号 i++; nextchar=getchar(); } Wordbuffer[i]=‘\0’;

编译原理词法分析程序实现实验报告

编译原理词法分析程序实现实验报告实验一词法分析程序实现 一、实验内容 选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。输入:由无符号数和+,,,*,/, ( , ) 构成的算术表达式,如 1.5E+2,100。输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。二、设计部分 因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下: 输入字符p指向第一个字符 符号识别*p=+||-||*||/ YYNN*p=0~9*p=E*p=0~9||"." N无效符号Y *p=“.”GOTO 2 GOTO 1 GOTO 1: NY无符号数GOTO 1*p=0~9*p='/0' YN P++NNP++*p=E*p='+'||'-' YY P++P++continue

YY *p=0~9*p=0~9 NN 无符号数无符号数 P++P++ continuecontinue GOTO 2: GOTO 2 *p=Econtinue Y 无符号数 P++ continue 三、源程序代码部分 #include #include #include #define MAX 100 #define UNSIGNEDNUMBER 1 #define PLUS 2 #define SUBTRACT 3 #define MULTIPLY 4 #define DIVIDE 5 #define LEFTBRACKET 6 #define RIGHTBRACKET 7 #define INEFFICACIOUSLABEL 8 #define FINISH 111

编译原理实验 词法分析&语法分析程序

编译原理实验 词 法 分 析 程 序

实验一:词法分析程序 1、实验目的 从左至右逐个字符的对源程序进行扫描,产生一个个单词符号,把字符串形式的源程序改造成单词符号形式的中间程序。 2、实验内容 表C语言子集的单词符号及内码值 单词符号种别编码助记符内码值 while 1 while -- if 2 if -- else 3 else -- switch 4 switch -- case 5 case -- 标识符 6 id id在符号表中的位置 常数7 num num在常数表中的位置 + 8 + -- - 9 - -- * 10 * -- <= 11 relop LE < 11 relop LT == 11 relop LQ = 12 = -- ; 13 ; -- 输入源程序如下 if a==1 a=a+1; else a=a+2; 输出对应的单词符号形式的中间程序 3、实验过程 实验上机程序如下: #include "stdio.h" #include "string.h" int i,j,k; char s ,a[20],token[20]; int letter() { if((s>=97)&&(s<=122))return 1; else return 0; } int Digit() {if((s>=48)&&(s<=57))return 1;

else return 0; } void get() { s=a[i]; i=i+1; } void retract() {i=i-1;} int lookup() { if(strcmp(token, "while")==0) return 1; else if(strcmp(token, "if")==0) return 2; else if(strcmp(token,"else")==0) return 3; else if(strcmp(token,"switch")==0) return 4; else if(strcmp(token,"case")==0) return 5; else return 0; } void main() { printf("please input you source program,end('#'):\n"); i=0; do { i=i+1; scanf("%c",&a[i]); }while(a[i]!='#'); i=1; memset(token,0,sizeof(char)*10); j=0; get(); while(s!='#') { if(s==' '||s==10||s==13) get(); else { switch(s)

编译原理实验-词法分析器的设计与实现.docx

南华大学 计算机科学与技术学院实验报告 (2018~2019学年度第二学期) 课程名称编译原理 实验名称词法分析器的设计与 实现 姓名学号 专业班级 地点教师

1.实验目的及要求 实验目的 加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。 实验要求 1.对单词的构词规则有明确的定义; 2.编写的分析程序能够正确识别源程序中的单词符号; 3.识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护 符号表; 4.对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误 提示,保证顺利完成整个源程序的词法分析; 2.实验步骤 1.词法分析规则 <标识符>::=<字母>|<标识符><字母>|<标识符><数字> <常数>::=<数字>|<数字序列><数字> <数字序列>::=<数字序列><数字>|<数字>|<.> <字母>::=a|b|c|……|x|y|z <数字>::=0|1|2|3|4|5|6|7|8|9 <运算符>::=<关系运算符>|<算术运算符>|<逻辑运算符>|<位运算符>|<赋值运算符> <算数运算符>::=+|-|*|/|...|-- <关系运算符>::=<|>|!=|>=|<=|== <逻辑运算符>::=&&| || |! <位运算符>::=&| | |! <赋值运算符>::==|+=|-=|/=|*= <分界符>::=,|;|(|)|{|}|:| // |/**/ <保留字>::=main|if|else|while|do|for|...|void

编译原理词法分析及语法分析

编译原理 实验报告 实验名称:词法分析及语法分析专业班级: 姓名: 学号: 完成日期:

实验一、sample语言的词法分析 一、实验目的 给出SAMPLE文法规范,要求编写SAMPLE语言的词法分析程序。 二、实验准备 了解sample语言单词的定义,选择任一种编程语言实现词法分析。 三、实验内容 给出SAMPLE语言文法,输出单词(关键字、专用符号以及其它标记)。 1、格式 输入:源程序文件。输出:关键字、专用符号以及其它标记。 2、实现原理 程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。 3、实验方法 读懂Sample源代码,自己重点独立实现对常量的判别。 四、实验设计 1、设计SAMPLE语言的词法分析器 A、字符集定义 1. <字符集> → <字母>│<数字>│<单界符> 2. <字母> → A│B│…│Z│a│b│…│z 3. <数字> → 0│1│2│…│9 4. <单界符> → +│-│*│/│=│<│>│(│)│[│]│:│. │; │, │' B、单词集定义 5.<单词集> → <保留字>│<双界符>│<标识符>│<常数>│<单界符> 6.<保留字> → and│array│begin│bool│call│case│char│constant│dim│do│else │end│false│for│if│input│integer│not│of│or│output│procedure│program │read│real│repeat│set│stop│then│to│true│until│var│while│write 7.<双界符> → <>│<=│>=│:= │/*│*/│.. 8.<标识符> → <字母>│<标识符> <数字>│<标识符> <字母> 9.<常数> → <整数>│<布尔常数>│<字符常数> 10.<整数> → <数字>│<整数> <数字> 11.<布尔常数> → true│false 12.<字符常数> → ' 除 {'} 外的任意字符串 ' 2、词法分析系统流程设计

(完整版)《编译原理》词法分析程序设计方案

实验1-4 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法:1.根据状态转换图直接编程的方式;2.利用DFA 编写通用的词法分析程序。 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 2.编写DFA模拟程序 算法如下: DFA(S=S0,MOVE[][],F[],ALPHABET[]) /*S为状态,初值为DFA的初态,MOVE[][]为状态转换矩阵,F[] 为终态集,ALPHABET[] 为字母表,其中的字母顺序与MOVE[][] 中列标题的字母顺序一致。*/ { Char Wordbuffer[10]=“”//单词缓冲区置空 Nextchar=getchar();//读 i=0; while(nextchar!=NULL)//NULL代表此类单词 { if (nextcha r!∈ALPHABET[]){ERROR(“非法字符”),return(“非法字符”);} S=MOVE[S][nextchar] //下一状态 if(S=NULL)return(“不接受”);//下一状态为空,不能识别,单词错误 wordbuffer[i]=nextchar ;//保存单词符号 i++; nextchar=getchar(); } Wordbuffer[i]=‘\0’; If(S∈F)return(wordbuffer);//接受 Else return(“不接受”);

相关主题
文本预览
相关文档 最新文档