⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 词法分析的c实现(做编译器的时候很有用).txt

📁 C&C++论坛精华
💻 TXT
字号:
作者:skyhorsebj
email: XUEY@CIDC.COM.CN
日期:2001-7-3 12:41:52


    这里以开始定义的PASCAL语言子集的源程序作为词法分析程序的输入数据。
在词法分析中,自文件头开始扫描源程序字符,一旦发现符合"单词"定义的源程
序字符串时,将它翻译成固定长度的单词内部表示,并查填适当的信息表。经过
词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息的单词
串(源程序的内部表示),并产生两个表格:常数表和标识符表,它们分别包含
了源程序中的所有常数和所有标识符。

下面就词法分析程序中的主要变量进行说明:
    FILE fp     :文件指针,用于指向要分析的PASCAL源程序;
    char *key[8]:指针数组,用于指向关键字表;
        char *border[6]:指针数组,用于指向符号表;
    char *arithmetic[4]:指针数组,指向算术运算符表;
    char *relation[6]:指针数组,指向关系运算符表;
    char *consts[20]:指针数组,指向常数表;
    char *label[20]:指针数组,指向标识符表;
        int constnum,labelnum:整型变量,分别用于存放当前常数个数和标
识符个数。

程序中的主要子函数:
alphaprocess:关键字和标识符处理子函数;
digitprocess:数字处理函数;
otherprocess:其他字符处理函数;
search:查找子函数;

下面简要分析一下词法分析程序的运行流程:

主函数main():
     打开要分析的PASCAL源程序,若不能正确打开,则报错。
   先从源程序中读入一个字符ch,然后进行如下处理:
   1、ch是字符:转入关键字和标识符处理子函数;
   2、ch是数字:转入数字处理函数;
   3、ch是其他字符:转入其他字符处理子函数;
    结束。

关键字和标识符处理子函数alphaprocess(char buffer);
        1、将buffer送入临时数组alphatp[0],再读入一个字符至buffer;
        2、判断buffer是否为字符或数字,若是,则alphatp[1]=buffer;
        3、重复1,2,直到2判断为假;在alphatp末尾添加'\0';
        4、调用search()子函数,在关键字表中匹配alphatp,若匹配成功,则返回序号;
    5、调用search,在标识符表中匹配alphatp,若匹配成功,则返回序号;
    6、在标识符表中添加alphatp,并返回序号;
        
其余子函数的处理方式于alphaprocess类似,此处不再赘述。

[程序调试]

现有PASCAL程序清单如下:
BEGIN 
  IF I=1 THEN
     I:=I+1  #
  ELSE   *&^
     IF I=2 THEN
        I:=I+11;
END.

运行词法分析程序后,显示如下结果:

BEGIN (1,1)
IF (1,4)
I (6,0)
= (4,2)
1 (5,0)
THEN (1,5)
I (6,0)
:= (2,2)
I (6,0)
+ (3,0)
1 (5,0)
# error,not a word
ELSE (1,2)
* (3,2)
& error,not a word
^ error,not a word
IF (1,4)
I (6,0)
= (4,2)
2 (5,1)
THEN (1,5)
I (6,0)
:= (2,2)
I (6,0)
+ (3,0)
11 (5,2)
; (2,1)
END (1,3)
. (2,3)
over

结果完全正确。

源程序: 
#include 
#include 
#include 
#include 
#include 
#define NULL 0

FILE *fp;
char cbuffer;
char *key[8]={"DO","BEGIN","ELSE","END","IF","THEN","VAR","WHILE"};
char *border[6]={",",";",":=",".","(",")"};
char *arithmetic[4]={"+","-","*","/"};
char *relation[6]={"<","<=","=",">",">=","<>"};
char *consts[20];
char *label[20];
int constnum=0,labelnum=0;

