一个小语言的词法分析程序
2010-01-23 20:32:18 来源:WEB开发网根据此文法,构造一词法分析程序。输入以“#”为结束符
按照这个文法,找出该语言的关键字,如program,begin,end ,if,then,else,以及其他一些特殊符号,然后再构造一个分析表,如下表:
单词符号 | 类别编号 |
标识符 | 1 |
常数 | 2 |
if | 3 |
then | 4 |
else | 5 |
program | 6 |
begin | 7 |
end | 8 |
+ | 9 |
- | 10 |
* | 11 |
/ | 12 |
( | 13 |
) | 14 |
> | 15 |
>= | 16 |
< | 17 |
<= | 18 |
<> | 19 |
:= | 20 |
; | 21 |
. | 22 |
, | 23 |
根据这个表来构造程序,程序的核心是下面的这个函数,
/********************************************************************
以下为主分析函数
从输入文件里面读,把分析结果写到输出文件中
参数:fpin :输入文件指针 fpout: 输出文件指针
********************************************************************/
void parse(FILE* fpin,FILE* fpout)
{
char arr[MAXBUF];//读出的最长的字符串不超过MAXBUF,MAXBUF定义为255,够长了我想
int i=0;//分析含字母的字符串用
int j=0;//分析纯数字的字符串用
while(1)
{
fscanf(fpin,"%c",&ch);//从输入文件中读入一个字符
if( ch=='' ''|| ch =='' '')//过滤掉空格和tab
;
else if( ch==''
'')//回车换行符,为下面进行错误判断
lineno++;
else if( IsDigit(ch))//读入的是数字
{
while(IsDigit(ch))
{
arr[j] = ch;
j++;
fscanf(fpin,"%c",&ch);
}
fseek(fpin,-1L,SEEK_CUR);//文件指针后退一个字节
char* temp1 =(char*)malloc(j+1);/
memcpy(temp1,arr,j);
temp1[j] ='''';//把数组里面的内容拷贝到连外一个数组里面,因为我定义的
//arr为255个字节,实际上写不到那么多,所以只拷贝实际上有数据的
j=0;//恢复初始状态,以备下次使用
fprintf(fpout,"%s %d
",temp1,2);//常数
free(temp1);//释放内存
}
else if(IsAlpha(ch))//是字母开头的
{
while(IsAlpha(ch) || IsDigit(ch))
{
arr[i] =ch;
i++;
fscanf(fpin,"%c",&ch);
}
fseek(fpin,-1L,SEEK_CUR);
char* temp = (char*)malloc(i+1) ;
memcpy(temp,arr,i);
temp[i] ='''';
i=0;
/*基本思想同处理数字的*/
if(FindOK(temp))//FindOK函数在关键字表中查找和temp字符串相同的,找到就返回类别编号
{
fprintf(fpout,"%s %d
",temp,FindOK(temp));
}
else
{
fprintf(fpout,"%s %d
",temp,1);//标示符号
}
free(temp);
}
//以下为2字节的运算符号
else if( ch=='':'')//符号“:=”
{
fscanf(fpin,"%c",&ch);
if(ch==''='')
fprintf(fpout,"%s %d
",":=",20);
else
fprintf(fpout,"error in compileing %d lines unknown character %c
",lineno,ch);//出错了
}
else if(ch==''>'')//符号 “> “ 和”>=”
{
fscanf(fpin,"%c",&ch);
if(ch==''='')
fprintf(fpout,"%s %d
",">=",16);
else
fprintf(fpout,"> 15
");
}
else if( ch==''<'') //符号 “< “ 和”<=”
{
fscanf(fpin,"%c",&ch);
if(ch==''='')
{fprintf(fpout,"<= 18
");}
else if( ch==''>'')
{fprintf(fpout,"<> 19");}
else
{fprintf(fpout,"< 19
");}
}
else {
//以下为一个字节的运算符号
if(ch==''-'') {fprintf(fpout,"%s %d
",''-'',10);continue;}//在文件中输出为“- 10”
if(ch=='';'') {fprintf(fpout,"; 21
");continue;}
if(ch==''+'') {fprintf(fpout,"+ 9
");continue;}
if(ch==''*'') {fprintf(fpout,"* 11
");continue;}
if(ch==''/'') {fprintf(fpout,"/ 12
");continue;}
if(ch==''('') {fprintf(fpout,"( 13
");continue;}
if(ch=='')'') {fprintf(fpout,") 14
");continue;}
if(ch==''.'') {fprintf(fpout,". 22
");continue;}
if(ch=='','') {fprintf(fpout,", 23
");continue;}
if(ch==''#'') break;//分析结束
else fprintf(fpout,"error in compileing %d lines unknown character %c
",lineno,ch);//出错了,输出出错信息
}
}
}
其他请看源代码,注释很详细,但是肯定有不足的地方,请大家吝赐教。有什么问题,可以给我发邮件。这是我第一次向VC知识库投稿,以后将会陆续写一些VC方面的程序来和大家共享。我的email:brilliant_zhang@21cn.com,QQ:110902663, 谢谢大家。
本文配套源码
更多精彩
赞助商链接