一个小语言的词法分析程序

资讯 驱动中国 rocket 6,180 次阅读 0 条评论
分享 Q

前些天写了个小语言的词法分析程序,因为前些天在VC知识库看到一个pascal词法分析的程序,觉得写得挺复杂的。其实词法分析程序的原理都是一样的,所以我想只要搞明白了简单的词法分析程序,再写复杂的就不难了,无非是多加几个关键字,多写几个条件判断语句而已。词法分析是编译程序的基础,也是最简单的。好,现在让我们看程序吧。
先让我们看看这个小语言的文法吧。

G[<程序>]:
<程序>∷=<程序首部>;<分程序>.
<程序首部>∷=program<标识符>
<分程序>∷=<复合语句>
<复合语句>∷=begin<语句序列>end
<语句序列>∷=<语句>{;<语句>}
<语句>∷=<赋值语句>|<复合语句>|<条件语句>
<赋值语句>∷=<标识符>:=<表达式>
<条件语句>∷=if <布尔表达式> then <语句> else <语句>
<表达式>∷=<项>{(+|-)<项>}
<项>∷=<因式>{(*|/)<因式>}
<因式>∷=<标识符>|<无正负号常量>|’(’<表达式>’)’
<布尔表达式>∷=<表达式><关系运算符><表达式>
<关系运算符>∷= =|<|<=|>|>=|<>
<标识符>∷=<字母>{<字母>|<数字>}
<无正负号常量>∷=<数字>{<数字>}[.<数字>{<数字>}]
<字母>∷=a|b|c|d|e|f|g|……|u|v|w|x|y|z
<数字>∷=0|1|2|3|4|5|6|7|8|9

根据此文法,构造一词法分析程序。输入以“#”为结束符
按照这个文法,找出该语言的关键字,如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 ==''\t'')//过滤掉空格和tab

			;

		else if( ch==''\n'')//回车换行符,为下面进行错误判断

			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] =''\0'';//把数组里面的内容拷贝到连外一个数组里面,因为我定义的

			//arr为255个字节,实际上写不到那么多,所以只拷贝实际上有数据的



			j=0;//恢复初始状态,以备下次使用

			fprintf(fpout,"%s\t\t%d\n",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] =''\0'';



			i=0;

			/*基本思想同处理数字的*/

		

          if(FindOK(temp))//FindOK函数在关键字表中查找和temp字符串相同的,找到就返回类别编号

		  {

			 

			 fprintf(fpout,"%s\t\t%d \n",temp,FindOK(temp));

			 

		  }

		  else

		  {

			  fprintf(fpout,"%s\t\t%d\n",temp,1);//标示符号

			  

		  }

		  free(temp);

		}

	

		//以下为2字节的运算符号

		else if( ch=='':'')//符号“:=”

		{

			fscanf(fpin,"%c",&ch);

			if(ch==''='') 

				fprintf(fpout,"%s\t\t%d\n",":=",20);

			

		else 	

			fprintf(fpout,"error in compileing %d lines unknown character %c \n",lineno,ch);//出错了

		}
版权声明:本文由驱动中国整理发布,转载需注明出处与原文链接。如有疑问请联系 editor@qudong.com
本文价值 成为第一个评分的人
登录后为本文打分
网友评论0 条评论
正在回复 的评论取消
评论加载中…
🔐

登录后参与互动

评论、点赞均可赚积分
连续签到、邀请好友也有奖励 🎁

电脑端: 微信扫码登录 微信内: 一键登录

微信扫一扫

打开微信「扫一扫」,分享本文到朋友圈或好友