注:
为了简化程序的编写,做了如下的限制:
(1) 空白符仅仅是空格、回车符、制表符。
(2) 代码是自由格式。
(3) 注释不允许嵌套。
单词:
根据要求,可以自行添加其他保留字或者特殊符号
实现功能:
- 识别单词并给出其类型
- 删除注释行
- 删除空白符 (空格、回车符、制表符)
- 在单词的前面加上行号
- 发现并定位错误。
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();//启动字符识别函数
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[p];
//跳过空格,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=='/')
{
p++;
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;
}
运行结果:
转载:https://blog.csdn.net/qq_43207916/article/details/102486491
查看评论