编写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<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<ctype.h>
#include<string.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); 
isalpha 函数
}
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 //数字中加有字母或无效字符则报错

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。