词法分析-----编译原理------c++

实验一. 词法分析
1. 实验目的
(1) 根据 PL/0 语言的文法规范,编写 PL/0 语言的词法分析程序;或者调研词法分析程序的自动生成工具 LEX 或 FLEX,设计并实现一个能够输出单词序列的词法分析器。
(2) 通过设计调试词法分析程序,实现从源程序中分出各种单词的方法; 加深对课堂教学的理解;提高词法分析方法的实践能力。
(3) 掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示 文件的法。
(4) 掌握词法分析的实现方法。
(5)上机调试编出的词法分析程序。
2. 实验准备
微机安装好 C 语言,或 C++,或 Visual C++,或自己需要用的语言.
3. 实验内容
已给 PL/0 语言文法,输出单词符号(关键字、专用符号以及其它标记)。

4. 实验要求
(1)把词法分析器设计成一个独立一遍的过程。
(2) 词法分析器的输出形式采用二元式序列,即:
(单词种类, 单词的值)

5. 设计思想
(1)正则式
标识符:(a|…|z|A|…|Z)( a|…|z|A|…|Z|0|…|9)*
常数:(1|…|9)(0|…|9)*
基本字:begin、call、const、do、end、if、odd、procedure、read、then、var、while、write
运算符:+、-、*、/、=、<>、<、<=、>、>=、:=
界符:(、)、,、;、.
(2)NFA
词法分析-----编译原理------c++_第1张图片
(3)DFA
词法分析-----编译原理------c++_第2张图片
(4)最小化DFA
词法分析-----编译原理------c++_第3张图片
(5)流程图
词法分析-----编译原理------c++_第4张图片
(6)输入输出源程序

#include
#include
#include
#include
#include
#include
#include
using namespace std;
map<string,string> Word;//使用map数据结构实现key-value对应
std::map<string,string>::iterator it;//用来遍历key-value对应关系的迭代器
void map_init(){//key-value(单词-编码)对应关系进行初始化
    Word["begin"]="beginsym";
    Word["call"]="callsym";
    Word["const"]="constsym";
    Word["do"]="dosym";
    Word["end"]="endsym";
    Word["if"]="ifsym";
    Word["odd"]="oddsym";
    Word["procedure"]="proceduresym";
    Word["read"]="readsym";
    Word["then"]="thensym";
    Word["var"]="varsym";
    Word["while"]="whilesym";
    Word["write"]="writesym";
    Word["+"]="plus";
    Word["-"]="minus";
    Word["*"]="times";
    Word["/"]="slash";
    Word["="]="eql";
    Word["<>"]="neq";
    Word["<"]="lss";
    Word["<="]="leq";
    Word[">"]="gtr";
    Word[">="]="geq";
    Word[":="]="becomes";
    Word["("]="lparen";
    Word[")"]="rparen";
    Word[","]="comma";
    Word[";"]="semicolon";
    Word["."]="period";
}
int main(){
    map_init();//key-value(单词-编码)对应关系进行初始化
    string word;//识别单词
    string str;//识别字符
    do{
    cin>>str;//输入字符串
    for(std::size_t i=0;i<str.size();i++){//对整个字符串进行遍历
        while(str[i]==' '||str[i]=='\n') i++;//若最开始为空格或换行符,则将指针的位置往后移
        if(isalpha(str[i])){//对标识符和基本字进行识别,调用库函数isalpha()
            word=str[i++];
            while(isalpha(str[i])||isdigit(str[i])){
                word+=str[i++];
            }
            it=Word.find(word);//返回word在Word中的迭代器
            if(it!=Word.end()){//判断是不是基本字,若为基本字则进行输出
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }
            else{//否则为标识符直接输出
                cout<<"(ident"<<","<<word<<")"<<endl;
            }
            i--;
        }
        else if(isdigit(str[i])){//判断是不是常数,调用库函数isdigit()
            word=str[i++];
            while(isdigit(str[i])){
                word+=str[i++];
            }
            if(isalpha(str[i])){
                cout<<"error!"<<endl;
                break;
            }
            else{
                cout<<"(number"<<","<<word<<")"<<endl;
            }
            i--;
        }else if(str[i]=='<'){//对<,<=,<>分别进行判断
            word=str[i++];
            if(str[i]=='>'){
                word+=str[i];
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }else if(str[i]=='='){
                word+=str[i];
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }else if(str[i]!=' '||!isdigit(str[i])||!isalpha(str[i])){
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }else{
                cout<<"error!"<<endl;
                break;
            }
            i--;
        }else if(str[i]=='>'){//对>,>=分别进行判断
            word=str[i++];
            if(str[i]=='='){
                word+=str[i];
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }else if(str[i]!=' '||!isdigit(str[i])||!isalpha(str[i])){
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }else{
                cout<<"error!"<<endl;
                break;
            }
            i--;
        }else if(str[i]==':'){//对:=进行判断
            word=str[i++];
            if(str[i]=='='){
                word+=str[i];
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }else{
                cout<<"error!"<<endl;
                break;
            }

        }else{//对其他的基本字依次进行判断
            word=str[i];
            it=Word.find(word);
            if(it!=Word.end()){
                cout<<"("<<Word[word]<<","<<word<<")"<<endl;
            }else{
                break;
            }
        }
    }}while(str!="end.");//判断输出条件当程序输出为"end."时结束
    return 0;
}

词法分析-----编译原理------c++_第5张图片

你可能感兴趣的:(编译原理,c++)