编译原理 词法分析实验/课程设计C++实现

简介: 词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务

@TOC

一、词法分析简介

词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务。

词法分析是编译程序的第一个阶段且是必要阶段;词法分析的核心任务是扫描、识别单词且对识别出的单词给出定性、定长的处理;实现词法分析程序的常用途径:自动生成,手工生成。

完成词法分析任务的程序称为词法分析程序或词法分析器或扫描器。

从左至右地对源程序进行扫描,按照语言的词法规则识别各类单词,并产生相应单词的属性字。

二、设计要求

创建一个词法分析程序,它支持对正规文法的分析。必须使用DFA(确定性有限自动机)或NFA(非确定性有限自动机)来实现这一项目。该程序的输入是一个文本文件,包括一组由该正规文法产生的产生式以及待识别源代码字符串。该程序的输出是一个符号表(二元式),它由5种类型符号:关键词,识别符,常量,界符和操作符。

三、开发环境

硬件环境:PC机 windows10 64 位

编程语言:C++

运行环境:codeblocks或vs

四、实现过程

用子集法将NFA转化为DFA。具体实现是:做一个NFA_set类型的栈,新状态不停的进栈,每次从堆栈中弹出一个,计算其转换的结果,是新状态就进栈,重复则丢弃,只记录好dfa的转换,直到栈空。最后成功构造出DFA。

对输入源程序的扫描过程很简单,一次读入一个字符,成串的送入匹配和DFA判断其合法性。给出输出结果。

五、分析过程框架图

在这里插入图片描述

六、运行结果

识别程序的一部分输出结果:

在这里插入图片描述

对应的用于语法分析的部分输入:

在这里插入图片描述

七、部分核心代码

void NFA_to_DFA()
{
    num_new_set=0;
    NFA_set work_set;
    NFA_set worked_set;
    work_set.set[work_set.len++]=start;
    worked_set.len=0;
    stack<NFA_set> s;
    get_closure(work_set);
    s.push(work_set);
    new_set[num_new_set++]=work_set;
    for(int i=0;i<150;++i)
    {
        for(int j=0;j<150;++j)
        {
            dfa[i][j]='-1';
        }
    }
    for(int i=0;i<150;++i)
        is_final[i]=false;
    if(Is_contained_Y(work_set))
        is_final[num_new_set-1]=true;
    while(!s.empty())
    {
        work_set=s.top();
        s.pop();
        for(int i=0;i<len_final;++i)
        {
            for(int j=0;j<work_set.len;++j)
            {
                for(int k=0;k<move[work_set.set[j]][final[i]].len;++k)
                {
                    if(move[work_set.set[j]][final[i]].set[k]!='#' && move[work_set.set[j]][final[i]].set[k]!='Y' && !Is_in_set(move[work_set.set[j]][final[i]].set[k],worked_set))
                    {
                        worked_set.set[worked_set.len++]=move[work_set.set[j]][final[i]].set[k];
                    }
                    if(move[work_set.set[j]][final[i]].set[k]=='Y' && !Is_in_set(move[work_set.set[j]][final[i]].set[k],worked_set))
                    {
                        worked_set.set[worked_set.len++]='Y';    //用Y表示终态
                    }
                }
            }
            get_closure(worked_set);
            if(worked_set.len>0 && Is_in(worked_set)==-1)
            {
                dfa[num_new_set-1][final[i]]=num_new_set;
                s.push(worked_set);
                new_set[num_new_set++]=worked_set;
                if(Is_contained_Y(worked_set))
                {
                    is_final[num_new_set-1]=true;
                }
            }
            if(worked_set.len>0 && Is_in(worked_set)>-1 && final[i]!='@')
            {
                dfa[Is_in(work_set)][final[i]]=Is_in(worked_set);
            }
            worked_set.len=0;
        }
    }
}


相关文章
|
6月前
|
算法 开发工具 计算机视觉
【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
94 1
|
6月前
|
存储 搜索推荐 C++
C++课程设计实验杭州电子科技大学ACM题目(中)
C++课程设计实验杭州电子科技大学ACM题目(中)
38 1
|
7月前
|
C++
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
|
6月前
|
存储 JavaScript 前端开发
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
|
6月前
|
存储 编译器 C++
详细解读C++编译原理
详细解读C++编译原理
42 0
|
6月前
|
存储 人工智能 测试技术
C++课程设计实验杭州电子科技大学ACM题目(下)
C++课程设计实验杭州电子科技大学ACM题目(下)
43 0
|
6月前
|
存储 C++
C++课程设计实验杭州电子科技大学ACM题目(上)
C++课程设计实验杭州电子科技大学ACM题目(上)
34 0
|
24天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
38 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
83 5
|
1月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
80 4