作者:so杨xi | 来源:互联网 | 2023-02-01 11:03
今天忙了一天,做了一个C_minus的词法分析器。下午睡醒后,写了一个文档,介绍了可以分析的范围,测试数据和主要的数据结构和算法。晚上搞了三个多小时,不停地编译,运行,debug。当
今天忙了一天,做了一个C_minus的词法分析器。
下午睡醒后,写了一个文档,介绍了可以分析的范围,测试数据和主要的数据结构和算法。
晚上搞了三个多小时,不停地编译,运行,debug。当看到那期待已久的数据,感觉好爽!
因为编程的时候是对关键字,符号,数字等是分开编的。所以等明天有时间的时候,把几个程序联在一起就可以啦。等全部搞好了,把代码贴出来请大家斧正。
这个东西是编译原理的课程设计中的一个,我是用c写的,也没有用vc做界面。用户在控制台下输入文件的路径,就可以对文件进行词法分析了。
说明文档如下:(第一次写文档,请大家指点)
/************************** 说明文档***********************************
本程序可以对C_minus语言进行词法分析。
C_minus,不是一种新的语言,她是C语言的一个子集。由Kenneth C.Louden提出并应用于教学。她主要有以下的特性:
C_minus语言的关键字:{else if int return void while},所有的关键字都是保留字,并且必须是小写。所有关键字按字母顺序排列,有利与折半查找(在关键字多的情况下可提高效率);
下面是专用符号:( ) * + , - / ; < = > [ ] { } (为简单起见,我已经对C_minus的符号集进行了简化。并且所有符号都按ASCII码的顺序从小到大排列,理由同上)。
其他标记是ID和NUM,通过下列正则表达式定义:ID = letter (letter | digit)* ,NUM = digit digit* .letter = a|..|z|A|..|Z|,digit = 0|..|9.注意在C_minus语言中小写和大写字母是有区别的;
空格由空白、换行符和制表符组成。空格通常被忽略,除了它必须分开ID,NUM关键字;
注释用通常的C语言符号/ * . . . * /围起来。注释可以超过一行。注意注释不能嵌套。 特别地,引号中的/*......*/不是注释。 (因为考虑注释比较复杂,所以在这个版本中不考虑输入注释的情况)
type 0 1 2 3
keyword num id symbol
*********************************************************************/
测试输入1:
int main()
{
int i = 2;
int j ;
if ( i > 0 )
j = i;
else
j = 0;
return 0;
}
预测输出1:
data ( type,value)
int (0,2)
main (2,0)
( (3,0)
) (3,1)
{ (3,13)
int (0,2)
i (2,1)
= (3,9)
2 (1,2)
; (3,7)
int (0,2)
j (2,2)
; (3,7)
if (0,1)
( (3,0)
i (2,1)
> (3,10)
0 (1,0)
) (3,1)
j (2,2)
= (3,9)
i (2,1)
; (3,7)
else (0,0)
j (2,2)
= (3,9)
0 (1,0)
; (3,7)
return (0,3)
0 (1,0)
; (3,7)
} (3,14)
//****************************************
测试输入2:
I am a genius!
预测输出2:
data ( type,value)
I (2,0)
am (2,1)
a (2,2)
genius (2,3)
! (4,0) illegal input
//****************************************
//用到的结构数组:
struct keyword{
char * word;
int value;
}keytab[] = {
"else",0,
"if",1,
"int",2,
"return",3,
"void",4,
"while",5,
};
//****
struct symbol{
char c;
int value;
}symboltab[] = {
'(', 0,
')', 1,
'*', 2,
'+',3,
',', 4,
'-', 5,
'/', 6,
';', 7,
'<',8,
'=',9,
'>',10,
'[', 11,
']', 12,
'{', 13,
'}', 14,
};
//用到的全局变量
int countnum = 0;
int countid = 0;
/***********************************
算法如下:
while(读入的字符不是EOF){
if ( isspace (c) )
continue;
else if( 是字母){
读取整个单词;
if(是关键字)
打印出来;
else{
countid++;
打印出来;
}
}else if(是数字){
读取整个数字;
打印出来;
}else if (ispunct(c)){
在符号表中查找;
if ( 在表中)
打印出来;
else
调用出错处理程序;
}
}