int search(char searchchar[],int wordtype)
     {
     int i=0;
     switch (wordtype) {
       case 1:for (i=0;i<=7;i++)
		  {
		   if (strcmp(key[i],searchchar)==0)
		     return(i+1);
		  };

       case 2:{for (i=0;i<=5;i++)
		  {
		   if (strcmp(border[i],searchchar)==0)
		      return(i+1);
		  };
	       return(0);
	      }

       case 3:{for (i=0;i<=3;i++)
		  {
		   if (strcmp(arithmetic[i],searchchar)==0)
		      {
		       return(i+1);
		      };
		  };
	      return(0);
	      };

       case 4:{for (i=0;i<=5;i++)
		  {
		   if (strcmp(relation[i],searchchar)==0)
		      {
		       return(i+1);
		      };
		  };
	       return(0);
	      };

       case 5:{for (i=0;i<=constnum;i++)
		  {
		   if (strcmp(consts[i],searchchar)==0)
		       {
			return(i+1);
		       };
		  }
	      consts[i-1]=(char *)malloc(sizeof(searchchar));
	      strcpy(consts[i-1],searchchar);
	      constnum++;
	      return(i);
	      };

       case 6:{for (i=0;i<=labelnum;i++)
		  {
		     if (strcmp(label[i],searchchar)==0)
		       {
			return(i+1);
		       };
		  }
	      label[i-1]=(char *)malloc(sizeof(searchchar));
	      strcpy(label[i-1],searchchar);
	      labelnum++;
	      return(i);
	      };

      }


     }


char alphaprocess(char buffer)
     {
      int atype;
      int i=-1;
      char alphatp[20];
      while ((isalpha(buffer))||(isdigit(buffer)))
	    {
	    alphatp[++i]=buffer;
	    buffer=fgetc(fp);
	    };
      alphatp[i+1]='\0';
      if (atype=search(alphatp,1))
	 printf("%s (1,%d)\n",alphatp,atype-1);
      else
	 {
	 atype=search(alphatp,6);
	 printf("%s (6,%d)\n",alphatp,atype-1);
	 };
      return(buffer);
      }

char digitprocess(char buffer)
     {
      int i=-1;
      char digittp[20];
      int dtype;
      while ((isdigit(buffer)))
	    {
	    digittp[++i]=buffer;
	    buffer=fgetc(fp);
	    }
      digittp[i+1]='\0';
      dtype=search(digittp,5);
      printf("%s (5,%d)\n",digittp,dtype-1);
      return(buffer);
     }

char otherprocess(char buffer)
     {

      int i=-1;
      char othertp[20];
      int otype,otypetp;
      othertp[0]=buffer;
      othertp[1]='\0';
      if (otype=search(othertp,3))
	 {
	 printf("%s (3,%d)\n",othertp,otype-1);
	 buffer=fgetc(fp);
	 goto out;
	 };

      if (otype=search(othertp,4))
	      {
	      buffer=fgetc(fp);
	      othertp[1]=buffer;
	      othertp[2]='\0';
	      if (otypetp=search(othertp,4))
		 {
		 printf("%s (4,%d)\n",othertp,otypetp-1);
		 goto out;
		 }
	      else
		 othertp[1]='\0';
		 printf("%s (4,%d)\n",othertp,otype-1);
		 goto out;
	      };

      if (buffer==':')
	      {
	      buffer=fgetc(fp);
	      if (buffer=='=')
		 printf(":= (2,2)\n");
		 buffer=fgetc(fp);
		 goto out;
	      }
	   else
	      {
	      if (otype=search(othertp,2))
		 {
		 printf("%s (2,%d)\n",othertp,otype-1);
		 buffer=fgetc(fp);
		 goto out;
		 }
	      };

	  if ((buffer!='\n')&&(buffer!=' '))
		  printf("%c error,not a word\n",buffer);
	  buffer=fgetc(fp);
out:      return(buffer);
     }



void main()
     {
     int i;
      for (i=0;i<=20;i++)
	  {
	   label[i]=NULL;
	   consts[i]=NULL;
	  };
      if ((fp=fopen("\\DEMO.PAS","r"))==NULL)
	 printf("error");
      else
	{
	cbuffer = fgetc(fp);
	while (cbuffer!=EOF)
	 {
	  if (isalpha(cbuffer))
	     cbuffer=alphaprocess(cbuffer);
	  else if (isdigit(cbuffer))
	     cbuffer=digitprocess(cbuffer);
	  else cbuffer=otherprocess(cbuffer);
	  };
	 printf("over\n");
	 };
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -