analyst.cpp
来自「一个简单的词法分析器」· C++ 代码 · 共 397 行
CPP
397 行
// ANALYST.cpp: implementation of the ANALYST class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ANALYST.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ANALYST::ANALYST()
{
char *key[]={"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"}; //C++语言关键字
char *limit[]={"+=","-=","*=","/=","==","!=","&&","||",">=","<=",">>","<<","--","++",
"->","#","(",")","[","]",".","!","~","*","/","%","+","-","<",">",
"=",",",";","{","}","_","'",":","&"};//运算、限界符
Line=1;
Errorno=0;
fstream outfile;
int i,j;
outfile.open("Key.txt",ios::out); //创建关键字表并写入关键字
for(i=0;i<32;i++)
outfile<<key[i]<<endl;
outfile.close();
outfile.open("Limit.txt",ios::out); //创建运算符、界符表并写入运算符、界符
for(j=0;j<39;j++)
outfile<<limit[j]<<endl;
outfile.close();
outfile.open("Bsf.txt",ios::out); //创建标识符表
outfile.close();
outfile.open("Data.txt",ios::out); //创建数据表
outfile.close();
outfile.open("Output.txt",ios::out); //创建目标代码文件
outfile<<'1'<<" ";
outfile.close();
outfile.open("Error.txt",ios::out); //创建出错记录文件
outfile.close();
}
ANALYST::~ANALYST()
{
}
void ANALYST::Bsfdeal(char *word) //关键字,标识符处理函数
{
fstream outfile,infile,outchar;
int number=0,find=0,i;
char ch;
char temp[30];
infile.open("Key.txt",ios::in); //打开关键字表,寻找匹配关键字
infile.get(ch);
while(ch!=EOF&&ch!='\n')
{
i=0;
while(ch!='\n')
{
temp[i++]=ch;
infile.get(ch);
}
temp[i]='\0';
number++;
if(strcmp(temp,word)==0)
{
outchar.open("Output.txt",ios::app); //若找到匹配关键字,写入目标代码文件
outchar<<word<<" ";
outchar.close();
infile.close();
find=1;
}
else //向下搜寻
infile.get(ch);
}
infile.close();
if(find==0) //若不是关键字,则搜寻标识符
{
infile.open("Bsf.txt",ios::in);
infile.get(ch);
while(ch!=EOF&&ch!='\n')
{
i=0;
while(ch!='\n')
{
temp[i++]=ch;
infile.get(ch);
}
temp[i]='\0';
number++;
if(strcmp(temp,word)==0) //若找到匹配标识符,写入目标代码文件
{
outchar.open("Output.txt",ios::app);
outchar<<word<<" ";
outchar.close();
infile.close();
find=1;
}
else
infile.get(ch); //向下搜寻
}
infile.close();
if(find==0) // 若未找到匹配标识符,则为新标识符,写入标识符表
{
outfile.open("Bsf.txt",ios::app);
outfile<<word<<endl;
outfile.close();
outchar.open("Output.txt",ios::app); //新标识符写入目标代码文件
outchar<<word<<" ";
outchar.close();
}
}
}
void ANALYST::Intdeal(char *word) //数据处理函数
{
fstream infile,outfile,outchar;
int number=0,find=0,i;
char ch;
char temp[30];
infile.open("Data.txt",ios::in); //打开数据表,寻找匹配数据
infile.get(ch);
while(ch!=EOF&&ch!='\n')
{
i=0;
while(ch!='\n')
{
temp[i++]=ch;
infile.get(ch);
}
temp[i]='\0';
number++;
if(strcmp(temp,word)==0) //若找到匹配数据,写入目标代码文件
{
outchar.open("Output.txt",ios::app);
outchar<<word<<" ";
outchar.close();
infile.close();
find=1;
}
else //否则,向下搜寻
infile.get(ch);
}
infile.close();
if(find==0) //若未找到,则写入数据表
{
outfile.open("Data.txt",ios::app);
outfile<<word<<endl;
outfile.close();
outchar.open("Output.txt",ios::app); //写入目标代码文件
outchar<<word<<" ";
outchar.close();
}
}
void ANALYST::Limitdeal(char *word, int line,fstream Infile) //运算符、界符处理函数
{
int number=0,find=0,i;
char ch;
char temp[30];
fstream infile,outfile, outchar;
infile.open("Limit.txt",ios::in); //打开界符表,开始搜寻
infile.get(ch);
while(ch!='#'&&ch!='\n') //先搜寻双字符
{
i=0;
while(ch!='\n')
{
temp[i++]=ch;
infile.get(ch);
}
temp[i]='\0';
number++;
if(strcmp(temp,word)==0) //若找到,写入目标代码文件
{
outchar.open("Output.txt",ios::app);
outchar<<word<<" ";
outchar.close();
infile.close();
find=1;
}
else
infile.get(ch);
}
if(find==0) //若不是双字符,则搜寻单字符
{
Infile.seekg(-1,ios::cur);
word[1]='\0';
while(ch!=EOF&&ch!='\n')
{
i=0;
while(ch!='\n')
{
temp[i++]=ch;
infile.get(ch);
}
temp[i]='\0';
number++;
if(strcmp(temp,word)==0) //若为单字符,写入目标代码文件
{
outchar.open("Output.txt",ios::app);
outchar<<word<<" ";
outchar.close();
infile.close();
find=1;
}
else
infile.get(ch);
}
infile.close();
if(find==0) //否则为无法识别字符,进行错误处理
{
Errorno++;
outfile.open("Error.txt",ios::app); //错误信息写入出错记录文件
outfile<<"第"<<line<<"行"<<"字符"<<" "<<word<<" "<<"出错"<<endl;
outfile.close();
outfile.open("Output.txt",ios::app); //标记出错点
outfile<<"^_^";
outfile.close();
}
}
}
void ANALYST::Scanner() //扫描函数
{
char temp[30],line[80];
char ch;
char*word;
int i;
fstream Infile, Outfile,Intxt;
char Filename[20];
cout<<"请输入需编译的文件名:";
cin>>Filename;
Infile.open(Filename,ios::nocreate|ios::in); //打开需编译的文件
while(! Infile)
{
cout<<"此文件不存在"<<endl;
exit(0);
}
cout<<endl<<endl;
cout<<"需编译的文件内容为:"<<endl;
Intxt.open(Filename,ios::in); //输出需编译的文件内容
while(Intxt.getline(line,80))
cout<<line<<endl;
Intxt.close();
Infile.get(ch); //开始扫描文件
while(ch!=EOF) //按字符依次扫描源程序,直至结束
{
i=0;
if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')) //识别标识符
{
while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||((ch>='0')&&(ch<='9')))
{
temp[i++]=ch;
Infile.get(ch);
}
word=new char[i+1];
memcpy(word,temp,i);
word[i]='\0';
Bsfdeal(word);
delete []word;
Infile.seekg(-1,ios::cur);
}
else if(ch>='0'&&ch<='9')
{ //识别数字
while(ch>='0'&&ch<='9')
{
temp[i++]=ch;
Infile.get(ch);
}
word=new char[i+1];
memcpy(word,temp,i);
word[i]='\0';
Intdeal(word);
delete []word;
Infile.seekg(-1,ios::cur);
}
else if((ch==' ')||(ch=='\t')) //消除空格符和水平制表符
{
}
else if(ch=='\n') //消除回车并记录行数
{
Line++;
Outfile.open("Output.txt",ios::app);
Outfile<<endl;
Outfile<<Line<<" ";
Outfile.close();
}
else if(ch=='/')
{ //消除注释
Infile.get(ch);
if(ch=='=')
{ //判断是否为‘/=’符号
Outfile.open("Output.txt",ios::app);
Outfile<<"/="<<' ';
Outfile.close();
}
else if(ch=='*')
{ //若为多行注释的开始,消除包含在里面的所有字符
int count=0;
Infile.get(ch);
while(count!=2)
{ //当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束
count=0;
while(ch!='*')
Infile.get(ch);
count++;
Infile.get(ch);
if(ch=='/')
count++;
else
Infile.get(ch);
}
}
else if(ch=='/') //消除单行注释
{
do
Infile.get(ch);
while(ch!='\n'&&ch!=EOF);
if(ch=='\n')
{
Line++;
Outfile.open("Output.txt",ios::app);
Outfile<<endl;
Outfile<<Line<<" ";
Outfile.close();
}
else
Infile.seekg(-1,ios::cur);
}
else if(ch==EOF) //若为文件末尾,则后退一个字符
Infile.seekg(-1,ios::cur);
else
{
Outfile.open("Output.txt",ios::app);
Outfile<<"/"<<" ";
Outfile.close();
Infile.seekg(-1,ios::cur);
}
}
else if(ch=='"')
{ //处理包含在双引号中的字符串常量
Outfile.open("Output.txt",ios::app);
Outfile<<ch<<" ";
do
{
Infile.get(ch);
Outfile<<ch;
}
while(ch!='"');
Outfile<<" ";
Outfile.close();
}
else
{ //首字符为其它字符,即运算符,界符或非法字符
temp[0]=ch;
Infile.get(ch); //读入下一个字符,判断是否为双字符运算、限界符
if(ch!=EOF&&ch!='\n')
{
temp[1]=ch;
word=new char[3];
memcpy(word,temp,2);
word[2]='\0';
Limitdeal(word,Line,Infile); //若为运算符界符,调用函数进行处理
delete []word;
}
else
{ //若读入的下一个字符为文件结束符,处理后需后退
word=new char[2];
memcpy(word,temp,1);
word[1]='\0';
Limitdeal(word,Line,Infile);
delete []word;
Infile.seekg(-1,ios::cur);
}
}
Infile.get(ch);
}
Infile.close();
cout<<endl<<endl;
cout<<"编译后的目标代码为:"<<endl;
Infile.open("Output.txt",ios::in); //输出编译后的目标代码
while(Infile.getline(line,80))
cout<<line<<endl;
Infile.close();
if(Errorno!=0)
{
cout<<"文件共有"<<Errorno<<"个错误"<<endl;
Infile.open("Error.txt",ios::in);
while(Infile.getline(line,80)) //输出错误信息
cout<<line<<endl;
Infile.close();
}
else
cout<<"文件错误0个"<<endl;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?