c语言的适当大小的子集,使用直接分析法编制C语言子集的词法分析程序.doc

附录B 编译程序实验

一、题目

使用直接分析法编制C语言子集的词法分析程序

二、目的

通过设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法.

三、要求

1. 根据具体情况,由同学们自己选取C 语言的一个适当大小的子集(可取一类典型单词,也可以尽可能使各种类型的单词都兼顾到);在实习前一定要制出相应的表.

2. 实验时间:4-8学时.

3. 检查内容及时间:A) 完整的实验报告(算法流程必须要有);

B) 在机器上调试成功的源程序;

实 验 报 告

题目: 用直接分析方法编制PASCAL语言子集的词法分析程序.

一、分析

对于单词符号我们将其分成四类:保留字K、标识符I、常数C和界符P,每类单词符号均可使用一张表格表示.在词法分析过程中,保留字K和界符P这两个表格的内容是固定不变的(由语言确定),源程序字符串只能从其中选取,而标识符I、常数C这两表是在分析过程中不断形成的.

对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是K、I、C或P中之一,那么就以单词的二元式形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串.

各类单词的二元式表述均具有相同的结构与长度,形式如下:

(单词种别t,单词自身的值i)

t是单词种别,而单词种别共分为K、I、C、P四类且每类对应一张表格.因此,t实际上就是一个指向这四类中某一类对应表格的指针.i则为指向该类表格中一个特定项目的指针.

所以整个的词法分析过程就是从源程序中获得一个个的单词符号,将这些符号分别填入四张类表中,并且有一个二元式序列构成一个索引,这个索引为以后的语法分析提供处理上的方便.

为了减少实习量,可以适量地选取K,P中的一个子集来进行.如下表:

表1 保留字K表

内部地址

1

2

3

4

5

6

7

8

9

10

保 留 字

BEGIN

CONST

DO

ELSE

END

IF

PROCEDURE

THEN

VAR

WHILE

表2 界符P表

内部地址

1

2

3

4

5

6

7

8

9

10

界 符

(

)

组合界符

保留字表包括10个有代表性的保留字,界符表包括关系运算符三种(8,9,10),算术运算符(2),分隔符三种(1,4,6),一对圆括号,加上赋值号共10种.这两表的内容表明PASCAL语言的条件语句,赋值语句,WHILE型循环语句,复合语句,过程及变量说明均可作为源程序例子输入给词法分析程序,标识符表I中的每一项包含一个标识符,常数表C中的每一项包含一个整常数,后两表的内容都是在词法分析过程中产生的.

如何从源程序中识别出一个个的单词符号呢?图1中的流图清晰地反映出这一过程.

图1中,双圆圈的状态表示终态,即能到达终态就代表识别出一个单词符号,而带有*号的终态是指处理时应回退一字符.

其它

界符

数字

字母

出错处理

C表有此单词否?

形成一项

形成(C,i)

十进制数转化成二进制数

K表有此单词否?

形成(I,i)

形成(K,i)

查界符表

形成(P,i)

源程序完否?

输出二元式

开始

开始

对源程序扫描

扫描到的单词符号

首字母是什么?

未完

图2词法分析算法流图

2

字母

非字母与数字

1

字母与数字

0

空白

4

数字

非数字

3

数字

+

6

5

8

非=

7

=

9

(

10

11

)

12

其它

17

14

<

非=

13

15

>

16

=

图1 扫描程序的状态转换图

二、算法

词法分析器在扫描过程中,依次从源程序中取出源字符,根据图1的扫描过程状态转换图,当碰到终态时,即双圆圈的状态时就得到一个单词符号,此时可以根据第一个字符判断单词属于K,I,C,P中哪一类,从而确定单词的"单词种别"和"单词自身的值".整个词法分析的算法流程如图2.

三、实现

选择实习环境为TURBO C2.0语言. 实现程序见附录.

四、总结

上机前应做好准备.即根据实习目的、要求和分析,选择相应的数据结构,使用C语言参照算法中的流程编写词法分析的程序.将编好的程序上机进行调试.注意调试的例子应有词法正确的,也应有词法错误的或是超出所选数据结构范围的.

实验完成达到实习目的之后,若尚有余力者,可以对所选子集适当扩大或是增加相应功能如:扩充界符和保留字数目;允许实型常数;进行词法错误检查;最大范围扩充以至PASCAL语言所有字符的集合.

实验完成以后编写出完整的实验报告,反映出最后的实验学习结果.

附录

/* 词法分析器程序 分析对象为PASCAL语言源程序文件

分析程序主文件: wanalyse.c;

保留字文件: token.txt;

分析结果存放文件: result.txt

WORD ANALYSE DEMO FOR TURBO C 2.0

Copyright (c) 2006, 07 Authors: WQJ

All rights reserved.

From the command line, use:C:\>wanalyse OBJECT.PAS

*/

#include "stdio.h"

#include "ctype.h"

#include "string.h"

#define NULL 0

#define TOKENSUM 100

FILE *fin,*fout,*fp;

char ch,wordget[10];

int i;

void makeword(); /*扫描源程序获得一个单词符号*/

void wordproc(); /*对单词符号进行分类处理生成二元式*/

void makeword(fpoint) /*扫描源程序获得一个单词符号*/

FILE *fpoint;

