编译原理:词法分析器实现

Posted 一只特立独行的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编译原理:词法分析器实现相关的知识,希望对你有一定的参考价值。

用C++定义了一个类,可以自定义保留字,通过调用类的方法来实现词法分析的功能,封装的还是挺高的。

前提假设

状态内容类别
1main、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;

以上是关于编译原理:词法分析器实现的主要内容,如果未能解决你的问题,请参考以下文章

编译原理实验 —— 词法分析器

编译原理--词法分析器(python语言实现)

编译原理词法分析 java简单实现

[编译原理]词法分析器的分析与实现

Java 实现《编译原理》简单词法分析功能

编译原理实验:实验一 简单词法分析程序设计(必修)(Python实现)