精品编写PL0语言词法分析程序c.docx

上传人:b****7 文档编号:25012167 上传时间:2023-06-03 格式:DOCX 页数:17 大小:18.91KB
下载 相关 举报
精品编写PL0语言词法分析程序c.docx_第1页
第1页 / 共17页
精品编写PL0语言词法分析程序c.docx_第2页
第2页 / 共17页
精品编写PL0语言词法分析程序c.docx_第3页
第3页 / 共17页
精品编写PL0语言词法分析程序c.docx_第4页
第4页 / 共17页
精品编写PL0语言词法分析程序c.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

精品编写PL0语言词法分析程序c.docx

《精品编写PL0语言词法分析程序c.docx》由会员分享,可在线阅读,更多相关《精品编写PL0语言词法分析程序c.docx(17页珍藏版)》请在冰豆网上搜索。

精品编写PL0语言词法分析程序c.docx

精品编写PL0语言词法分析程序c

编写PL/0语言的词法分析程序

要求:

1、读入用PL/0语言编写的源程序,正确的进行词法分析,并输出二元式序列.

2、若源程序有词法错误,能够给出出错的准确位置。

3、词法代号如下

(+,+);

(-,—);

(*,*);

(/,/);

((,();

(),));

(,,,);

(;,;);

(。

,。

);

