编译原理:词法分析器实现
Posted 一只特立独行的猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编译原理:词法分析器实现相关的知识,希望对你有一定的参考价值。
用C++定义了一个类,可以自定义保留字,通过调用类的方法来实现词法分析的功能,封装的还是挺高的。
前提假设
状态 | 内容 | 类别 |
---|---|---|
1 | main、if、int、for、while、do、return、break、continue… | 保留字 |
2 | 标识符 | |
3 | 常数 | |
4 | +、-、*、/、=、>、<、>=、<=、!= | 运算符 |
5 | 、;、、、(、) | 分割符 |
正规式
标识符:
(a|b|c…z|A|B|…|Z)(a|b|c…z|A|B|…|Z|0|1|2…9|)*
常数:
(0|1|2…9|)*
输入格式:
输出格式:
代码:
#include<iostream>
#include<string>
#include<fstream>
#include<map>
#include<vector>
class Compiler
protected:
std::map<std::string,int> table;//单词表格,包含了标识符表与
std::string *key_table;//保留字表
int key_len;
std::string singalword;
std::string doubleword;
std::vector<std::string> operator_table;//运算符表
std::vector<std::string> limitation_table;//界符表
public:
Compiler(int key_len,std::string *key_table);
void begin_compiler(std::string fin,std::string fout);
int lookup(std::string temp);
bool isOperator(std::string temp);
bool isLimitation(std::string temp);
;
Compiler::Compiler(int key_len,std::string *key_table)
Compiler::key_table = key_table;
Compiler::key_len = key_len;
Compiler::singalword = "+-*();,:";
Compiler::doubleword = "><=!!";//需要使用超前搜索
Compiler::operator_table = std::vector<std::string> "+", "-","*","/","=",">","<",">=","<=","!=";
Compiler::limitation_table = std::vector<std::string> ",", ";","","","(",")";
int Compiler::lookup(std::string temp)
int j=0;
for(auto i=key_table;j<Compiler::key_len;i++,j++)
if((*i)==temp)
//temp是保留字
return 0;
return 1;
bool Compiler::isOperator(std::string temp)
for(auto i=Compiler::operator_table.begin();i!=Compiler::operator_table.end();i++)
if((*i)==temp)
return true;
return false;
bool Compiler::isLimitation(std::string temp)
for(auto i=Compiler::limitation_table.begin();i!=Compiler::limitation_table.end();i++)
if((*i)==temp)
return true;
return false;
void Compiler::begin_compiler(std::string fin,std::string fout)
char c;
std::ifstream ifile(fin,std::ios::in);//打开fin文件
std::ofstream ofile(fout,std::ios::out);//打开fin文件
if (!ifile)
std::cout<<"输入文件打开失败!"<<std::endl;
if (!ofile)
std::cout<<"输出文件打开失败!"<<std::endl;
ifile>>c;
while (!ifile.eof())
while(c==' '||c=='\\n'||c=='\\r'||c=='\\t') ifile>>c;//处理空格与无意义字符
if(isalpha(c))
//字母开头
std::string temp="";
temp = temp + c;
ifile.get(c);
while (!ifile.eof()&&(isdigit(c)||isalpha(c)))
temp = temp + c;
ifile.get(c);
if(!lookup(temp))
//temp是保留字
table.insert(std::pair<std::string,int>(temp,1));//将(value,type)存入标识符表
ofile<<"("<<1<<","<<temp<<")"<<std::endl;
else
//temp是标识符
table.insert(std::pair<std::string,int>(temp,2));//将(value,type)存入标识符表
ofile<<"("<<2<<","<<temp<<")"<<std::endl;
else if(isdigit(c))
//数字开头
std::string temp="";
temp = temp + c;
ifile.get(c);
while (!ifile.eof()&&isdigit(c))
temp = temp + c;
ifile.get(c);
table.insert(std::pair<std::string,int>(temp,3));//将(value,type)存入标识符表
ofile<<"("<<3<<","<<temp<<")"<<std::endl;
else if(Compiler::singalword.find(c)!=std::string::npos)
//一定为单字符单词
std::string temp="";
temp = temp + c;
if(isLimitation(temp))
table.insert(std::pair<std::string,int>(temp,5));//temp为界符
ofile<<"("<<5<<","<<temp<<")"<<std::endl;
else if(isOperator(temp))
table.insert(std::pair<std::string,int>(temp,4));//temp为运算符
ofile<<"("<<4<<","<<temp<<")"<<std::endl;
ifile.get(c);
else if(Compiler::doubleword.find(c)!=std::string::npos)
//可能为双字符单词或单字符单词
std::string temp="";
temp = temp + c;
ifile.get(c);
if(ifile.eof())
//到文件尾部,肯定是单字符
if(isLimitation(temp))
table.insert(std::pair<std::string,int>(temp,5));//temp为界符
ofile<<"("<<5<<","<<temp<<")"<<std::endl;
else if(isOperator(temp))
table.insert(std::pair<std::string,int>(temp,4));//temp为运算符
ofile<<"("<<4<<","<<temp<<")"<<std::endl;
break;
std::string temp1 = temp+c;
if(isOperator(temp1))
//为双字符
table.insert(std::pair<std::string,int>(temp1,4));//temp为双字符运算符
ofile<<"("<<4<<","<<temp1<<")"<<std::endl;
ifile.get(c);
else
table.insert(std::pair<std::string,int>(temp,4));//temp为单字符运算符
ofile<<"("<<4<<","<<temp<<")"<<std::endl;
else
//出错处理
ofile<<"(ERROR,"<<c<<")"<<std::endl;
ifile.get(c);
int main()
int key_len;
std::string fin, fout, *key_table;
std::cout<<"是否自定义关键字:(y/n)";
char flag;
std::cin>>flag;
if((flag^'y')==0)
std::cout<<"请输入关键字数量:";
std::cin>>key_len;
key_table = new std::string[key_len];
for(int i=1;i<=key_len;i++)
std::cout<<"请输入关键字"<<i<<":";
std::cin>>key_table[i-1];
else
key_len = 9;
key_table = new std::string[key_len] "main","if","else","for","while","do","int","read","write";
std::cout<<"请输入源文件地址:";
std::cin>>fin;
std::cout<<"请输入输出文件地址:";
std::cin>>fout;
Compiler *compiler = new Compiler(key_len,key_table);//制定编译的保留字表
(*compiler).begin_compiler(fin,fout);//编译文件
delete compiler;
delete[] key_table;
return 0;
以上是关于编译原理:词法分析器实现的主要内容,如果未能解决你的问题,请参考以下文章