解析器最终版本

#include <stdio.h>

#include <ctype.h>

#define SIZE 512

#define CR '/n'

char file[300]="input.txt";//用于接收输入输出文件名

//定义分界符

char singleword[50]="+-=#;<>";

FILE *fin; //指向输入文件的指针

 

void main(){

int returnvalue=0;

cmdinput();

returnvalue=scan(); //进行词法分析

    if (returnvalue==1) printf("分析有错!The maxium length of token is 15 characters!/n");

else printf("分析成功!/n");

}

 

int scan()//词法分析函数

{

   char ch,chk=0,id[15]; //ch为每次读入的字符,chk为引号、回车检查所用量,id用于保存识别出的单词

   int i=1,j,n=0; //i,j为临时变量,n统计token个数

   int flag; //检查一行内是否有两个引号,是为1,否为0

   FILE *tmp; //用于存放文件读指针_IO_read_ptr的地址

   fin=fopen(file,"r"); 

   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++;

  chk=0;

  }

  }

  

  if (isalnum(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')

  {

  flag=0;

  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++;

  chk=0;

  }   

  }

  

  if (isalpha(ch)||isdigit(ch)) 

  {

  id[0]=ch; j=1;

  ch=getc(fin);

  while(isalnum(ch)) 

  {

  id[j++]=ch;

  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); //返回出错代码

}

 

void cmdinput() //输入函数

{

char buffer[SIZE]; //定义输入缓冲区大小

FILE *fp1;

fp1=fopen(file,"w");

printf("Command Line:/n");

printf("Input a blank line to exit!/n"); //输入一个空行以结束输入函数

gets(buffer);

while(fgets(buffer,SIZE,fp1)!=NULL||buffer[0]!=0)

{

fputs(buffer,fp1);

fputc(CR,fp1); //在每行后插入一个回车

gets(buffer);

}

fclose(fp1);

printf("Input end!/n/n");

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值