(#,#);

(=,=);

(>,〉);

(<,<);

(:

=,a);

(〉=,b);

(<=,c);

(数字,d);

(标识符,e);

关键字代号:

(begin,f);

(call,g);

(const,h);

(do,i);

(end,j);

(if,k);

(odd,l);

(procedure,m);

(read,n);

(then,o);

(var,p);

(while,q);

(write,r);

4、等于运算符号为一个 =测试程序:

A。

C

======================

CONST A=10; 

VAR B,C; 

PROCEDURE P;   

VAR D;      

PROCEDURE Q;   

VAR X;       

BEGIN       

READ(X);

D:

=X;

WHILE X〈0 

DO CALL P;  

END;     

BEGIN     

WRITE(D);   

CALL Q;   

END;  

BEGIN  

CALL P;   

END。

*//*program name:

chifufenxi*//*作者:

小万 qq:

421404493*//*date:

2004.10.11*/#include

#include〈stdlib.h〉

#include

#include〈ctype.h〉

#include

h〉

                                                                                                         

#define N 256//每一行的字符数不能超过256个

                                                         

char buffer[N];   //用作存放一行字符char word[20];  //用作存放经过分析单词char *kword[13]={"begin",”call",”const”,”do”,"end”,”if”,”odd”,”procedure”,"read”,”then”,”var",”while",”write”};

char ktype[13]={’f',’g','h','i’,’j’,'k',’l’,’m’,’n','o','p',’q',’r'};int len;//记录每一行的长度int count=0;//用来记录行数void write(char *wstr,char wc,FILE *wout)//将分析结果按照规则写入到文件

{

       fputc(’(’,wout);

       fputs(wstr,wout);

    fputc(’,',wout); 

    fputc(wc,wout);

    fputc(')',wout); }

int readbuffer(FILE *fp)

{

char ch;

len=0;

ch=fgetc(fp);

while(!

feof(fp) && ch!

=’\n’)//读取字符到缓冲区

buffer[len]=ch;

ch=fgetc(fp);

len++;

                                                                                                                    

len-—;//用来控制词法分析时行分析中字母的个数

                                                                                                                                       

if(feof(fp))//标志文件是否结束

return 0;

else 

return 1;}

void error(int type)

{

 

 if(type==1)

  printf("为无效字符,第%d行词法出错,标志符不能以数字开头\n",count);

 else if(type==2)

      printf("第%d行词法出错,赋值符应为\:

\= \n ”,count);

 

     else printf(”为无效字符,第%d行词法出错\n",count);

}void check(char *str,FILE *out);//声明函数,此函数用来分类单词void fenxi(char *row,FILE *op)//此函数用来对每一行的单词进行语法分析

  //printf("%d\n",count);

 int k=0;//用作控制临时存放单词的变量str0

 int i=0;//定义两个变量用作控制每一行是否结束,

 int ferror=0;//用作出错标志

 char str0[20];//临时存放单词的变量

 while(i〈=len)

 {   

  k=0;//将k置0

  strcpy(word,”\0");//将存放单词的变量清空

  /*去除空格*/

  if(isspace(row[i]))//去出空格,跳格符,换行符

  {

   i++;

      continue;

  }

/*去出无效字符*/

 while(!

isalpha(row[i])&&!

isdigit(row[i])&&i<=len&&!

isspace(row[i])&&!

(row[i]==’\0'||row[i]==’:

’||row[i]=='>'||row[i]==’〈’||row[i]==’+’ || row[i]=='—' || row[i]=='*' || row[i]==’/’ || row[i]==’(’ || row[i]==’)’ || row[i]==',’ || row[i]==’;’|| row[i]=='.'|| row[i]==’#’ || row[i]==’=’))

 {

  putchar(row[i]);

  i++;

  ferror=1;//设置错误标志符

  

 }

  if(ferror==1)

  {

   error(3);//调用出错处理函数

   ferror=0;

  }

  /*对注释进行处理,假设此语言的注释只能单行注释以双斜杠“//”为注释开始标志*/

 if(row[i]=='/')

  {

   i++;

   if(row[i]==’/’)

   {

    i=len+1;//忽略注释符后面的单词

    continue;

   }

   else

    i--;

  } /*判断是否为数字*/

     if(isdigit(row[i]))

  {

       while(i〈=len&&!

isspace(row[i])&&!

(row[i]=='\0'||row[i]==':

’||row[i]=='〉'||row[i]=='〈'||row[i]==’+’ || row[i]==’—' || row[i]==’*’ || row[i]=='/' || row[i]=='(’ || row[i]==’)' || row[i]==',’ || row[i]==’;'|| row[i]=='.'|| row[i]==’#’ || row[i]=='=’))    //当不到行尾,是数字或字母当然有可能是无效字符

   {

                     

              if(isdigit(row[i]))//是数字则将字符逐个存入临时数组

      {     

            str0[k]=row[i];

                  i++;

      k++;

     // putchar('e’);

      }

         else //数字中加有字母或无效字符则报错

      {

      // putchar(’x’);

       ferror=1;break;//已经出错设置标志并退出循环

    

      }

   }

            if(ferror==1)//检测是否出错

   {  /*将刚刚的那个单词后面的数字和字母

    清空,如123abc123或则123$$23等,当出现错误后,需

    要消除abc123和$$23 以免误作为下一个标志符*/

    for(int j=0;j〈k;j++)

     putchar(str0[j]);

     while(i〈=len&&!

isspace(row[i])&&!

(row[i]==’\0’||row[i]==':

’||row[i]=='>'||row[i]==’〈'||row[i]=='+’ || row[i]=='-’ || row[i]=='*' || row[i]==’/' || row[i]=='(’ || row[i]==')' || row[i]==',’ || row[i]==’;’|| row[i]==’。

'|| row[i]==’#' || row[i]=='=’))

     {

                        putchar(row[i]);

      i++;

      

     }

      error

(1);//putchar('e');//调用出错处理函数

      ferror=0;//重新设置错误标志位

      //i-—;//strcpy(word,"”);

   }

      else//未出错照常处理

     {

      str0[k]='\0';

      strcpy(word,str0);

      i--;//减一是为了使最后取出的那个字符不在被下面的程序判断

     // str0[0]='\0';

     

     }

  }

  /*判断是否为标志符和关键字即由字母开头并且不含标点符号用ispunct(int ch)判断标点符号*/

     if(isalpha(row[i]))//标志符或关键字由字母开头

  {

   

   k=0;

      while(i〈=len&&row[i]!

=32&&!

(row[i]=='\0’||row[i]==’:

’||row[i]=='>'||row[i]=='<’||row[i]=='+' || row[i]=='-’ || row[i]==’*' || row[i]==’/' || row[i]==’(' || row[i]==’)’ || row[i]==',’ || row[i]==’;'|| row[i]=='.’|| row[i]=='#’ || row[i]=='='))//关键字和标志符由数字和字母组成

   {      

    if(isalpha(row[i])||isdigit(row[i]))//由数字和字母组成

    {

            str0[k]=row[i];

      i++;

      k++;

    }

    else//出错,原因可能是出现了不可识别的字符

    {

     

     

     ferror=1;break;

    }

      

   }

   if(ferror)

   {

    for(int j=0;j

     putchar(str0[j]);

    while(i〈=len&&!

isspace(row[i])&&!

(row[i]=='\0’||row[i]==':

’||row[i]=='>’||row[i]=='〈'||row[i]=='+' || row[i]==’—' || row[i]==’*’ || row[i]==’/’ || row[i]=='(’ || row[i]==')' || row[i]==',’ || row[i]==';’|| row[i]=='.'|| row[i]==’#’ || row[i]==’='))

    {

     putchar(row[i]);//消除整个非法单词

     i++;    }

    ferror=0;

    error(3);

    //i——;

   }

   else

   {

        str0[k]='\0’;

                 strcpy(word,str0);

        str0[0]=’\0’;

           i—-;

   }

        }

   /*判断运算符*/

         if(row[i]=='+' ||row[i]==’-' ||row[i]=='*' || row[i]=='/' || row[i]=='(' || row[i]==’)’ || row[i]==’,’ || row[i]==';’||row[i]==’。

’||row[i]==’#’ || row[i]==’=')

   {

    str0[0]=row[i];

    str0[1]='\0';

    strcpy(word,str0);

    str0[0]=’\0’;

  }//要先判断单个字符的运算符,以避免诸如>=的运算符后面的=再次被判断       if(row[i]==':

’)

  {

   i++;

   if(row[i]==’=’)

   {

    //word[0]=':

’;

    //word[1]='=’;

    //word[2]='\0’;

    strcpy(word,”〉=”);    }

              else 

     {

      error

(2);//出错后调用处理函数

      i—-;

     }

  }

  

  if(row[i]=='〉')

  {

   i++;

   if(row[i]==’=')

   { 

   

    strcpy(word,">=”);

   }

              else 

     {

      strcpy(word,"〉");

      i--;

     }   

  }

if(row[i]==’〈’)

  {

   i++;

   if(row[i]==’=')

   {

    strcpy(word,"<=”);    

   }

              else 

     {strcpy(word,”〈”);i—-;}   

  }

  

   //puts(word);

   

   

    check(word,op);/*

  调用分类函数,辨别每一个单词的类别要求

    输入的每一个单词必须符合词法规则*/

    //word[0]=’\0’;

     i++;//使指针后移,取出下一个字母 }

 }void check(char *str,FILE *out)

{  

   

    if(isdigit(str[0]))/*如果第一个字符是数字那么整个单词都是数字组成的,即为常数*/

    { 

     write(str,'d’,out);//调用写函数将分好类的单词写入文件

    } 

 

           if(isalpha(str[0]))/*如果第一个字符是字母,那么这个单词是标志符或关键字*/

     {   

            int fyiyong=0;//用作标记这个单词是否已被分类

               /*以下判别是否是关键字*/      for(int ct=0;ct<13;ct++)

      {

                    if(!

strcmp(str,kword[ct]))

     {

      write(str,ktype[ct],out);

      fyiyong=1;

     }

      }

    /*经过以上判别,可以判别是否是关键字,不是即为标志符*/

    if(fyiyong!

=1)

    {

               write(str,’e’,out);

    }

        }

     /*以下对运算符分类*/

     if(str[0]=='>’)

     {

      if(str[1]==’=')

      {

                   write(str,'b’,out);

      }

      else

      {

                   write(str,'>',out);

      }     }     if(str[0]=='<’)

     {

      if(str[1]==’=')

      {

                 write(str,'c’,out);

      }

      else

      {

                     write(str,'<’,out);

      }     }            

        if(!

strcmp(str,":

="))

     {

               write(str,’a',out);

     }

             

            

   if(str[0]==’+’ || str[0]=='-' || str[0]==’*' || str[0]=='/' || str[0]=='(' || str[0]==’)’ || str[0]==’,’ || str[0]==';'|| str[0]=='。

’|| str[0]=='#' || str[0]=='=’  ) 

   {

                    write(str,str[0],out);   }

    

          

}void main()

{ 

 count=1;

 char scfilename[20],rsfilename[20];//定义用来存放输入源文件和输出目标文件的名字

 printf("Please input your source file name:

");

 gets(scfilename);

    printf(”Please input your result file name:

");

 gets(rsfilename);

 FILE *fp,*op;

 fp=fopen(scfilename,”r");

    op=fopen(rsfilename,"w”);

 if(fp)//打开文件成功后调用函数对源文件进行词法分析

 {

      while(readbuffer(fp))

   {

      fenxi(buffer,op);

   count++;//行加一

        }

 }

 else//while the file not exist

 {

  printf(”Your souce file not exist!

!

!

\n”);

  exit(0);

 }

 fclose(fp);//close the files

 fclose(op);

    printf(”ok!

");//output the mark of end

    getchar();

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1