《编译原理及编译程序构造》-词法分析

词法分析

  词法分析程序又称词法分析器或扫描器,是编译程序的基本子过程之一。

3.1 词法分析程序的功能及实现方案

  词法分析程序的功能是:扫描源程序字符,按语言的词法规则识别出各类单词符号(Token),并将有关字符组合成为单词并输出,同时进行词法检查。语言的保留字、标示符,常数和运算符等等都是单词的例子。词法分析程序的主要任务是进行词法分析,同时完成相关单词转化和处理。

归纳如下:

(1),词法分析:从源程序第一个字符开始,顺序的读字符,一个个读入并确定单词同时进行词法检查,若发现单词组成有错误时输出有关错误信息。

(2),对数字常数完成数字字符串到二进制数值的转换,并将其值输出。

(3),删去空格、换行、制表字符和注释。

 

词法分析程序可以单独作为一遍来实现,此时将它的输出放在一个单独文件中,语法分析器可以从该文件中取得输入。也可以将其存放到内存中,提高效率。通过这一遍的加工,就可以将字符串表示的源程序表示为以单词表示的源程序了

 

3.2 单词的种类及词法分析程序的输出形式

 1,单词的种类:

  (1),保留字:程序语言预定义的字符串,如begin,end,for,if,then,do

  (2),标识符:用户定义的标示各种名字的字符串,如变量名,数组名和函数名等。

(3),常数。

(4),分界符或操作符。

2,词法分析程序的输出形式:

为了便于编译程序进一步加工,单词的输出形式一般采用二元式,如图:

单词类别

单词值

整型

保留字

58

 

for

其实,一个单词符号如何分类、怎么样编码是一个技术性的问题,主要取决于处理上的方便。

3.3 正则文法和状态图

由形式语言和自动子理论可以知道,对于正则文法所描述的语言,可以用一种有穷自动机来识别。我们直接介绍这种自动机的非形式表示,即状态图。

3.3.1 状态图

状态图也称状态转换图,是一个有向图。

 

3.4 词法分析程序的设计与实现

首先确定词法分析程序的具体输出形式,然后编写程序。

1,输出形式:

仍采用二元式,下表表示了词法分析程序的输出形式

单词名称

类别编码

记忆符

单词值

BEGIN

END

IF

THEN

ELSE

标示符

整常数

+

-

*

/

(

)

,

;

:

:=

=

1

2

3

4

5

 

20

 

21

22

23

24

25

26

27

28

29

30

31

32

BEGINSY

ENDSY

IFSY

THENSY

ELSESY

 

IDSY

 

INTSY

PLUSSY

MINUSSY

STARSY

DIVISY

LPARSY

RPARSY

COMMASY

SEMISY

COLONSY

ASSIGNSY

EQUSY

-

-

-

-

-

 

内部字符串表示

 

二进制数值表示

-

-

-

-

-

-

-

-

-

 

2,全局变量和过程:

词法分析程序所用的全局变量和要调用的过程和函数如下:

char:字符全局变量,存放当前读入的字符。

token:字符数组,存放单词的字符串

symbol:枚举型全局变量,保存当前所识别的单词类型。

getchar():读字符过程,每调用一次镀金一个字符放在char中,并把读字符指针指向下一个字符.

clearToken():清空token字符数组

isSpace(),isNewline(),isTab():判断char中字符是否为空格、换行、Tab

isLetter(),isDigit():判断char中字符是否为数字、字母

isClono(),isComma(),isSemi():判断char中字符是否为冒号,逗号,分号

isEqu(),isPlus(),isMinus(),isDivi():判断char中字符是否为等号,加号,减号,除号

isStar():判断char中字符是否为*

isLpar(),isRpar():判断char中字符是否为左右括号

catToken():每次调用把当前char中字符与token数组中的字符串联接。

retract():将读字符指针后退一个字符。

reserver():查找保留字,如果返回值为0,则表示token中字符串是一个标示符,否则为保留字编码,返回当前保留字的类编码。

transNum():将token中的字符串转换成整型数值,返回这个值

error():错误处理过程。

对应的词法分析程序算法如下:

/*词法分析程序*/
int getsym()
{
	clearToken();
	while(isSpace()||isNewline()||isTab()) getchar();/*读取字符,跳过空格换行和tab*/
	if(isLetter())/*判断当前字符是否是一个字母*/
	{
		while(isLetter()||isDigit())/*将字符拼接成字符串*/
		{
			catToken();
			getchar();
		}
		retract();/*指针后退一个字符*/
		int resultValue = reserver();/*resultValue是查找保留字的返回值*/
		if(resultValue==0)
			symbol=IDSY;/*resultValue=0,token中的字符串为标识符*/
		else
			symbol=resultValue;/*否则token中的字符串为保留字*/
	}
	else(isDigit())/*判断当前字符是否是一个数字*/
	{
		while(isDigit())/*将字符拼接成整数*/
		{
			catToken();
			getchar();
		}
		retract();
		num = transNum();/*将token中的字符串转换成整数*/
		symbol=INTSY;/*此时识别的单词是整数*/
	}
	else(isColon())/*判断当前字符是否是冒号*/
	{
		getchar();
		if(isEqu())
			symbol=ASSIGNSY;/*判断是否是赋值符号*/
		else retract();
		symbol=COLONSY;
	}
	else if(isPlus()) /*判断是否是加号*/
		symbol=PLUSSY;
	else if(isMinus())  /*判断是否是减号*/
		symbol=MINUSSY;
	else if(isStar())/*判断是否时星号*/
		symbol=STARSY;
	else if(isLpar())/*判断是否是左括号*/
		symbol=LPARSY;
	else if(isRpar())/*判断是否是右括号*/
		symbol=RPARSY;
	else if(isComma())/*判断是否是逗号*/
		symbol=COMMASY;
	else if(isSemi())/*判断是否是分号*/
		symbol=SEMISY;
	else if(isDivi())/*判断是否是斜竖*/
	{
		getchar();
		if(isStar())/*处理注释*/
		{
			do{
				do{ getchar();} while(!isStar());
				do{
					getchar();
					if(isDivi())
						return 0;/*注释处理完毕*/
					}while(isStar());
			}while(!isStar());
		}
		else{
			retract();
			symbol=DIVISY;/*如果不是注释则为除号*/
		}
	}
	else error();
	return 0;
}


《编译原理及编译程序构造》-词法分析_第1张图片

你可能感兴趣的:(《编译原理及编译程序构造》-词法分析)