您的位置:首页 > 编程语言 > C语言/C++

【编译原理与技术】词法分析器(C++实现)

2020-01-15 06:45 579 查看

目录

注:

为了简化程序的编写,做了如下的限制:
(1) 空白符仅仅是空格、回车符、制表符。
(2) 代码是自由格式。
(3) 注释不允许嵌套。

单词:

根据要求,可以自行添加其他保留字或者特殊符号

实现功能:

  1. 识别单词并给出其类型
  2. 删除注释行
  3. 删除空白符 (空格、回车符、制表符)
  4. 在单词的前面加上行号
  5. 发现并定位错误。

算法分析

main()函数中负责读取文件中字符数据,并保存在prog【】数组中。利用while循环调用GetToken()函数,判断字符状态并进行输出。GetToken()函数中负责判断字符类型并标记其类型状态。

C++代码:

#include <string.h>
#include <string>
#include<iostream>
using namespace std;
char prog[1000],ch,ch1,token[1000];
int p=0,sym=0,n,line=1;
char filename[30];
FILE *fpin;
const char *keyword[21]={"if","else","while","do","main","int","float",
"double","return","const","void","continue","break","char",
"signed","enum","long","switch","case","auto","unsigned"};
void GetToken();
int main()
{
p=0;
cout<<"请输入源文件名:";
for(;;)
{
cin>>filename;
if((fpin=fopen(filename,"r"))!=NULL)//只读
{
break;
}
else
{
cout<<"文件输入错误!请输入源文件名:";
}
}
//将fpin中的所有字符通过ch传入字符数组prog[]中
do
{
ch=fgetc(fpin);
prog[p++]=ch;
}while(ch!=EOF);
p=0;
do
{
GetToken();//启动字符识别函数
//if(ch==EOF) break;
switch(sym)//打印字符状态
{
case 1:cout<<"("<<line<<" "<<token<<" "<<"标识符"<<")"<<endl;break;
case 2:cout<<"("<<line<<" "<<token<<" "<<"保留字"<<")"<<endl;break;
case 3:cout<<"("<<line<<" "<<token<<" "<<"整型"<<")"<<endl;break;
case 31:cout<<"("<<line<<" "<<token<<" "<<"浮点型"<<")"<<endl;break;
case 32:cout<<"("<<line<<" "<<token<<"S"<<" "<<"短类型"<<")"<<endl;break;
case 33:cout<<"("<<line<<" "<<token<<"L"<<" "<<"长类型"<<")"<<endl;break;
case 34:cout<<"("<<line<<" "<<token<<"O"<<" "<<"八进制数"<<")"<<endl;break;
case 35:cout<<"("<<line<<" "<<token<<"H"<<" "<<"十六进制数"<<")"<<endl;break;
case 4:cout<<"("<<line<<" "<<token<<" "<<"特殊符号"<<")"<<endl;break;
case -1:cout<<"("<<line<<" "<<"错误!"<<")"<<endl;break;
default:break;
}
}while(ch!=EOF);
return 0;
}

void GetToken()
{
sym=0;
//先把token[]数组清空
for (n=0;n<1000;n++)
{
token[n]='\0';
}
n=0;
ch=prog[p++];
ch1=prog

; //跳过空格,回车,tab的识别 while(ch==' '||ch=='\t') { ch=prog[p++]; } if(ch=='\n'){ line++; return; } if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch=='_')) { //标识符 状态1 sym=1; do{ token[n++]=ch; ch=prog[p++]; }while ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')); //比较标识符与keyword的关键字是否相同,若相同转为状态2 for(n=0;n<21;n++) { if(strcmp(token,keyword[n])==0){ sym=2; break; } } p--; return; } else if (ch>='0'&&ch<='9') { //识别到数字,置状态为3 sym=3; do { token[n++]=ch; ch=prog[p++]; if(ch=='.'){ sym=31; token[n++]=ch; ch=prog[p++]; } if(ch=='S'){ sym=32; ch=prog[p++]; } if(ch=='L'){ sym=33; ch=prog[p++]; } if(ch=='O'){ sym=34; ch=prog[p++]; } if(ch=='H'){ sym=35; ch=prog[p++]; } }while(ch>='0'&&ch<='9'); p--; return; } //跳过注释的内容 else if(ch=='/' && ch1=='*') { p++; do{ ch=prog[p++]; ch1=prog[p++]; if(ch=='\n'){ line++; } }while(ch!='*'||ch1!='/'); return; } else if(ch=='/'&& ch1=='/') { do{ ch=prog[p++]; }while(ch!='\n'); line++; return; } else if(ch=='='&& ch1=='='){ p++; sym=4; token[0]='='; token[1]='='; return; } else if(ch=='<'&& ch1=='='){ p++; sym=4; token[0]='<'; token[1]='='; return; } else if(ch=='>'&& ch1=='='){ p++; sym=4; token[0]='>'; token[1]='='; return; } else if(ch=='!'&& ch1=='='){ p++; sym=4; token[0]='!'; token[1]='='; return; } else if(ch=='&'&& ch1=='&'){ p++; sym=4; token[0]='&'; token[1]='&'; return; } else if(ch=='|'&& ch1=='|'){ p++; sym=4; token[0]='|'; token[1]='|'; return; } else { switch(ch)//识别关键符号 { case '=': case '<': case '>': case '/': case '+': case '-': case '*': case '{': case '}': case ';': case '(': case ')': case ',': case '\'': case '\"':sym=4;token[0]=ch;break; default:sym=-1;break; } } return; }

运行结果:

[p]

  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
@SlimShady 发布了48 篇原创文章 · 获赞 4 · 访问量 3377 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: