简单的解析器

#include <stdio.h>
#include <ctype.h>
#include <iostream>
char PL0Scanin[300]="1.txt"; //用于接收输入输出文件名
//下面定义纯单分界符,如需要可添加
char singleword[50]="+-=#;<>";
FILE *fin; //用于指向输入输出文件的指针
void main(){
   int es=0;
   es=PL0scan();//词法分析   
    if (es==1) printf("分析有错!The maxium length of token is 15 characters!/n");
      else printf("分析成功!/n");
      return 0;
}

int PL0scan()//词法分析函数
{
   char ch,chk=0,id[15]; //ch为每次读入的字符,id用于保存识别出的单词
   FILE *tmp;
   int number=0; //number用于保存识别出的数字
   int i=1,j,n=0; //es错误代码,0表示没有错误。j,n为临时变量,控制组合单词时的下标等
   int flag;
    if ((fin=fopen(PL0Scanin,"r"))==NULL) //判断输入文件名是否正确
   {
      printf("/n打开词法分析输入文件出错!/n");
      return(1);//输入文件出错返回错误代码1
   }
    ch=getc(fin);
    start:   while(ch!=EOF)
   {
      while (ch==' '||ch=='/n') 
         {
            chk=ch;
            ch=getc(fin);
            if (ch==EOF) goto end;            
            else if(ch=='/n')
               goto end;
            else if(ch!='/n'&&chk!=' '&&chk!=34)
            {
               printf("token[%d] is/t<CR>/n",i);
               fseek(fin,-1L,1);
               ch=getc(fin);
               i++;
            }
         }
      
      if (isalpha(ch)||isdigit(ch))   //如果是字母,则进行标识符处理
      {
         id[0]=ch; j=1;
         ch=getc(fin);
         while(isalnum(ch))  //如果是字母数字则组合标识符;如果不是则标识符组合结束
         {
            id[j++]=ch;  //组合的标识符保存在id中
            ch=getc(fin);  //读下一个字符
            if(j>15)
               goto error;
         }
         id[j]='/0';  //标识符组合结束
         printf("token[%d] is/t",i);
         puts(id);
      }
      else if (strchr(singleword,ch)>0)  //单分符处理
      {
         id[0]=ch; id[1]='/0';
         ch=getc(fin);//读下一个符号以便识别下一个单词
         printf("token[%d] is/t",i);  //输出单分界符符号
         puts(id);
      }
      else if (ch==',')  //单分符处理
      {
         ch=getc(fin);//读下一个符号以便识别下一个单词
         i--;
      }
      
      else if (ch==34)
      {
            tmp=fin->_IO_read_ptr;
            while(1)
            {
               if(chk==34)
               {flag=1;break;}
               else if(chk=='/r'||chk=='/n')
                  break;
               else
                  flag=0;
               chk=getc(fin);

            }
       
      if (flag==0)
      {
         fin->_IO_read_ptr=tmp;
         id[0]=34;id[1]='/0';
         ch=getc(fin);
         printf("token[%d] is/t",i);
         puts(id);
         i++;
         goto start;
      }
      else
      {   
         fin->_IO_read_ptr=tmp;
         ch=getc(fin);
         while(ch!=EOF)
         {
               while (ch==' '||ch==34||ch=='/n') 
               {
                  chk=ch;
                  ch=getc(fin);
                  if (ch==EOF) goto end;
                  if (ch!='/n'&&chk!=' '&&chk!=34)
                  {
                     printf("token[%d] is/t<CR>/n",i);
                     fseek(fin,-1L,1);
                     ch=getc(fin);
                     i++;
                  }
               }
               
               if (isalpha(ch)||isdigit(ch))   //如果是字母,则进行标识符处理
               {
                  id[0]=ch; j=1;
                  ch=getc(fin);
                  while(isalnum(ch))  //如果是字母数字则组合标识符;如果不是则标识符组合结束
                  {
                     id[j++]=ch;  //组合的标识符保存在id中
                     ch=getc(fin);  //读下一个字符
                     if(j>15)
                        goto error;
                  }
                  id[j]='/0';  //标识符组合结束
                  printf("token[%d] is/t",i);
                  puts(id);
               }
               else if (strchr(singleword,ch)>0)  //单分符处理
               {
                  id[0]=ch; id[1]='/0';
                  ch=getc(fin);//读下一个符号以便识别下一个单词
                  printf("token[%d] is/t",i);  //输出单分界符符号
                  puts(id);
               }
               else if (ch==',')  //单分符处理
               {
                  ch=getc(fin);//读下一个符号以便识别下一个单词
                  i--;
               }
            i++;
            flag=0;
            goto start;
         }
      }
      }
   i++;
   }
   fclose(fin);//关闭输入输出文件
   end:      return(0);  //返回主程序
   error:   return(1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值