📄 lex.cpp
字号:
#include<iostream>
#include<fstream>
#include<string>
#include<cmath>
using namespace std;
int colume=0;
int *ERROR=new int [100];
int error=0;
struct table
{
string *pst;
int size;
int length;
};
struct tablenum
{
double *pst;
int size;
int length;
};
bool Keyword(char c,string *KEYWORD,int KNLength,ifstream &infile,
table &table_key,table &table_ID,table &table_operator,table &table_delimiter);
bool Identify(char c,ifstream &infile,string &strtemp,table &table_ID,
table &table_operator,table &table_delimiter);
bool ConstN(char c,ifstream &infile,table &table_const);
bool ConstStr(char c,ifstream &infile,table &table_const);
bool ConstChar(char c,ifstream &infile,table &table_const);
bool ConstNum(char c,ifstream &infile,tablenum &table_const,table &table_operator,
table &delimiter);
bool Operator(char c,ifstream &infile,table &table_operator,table &table_delimiter);
bool Delimiter(char c,table &table_delimiter );
void Getword(table &table_sub,string stemp);
void Getnum(tablenum &table_sub,double temp);
int classfify(char c);
int classify_num(char c);
//输出控制函数
void Manager(table &table_key,table &table_ID,table &table_operator,
table &table_delimiter,table &table_const,tablenum &table_num);
void Outtenspace();
void ShowError(char &select1) ;
void ShowDelimiter(table &table_delimiter,char &select1) ;
void ShowOperator(table &table_operator,char &select1);
void ShowConst(table &table_const,tablenum &table_num,char &select1);
void ShowID(table &table_ID,char &select1);
void ShowKeywords(table &table_key,char &select1);
//写文件
void Outputfile(table & table_sub,char *p,int a);
void Outputfile(tablenum &table_num,char *p,int a);
void Outputfile(char *P);
int main()
{
//读出关键字
string KEYWORD[80];
int KNLength=0;
ifstream inf("KEYWORD.txt",ios::in);
if(!inf){cout<<"error";exit(1);}
int i=0;
while(inf>>KEYWORD[i])
i++;
KEYWORD[i]="-1";
KNLength=i;
inf.close();
//初始化关键字表
table table_key;
table_key.pst=new string [50];
table_key.size=50;
table_key.length=0;
//初始化标识符表
table table_ID;
table_ID.pst=new string [50];
table_ID.length=0;
table_ID.size=50;
//初始化字符串常量字符表
table table_const;
table_const.pst=new string[50];
table_const.length=0;
table_const.size =50;
//初始化数字常量字符表
tablenum table_num;
table_num.pst=new double[50];
table_num.length=0;
table_num.size=50;
//运算符字符表
table table_operator;
table_operator.pst=new string [50];
table_operator.length=0;
table_operator.size =50;
//界符字符表
table table_delimiter;
table_delimiter.pst=new string[100];
table_delimiter.length =0;
table_delimiter.size =100;
ifstream infile("procedure.txt",ios::in);
if(!infile){cout<<"error";exit(1);}
char c;
while(infile.get(c))
{
if(c>='a'&&c<='z')
Keyword( c,KEYWORD,KNLength,infile,table_key,table_ID,
table_operator,table_delimiter);
else if((c>='A'&&c<='Z')||c=='_')
{
string strtemp;
Identify( c,infile,strtemp,table_ID,table_operator,table_delimiter);
}
else if((c=='\"')||(c=='\''))
{
//cout<<"NUM"<<endl;
ConstN( c,infile,table_const);
//cout<<c<<endl;
}
else if(c>='0'&&c<='9')
ConstNum(c,infile,table_num,table_operator,table_delimiter);
else if(classfify(c)==2)
Operator(c,infile,table_operator,table_delimiter);
else if(classfify(c)==1)
Delimiter(c,table_delimiter );
else
{
if(c==10||c==13)
colume++;
}
}
infile.close();
//写文件
Outputfile(table_key,"table_key.txt",3);
Outputfile(table_ID,"table_ID.txt",1);
Outputfile(table_delimiter,"table_delimiter.txt",5);
Outputfile(table_operator,"table_operator.txt",4);
Outputfile(table_const,"table_const.txt",2);
Outputfile(table_num,"table_num.txt",2);
Outputfile("error.txt");
//进主菜单
Manager(table_key,table_ID,table_operator,table_delimiter,table_const,table_num);
//
return 0;
}
bool Keyword(char c,string *KEYWORD,int KNLength,
ifstream &infile,table &table_key,table &table_ID
,table &table_operator,table &table_delimiter)
{
string keystemp;
int i=0;
for(;i<KNLength;i++)
{
int k=0;
//如果已经提取的有字符了
if(keystemp.length()!=0)
{
for(;k<keystemp.length();k++)
{
if(keystemp[k]!=KEYWORD[i][k])break;
else continue;
}
}
//如果不匹配
if(k!=keystemp.length())continue;
//判断是否匹配
for(int j=k;j<KEYWORD[i].length();j++)
{
if(c!=KEYWORD[i][j])
break;
else
{
keystemp+=c;//如果匹配,加入keystemp
if(infile.get(c)) //读取下一个字符
{
if((c>='a'&&c<='z')||c=='_')continue;
switch(classfify(c))
{
case 0://ERROR
ERROR[error]=colume;
error++;
return 0;
case 1:if(j==KEYWORD[i].length()-1)//如果和关键字匹配
{
Getword(table_key,keystemp);
Delimiter(c,table_delimiter);
return 1;
}
else//如果和关键字不匹配
{
Getword(table_ID,keystemp);
Delimiter(c,table_delimiter);
return 0;
}
case 2:if(j==KEYWORD[i].length()-1)//如果和关键字匹配
{ //如果空间不够再增加20
Getword(table_key,keystemp);
Operator(c,infile,table_operator,table_delimiter);
return 1;
}
else//如果和关键字不匹配
{
Getword(table_ID,keystemp);
Operator(c,infile,table_operator,table_delimiter);
return 0;
}
case 3:if(c==' ')
{
if(j==KEYWORD[i].length()-1)
{
Getword(table_key,keystemp);
return 1;
}
else
{
Getword(table_ID,keystemp);
return 0;
}
}
else if(c==10||c==13)
{
if(j==KEYWORD[i].length()-1)
{
Getword(table_key,keystemp);
colume++;
return 1;
}
else
{
Getword(table_ID,keystemp);
colume++;
return 0;
}
}
}
}
else//如果是最后结尾
{
if(j==KEYWORD[i].length()-1)
Getword(table_key,keystemp);
}
}
}
}
if(i==KNLength)
{
Identify( c,infile,keystemp,table_ID,table_operator,table_delimiter);
return 0;
}
//cout<<"ID "<<c<<endl;
}
bool Identify(char c,ifstream &infile,string &strtemp,table &table_ID
,table &table_operator,table &table_delimiter)
{
while(1)
{
if((c>='0'&&c<='9')||(c>='A'&&c<='Z')||(c>='a'&&c<='z')||c=='_')
strtemp+=c;
else
{
switch(classfify(c))
{
case 0:ERROR[error]=colume;
error++;
return 0;
case 1:Getword(table_ID,strtemp);
Delimiter(c,table_delimiter);
return 1;
case 2:Getword(table_ID,strtemp);
//CALL OPERATOR
Operator(c,infile,table_operator,table_delimiter);
return 1;
case 3:Getword(table_ID,strtemp);
if(c==13||c==10)
colume++;
return 1;
}
}
if(!infile.get(c))
break;
}
return 0;
}
bool ConstN(char c,ifstream &infile,table &table_const)
{
bool b=0;
if(c=='\"')
b=ConstStr(c,infile,table_const);
else//(c=='\'')
b=ConstChar(c,infile,table_const);
return b;
}
bool ConstStr(char c,ifstream &infile,table &table_const)
{
string strstemp="\"";
while(infile.get(c))
{
if(c!='\"')
strstemp+=c;
else break;
}
strstemp+='\"';
Getword(table_const, strstemp);
return 1;
}
//提取字符常量
bool ConstChar(char c,ifstream &infile,table &table_const)
{
string strstemp="\'";
infile.get(c);
strstemp+=c;
infile.get(c);
strstemp+=c;
Getword(table_const, strstemp);
return 1;
}
//提取数字常量
bool ConstNum(char c,ifstream &infile,tablenum &table_num,
table &table_operator,table &table_delimiter)
{// 1
double temp=0;//存放当前数据
int locatespot=1;//当前输入数字离小数点位置
double power=0;//权值
bool spot_appear=0;//小数点是否出现0表示没出现1表示出现
bool E_appear=0;//E或者e是否出现0表示没出现,1表示出现
bool add_sub=0;//E后面的数字0为加,1为减
bool num=0;//E后面是否有数字,如果有则1,否则0
while(1)
{// 2
switch(classify_num(c))
{// 3
case 0://ERROR
ERROR[error]=colume;
error++;
return 0;
case 1:Getnum(table_num,temp);//当遇到界符,提取当前数据
Delimiter(c,table_delimiter);//提取界符
return 1;//返回
case 2://如果是构成数字含义的字符0-9,+,-,E,e,.
if(E_appear!=1)//E未出现
{//4
if(spot_appear!=1)//小数点未出现
{//5
if(c>='0'&&c<='9')//如果是数字则运算提取
{
temp=temp*10+(c-48);
}
else if(c=='.')//如果是小数点则标记
{
spot_appear=1;
Delimiter(c,table_delimiter);//提取界符
}
else if(c=='E'||c=='e')//如果是E或者e,标记
E_appear=1;
else //+|-
{//6
//
Getnum(table_num, temp);
//CALL OPERATOR
Operator(c,infile,table_operator,table_delimiter);
return 1;
}//6
}//5
else //spot_appear==1
{//5.1
//
if(c>='0'&&c<='9')//如果数字则提取事实上算的是小数部分,整数部分没变
{//6.1
temp=temp+(c-48)*pow(10.0,double(0-locatespot));
locatespot++;
}//6.1
else if(c=='e'||c=='E')
{//6.2
if(locatespot==1)//ERROR ,E出现在小数点后
{
ERROR[error]=colume;//加入错误信息数组
return 0;
}
else E_appear=1;
}//6.2
else if(c=='-'||c=='+')//如果遇到+或者-
{//6.3
//提取运算符
Operator(c,infile,table_operator,table_delimiter);
if(locatespot==1)//error如果+或者-出现于小数点后,错误
{
ERROR[error]=colume;
error++;
}
else //如果+和-当前表示运算符正确则提取数字
{//7
Getnum(table_num,temp);
//CALL OPERATOR
Operator(c,infile,table_operator,table_delimiter);
return 1;
}//7
}//6.3
else //(c=='.')//ERROR 小数点再次出现
{
ERROR[error]=colume;
error++;
return 0;
}
}//5.1
}//4
else //E或者e出现
{//4.1
if(c=='-'&&num==0)//-紧紧出现在E后面
{
add_sub=1;//E的权值为负数
Operator(c,infile,table_operator,table_delimiter);
}
else if(c=='+'&&num==0)//+紧紧出现于E后面
{
add_sub=0;//E的权值为正数
Operator(c,infile,table_operator,table_delimiter);
}
else if(c>='0'&&c<='9')
{//5.2
//计算E的权值
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -