数据结构之简易词法分析(未包含错误分析)

#include <iostream>
#include <stdio.h>
#include <string>
#include <ctype.h>


const int WORD_SIZE=100; //用来存储临时变量的大小
int Line=1; //全局变量用以输出单词所在行数


using namespace std;


string Key1[20]={"asm","auto","break","case","cdecl","char","const","continue","default", //定义关键字表1
"do","double","else","enum","extern","far","float","for","goto","huge","if"};


string Key2[20]={"interrupt","int","long","near","pascal","register","return","short","signed", //定义关键字表2
"sizeof","static","struct","switch","typedef","union","unsigned","void",
"volatile","while","main"}; //其中main不为关键字,只为添加便于循环


char Alphaprocess(FILE* &fp,char ch){ //字母过程,用来判断标识符与关键字
char tempBuffer[WORD_SIZE]; //字符数组临时变量,用以存放该函数用以处理的字符串(字符数组)


int i=0;


while(ch=='_' || isalnum(ch) ){ //将其后多个字符存入字符数组中 isalnum()为库函数,以下判断字符或数字等的函数均来自ctype头文件
tempBuffer[i]=ch;
ch=getc(fp);
i++;
}

fseek(fp,-1,1); //多处理了一个字符,故将文件指针后移一个单位


tempBuffer[i]=NULL; //将数组中最后一个字符设为空,否则输出该字符数组时会有一系列乱码。比如:烫烫烫烫(编译环境为vc++6.0)


for(i=0;i<20;i++){ //将获得的字符数组与关键字表进行比较,输出编号为0
if(Key1[i]==tempBuffer || Key2[i]==tempBuffer){
cout<<"Line:"<<Line<<" "<<"(0,"<<tempBuffer<<")"<<endl;
return ch;
}
}


cout<<"Line:"<<Line<<" "<<"(1,"<<tempBuffer<<")"<<endl; //未找到关键字,则为标识符,输出编号为1
return ch;
}


char Digitprocess(FILE* &fp,char ch){ //数字过程,用以判断数字常量
char tempBuffer[WORD_SIZE];
int i=0;


while(isdigit(ch) || ch=='.'){
tempBuffer[i]=ch;
ch=getc(fp);
i++;
}

fseek(fp,-1,1);                           //对多处理的一个字符进行还原


tempBuffer[i]=NULL;

cout<<"Line:"<<Line<<" "<<"(2,"<<tempBuffer<<")"<<endl; //数字编号为3
return ch;
}


char Otherprocess(FILE* &fp,char ch){ //特殊符号过程
int id=3;
char tempBuffer[3];


tempBuffer[0]=ch;
tempBuffer[1]=NULL;


if(ch=='(' || ch==')' || ch=='{' || ch=='}' || ch=='[' || ch==']'
|| ch==',' || ch==';'){
id=4;
}




if(ch=='-'){ //对特殊符号进行补充
ch=getc(fp);
if(ch=='=' || ch=='-') //判断-=  与 --
tempBuffer[1]=ch;
else{
fseek(fp,-1,1);
}
}


if(ch=='+'){
ch=getc(fp);
if(ch=='=' || ch=='+')
tempBuffer[1]=ch;
else{
fseek(fp,-1,1);
}
}


if(ch=='>'){
ch=getc(fp);
if(ch=='=')
tempBuffer[1]=ch;
else{
fseek(fp,-1,1);
}
}


if(ch=='<'){
ch=getc(fp);
if(ch=='=')
tempBuffer[1]=ch;
else{
fseek(fp,-1,1);
}
}

if(ch=='!'){
ch=getc(fp);
if(ch=='=')
tempBuffer[1]=ch;
else{
fseek(fp,-1,1);
}
}


if(ch=='='){
ch=getc(fp);
if(ch=='=')
tempBuffer[1]=ch;
else{
fseek(fp,-1,1);
}
}




tempBuffer[2]=NULL;


cout<<"Line:"<<Line<<" "<<"("<<id<<","<<tempBuffer<<")"<<endl;
return ch;
}


void main()
{
char ch;
FILE *fp;
char file[100];
cout<<"输入你要进行词法分析的文件:";
cin>>file;


cout<<"---------------------------------------------------"<<endl;
cout<<"---------------------------------------------------"<<endl;
cout<<endl;
cout<<endl;


if((fp=fopen(file,"r"))==NULL){ //打开文件
cout<<"File opened Error!"<<endl;
return;
}


do{ //将文件内容输出到命令行窗口
ch=getc(fp);
cout<<ch;
}while(ch!=EOF);

fseek(fp,0,0); //将文件指针移动至文件开始处


cout<<endl;
cout<<endl;

do{
ch=getc(fp); //第二次对文件进行遍历,将取得的各个字符用相对应的过程函数解决
if(ch==' ' || ch=='\n'){
if(ch=='\n')
Line++; //遇到换行符,行号加1
}
// ch=getc(fp);
else if(isalpha(ch) || ch=='_')
ch=Alphaprocess(fp,ch); //以各个对应的函数解决
else if(isdigit(ch))
ch=Digitprocess(fp,ch);
else if(ispunct(ch))
ch=Otherprocess(fp,ch);
}while(ch!=EOF);


fclose(fp); //关闭文件*/

}


//课程较紧,老师也未深入讲解,故只做了简单地分析,也有很多未考虑的地方,不足之处也显而易见,对于注释的解决,浮点数的判断正误,函数名的判别等等




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值