{

……

}

void wordproc() /*对单词符号进行分类处理生成二元式*/

{

……

}

main(argc,argv) /*词法分析主程序*/

int argc;

char *argv[];

{if (argc==1) /*没有被分析文件作为参数1*/

{printf("Please input filenames of OBJECT\n");

exit(0);

}

if ((fin=fopen(argv[1],"r"))==NULL)

{printf("Cannot open infile\n");

exit(0);

}

if ((fout=fopen("result.txt","w"))==NULL)

{printf("Cannot open outfile\n");

exit(0);

}

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

{printf("Cannot open tokenfile\n");

exit(0);

}

while(!feof(fin))

{makeword(fin); /*扫描源程序获得一个单词符号*/

wordproc(); /*对单词符号进行分类处理生成二元式*/

}

}

分析对象文件OBJECT.PAS

program exe6(input,output);{PASCAL分析对象程序}

const max=1000;

type ar=array[0..max] of integer;

var m,n,i,j,s:integer; d:ar;

begin

readln(n);

for m:=1 to n do

begin

s:=m*m;

j:=0;

while s>0 do

begin

j:=j+1;

d[j]:=s mod 10;

s:=s div 10

end;

i:=1;

while (d[i]=d[j]) and (ij then writeln(m,m*m:10)

%$ end

end.

分析结果文件RESULT.TXT

(25,-) #PROGRAM#

(101,EXE6)

(46,-) #(#

(68,-) #INPUT#

(54,-) #,#

(69,-) #OUTPUT#

(47,-) #)#

(55,-) #;#

( 5,-) #CONST#

(101,MAX)

(40,-) #=#

(100,1000)

(55,-) #;#

(31,-) #TYPE#

(101,AR)

(40,-) #=#

( 2,-) #ARRAY#

(48,-) #[#

(100,0)

(57,-) #..#

(101,MAX)

(49,-) #]#

(21,-) #OF#

(63,-) #INTEGER#

(55,-) #;#

(33,-) #VAR#

(101,M)

(54,-) #,#

(101,N)

(54,-) #,#

(101,I)

(54,-) #,#

(101,J)

(54,-) #,#

(101,S)

(56,-) #:#

(63,-) #INTEGER#

(55,-) #;#

(101,D)

(56,-) #:#

(101,AR)

(55,-) #;#

( 3,-) #BEGIN#

(77,-) #READLN#

(46,-) #(#

(101,N)

(47,-) #)#

(55,-) #;#

(12,-) #FOR#

(101,M)

(52,-) #:=#

(100,1)

(30,-) #TO#

(101,N)

( 7,-) #DO#

( 3,-) #BEGIN#

(101,S)

(52,-) #:=#

(101,M)

(38,-) #*#

(101,M)

(55,-) #;#

(101,J)

(52,-) #:=#

(100,0)

(55,-) #;#

(34,-) #WHILE#

(101,S)

(43,-) #>#

(100,0)

( 7,-) #DO#

( 3,-) #BEGIN#

(101,J)

(52,-) #:=#

(101,J)

(36,-) #+#

(100,1)

(55,-) #;#

(101,D)

(48,-) #[#

(101,J)

(49,-) #]#

(52,-) #:=#

(101,S)

(18,-) #MOD#

(100,10)

(55,-) #;#

(101,S)

(52,-) #:=#

(101,S)

( 6,-) #DIV#

(100,10)

(10,-) #END#

(55,-) #;#

(101,I)

(52,-) #:=#

(100,1)

(55,-) #;#

(34,-) #WHILE#

(46,-) #(#

(101,D)

(48,-) #[#

(101,I)

(49,-) #]#

(40,-) #=#

(101,D)

(48,-) #[#

(101,J)

(49,-) #]#

(47,-) #)#

( 1,-) #AND#

(46,-) #(#

(101,I)

(42,-) ##

(101,J)

(29,-) #THEN#

(82,-) #WRITELN#

(46,-) #(#

(101,M)

(54,-) #,#

(101,M)

(38,-) #*#

(101,M)

(56,-) #:#

(100,10)

(47,-) #)#

(ERROR,%)

(ERROR,$)

(10,-) #END#

(10,-) #END#

(53,-) #.#

保留字文件TOKEN.TXT

AND

ARRAY

BEGIN

CASE

CONST

DIV

DO

DOWNTO

ELSE

END

FILE

FOR

FUNCTION

GOTO

IF

IN

LABEL

MOD

NIL

NOT

OF

OR

PICKED

PROCEDURE

PROGRAM

RECORD

REPEAT

SET

THEN

TO

TYPE

UNTIL

VAR

WHILE

WITH

+

-

*

/

=

<>

<

>

<=

>=

(

)

[

]

{

}

:=

.

,

;

:

..

'

^

FALSE

TRUE

MAXINT

INTEGER

REAL

BOOLEAN

CHAR

TEXT

INPUT

OUTPUT

DISPOSE

GET

NEW

PACK

PAGE

PUT

READ

READLN

RESET

REWRITE

UNPACK

WRITE

WRITELN

ABS

ARCTAN

CHR

COS

EOF

EOLN

EXP

LN

ODD

ORD

PRED

ROUND

SIN

SQR

SQRT

SUCC

TRUNC

展开阅读全文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值