编译原理课程设计(LR(0)分析表的构造)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
引言
《编译原理》是计算机专业的一门重要的专业课程,其中包含大量软件设计思想。
通过课程设计,实现一些重要的算法,或设计一个完整的编译程序模型,能够进一步加深理解和掌握所学知识,对提高自己的软件设计水平具有十分重要的意义。
语法分析是编译过程的第二阶段,是编译器前端的核心组成部分,在编译系统中起到了至关重要的作用。
自底向上的语法分析与自顶向下的语法分析相比,对将要分析的源程序有着更大的分析空间,从而受到了广泛的运用。
LR(0)分析是自底向上LR类语法分析的基础,自底向上语法分析方法是一种移进-规约过程,在当前分析的栈顶符号串形成句柄时就采取规约动作,因此最终目标是如何在分析过程中确定句柄。
LR分析法是给出一种能根据当前分析栈中的符号串和向右顺序查看k个符号串就可以唯一地确定分析器动作:是移进还是规约,采用哪条产生式。
LR(0)分析器是在分析过程中,不需要向后查看输入串符号,因此它对文法的限制较大。
对绝大多数高级语言语法分析器是不适用的,但是它是构造其他LR分析器的基础。
LR(0)最终存在的问题和需要解决的问题是在构造LR(0)分析表的时候,在LR(0)项目集规范族中,有移进项目和规约项目、规约项目和规约项目同时存在的现象,形成移进-规约冲突和规约-规约冲突,直接导致语法分析器无法在某一状态进行移进还是规约。
为了能够解决这一问题,我们需要再向后查看一个输入字符(也就是当前字符的FOLLOW集)以确定下一步操作是否能够进行。
我班选择的是老师给的LR(1)语法分析构造器的设计,即对任意给定的文法G构造LR(1)项目集规范族,其中要实现CLOSURE(I)、GO(I,X)、FIRST集合等。
在此基础上,构造了LR(1)分析表。
然后对输入的句子进行语法分析,给出接受或出错报告。
程序采用文件输入输出方式。
其中包括两个输入文件:文法grammar.txt,以及输入串input.txt;两个输出文件:项目集items.txt和文法的LR(1)分析表action_table.txt。
由于语法分析的结果只给出接受或错误报告,比较简单。
所以直接在屏幕上输出,也便于用户查看。
在具体编写程序过程中,对文法操作的各个功能模块独立成为一个子程序,而对具体输入串的分析则放在main()函数中进行。
各个变量及函数的意义和用法我将在叙述程序设计的总体方案中详细给出。
程序的总体算法思想来自《编译原理》课程。
具体实现由我独立完成。
程序用C/C++语言编写。
在Microsoft Visual C++ 2005环境下调试通过。
摘要
语法分析的主要任务是接收词法分析程序识别出来的单词符由某种号串,判断它们是否语言的文法产生,即判断被识别的符号串是否为某语法部分。
LR分析法是给出一种能根据当前分析栈中的符号串(通常以状态表示)和向右顺序查看输入串的K个(K≥0))符号就可唯一地确定分析器的动作是移进还是归约和用哪个产生式归约,因而也就能唯一地确定句柄,所以LR分析过程是一种规范归约过程。
经过分析,我们使用C作为前端开发工具,在分析语法成分时比较方便直观,更便于操作。
运行程序的同时不断修正改进程序,直至的到最优源程序。
关键字
语法分析文法LR(1)分析移进归约
Abstract
Grammatical analysis of the main tasks was to receive lexical analysis procedure to identify the words from a website, string, and judge whether they have a grammar of the language, that is, judging by the series of symbols to identify whether a grammar part.The LR analytic method is gives one kind to be able to act according to current analyzes in stack's string (usually by condition expression) and examined in turn toward right the input string K (K≥0)) the mark may determine only which production pattern selling and buying of real esgate within the same family analyzer's movement is moves to or the selling and buying of real esgate within the same family and uses .Therefore can also determine the handle only, therefore the LR parsing process is one kind of standard selling and buying of real esgate within the same family process. After analysis, we use VC + + as a front-end development tool for the analysis of syntax ingredients more convenient visual, more easy to operate. Operational procedures at the same time constantly improving procedures, until the source of optimal.
Key Words
Grammatical analysis grammar LR (1) Analysis
Moves Selling and buying of real esgate within the same family
课程设计任务书
1、本课题的目的及意义
课程设计实践对学生巩固所学基础专业课程知识、进行编译系统基本技能训练、培养实践动手能力,从而掌握编译系统的基本工作原理、基本方法和基本开发技术,最终达到具有一定的编译系统的实际开发能力有重要意义。
通过课程设计,主要达到以下目的:1.帮助学生深入理解编译原理的有关理论和巩固编译原理相关知识。
2. 巩固学生学习的编译原理、程序设计语言、数据结构等课程的基础知识,训练学生分析和解决编译系统的相关问题的能力,提高学生的综合素质。
3. 从软件工程的角度来看,《编译原理》课程设计是一个很好的实例,可以训练学生软件设计的能力以及编码调试能力。
2、本课题任务的主要内容
本课程设计主要内容包括以下几点:
1、根据选定的题目,查阅资料,熟悉相关理论、方法;
(1)掌握文献检索方法,以获得编译系统开发技术等相关资料;
(2)学习并熟练使用一种4GL开发平台(如VC++、Java、Dephi、PB、VB等);
2、分析问题,确定系统逻辑结构;
3、确定系统所需模块及模块结构,并用流程图描述各模块;
4、编码及调试程序;
5、撰写课程设计说明书。
3、提交的成果
1、一份符合课程设计说明书撰写规范的课程设计说明书。
2、一套系统原型。
目录
第1章概述 (6)
1.1 项目背景 (6)
1.2 编写目的 (7)
1.3 软件定义 (7)
1.4 开发环境 (7)
1.5 编译环境简介 (7)
第2章需求分析 (8)
2.1 问题陈述 (8)
2.2 需完成的功能 (8)
2.3 数据流图 (9)
2.4 数据字典 (10)
2.4.1 数据项 (10)
2.4.2数据结构 (11)
2.4.3数据流 (11)
2.4.4数据存储 (12)
2.4.5处理过程 (12)
2.5 E-R图 (14)
第3章逻辑设计 (15)
3.1 系统组织基本工作流程 (15)
3.2 系统设计框图 (16)
第4章总体设计 (17)
4.1 LR(1) 分析器工作流程图 (17)
4.2 流程简介 (17)
4.3 LR(1) 分析思想 (19)
4.4 各模块流程图 (20)
第5章详细设计 (22)
5.1正规式构造NFA (22)
5.2将NFA转化为DFA (24)
5.3把DFA最小化 (25)
第6章测试 (26)
小结 (28)
致谢 (29)
参考文献 (30)
第1章概述
1.1 项目背景
随着科学技术的不断提高,计算机科学日渐成熟,其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。
作为计算机应用的一部分,使用计算机对LR(1)文法判定与预测分析器的构造系统,具有比手工运算、构造所无法比拟的优点。
例如:检索迅速、查找方便准确性高等。
这些优点能够极大地提高判定LR(1)文法的效率,也是我们此次课程设计的目的。
因此,开发一套这样的LR(1)文法判定与预测分析器的构造软件成为很有必要的事情。
编译原理是大学计算机专业的必修课程。
而词法分析作为其中的一部分占据着比较重要的比重。
词法分析是编译的第一个阶段,它的主要任务是从左至右逐个字符地对源程序进行扫描,产生一个个单词序列,用以语法分析。
通过本次课程设计,学生对编译的理解就不只停留在书本的概念上,而是知道怎样把编译理论应用到实际的编译程序设计的实践中。
对我们今后的学习和就业都是至关重要的。
1.2 编写目的
课程设计实践对学生巩固所学基础专业课程知识、进行编译系统基本技能训练、培养实践动手能力,从而掌握编译系统的基本工作原理、基本方法和基本开发技术,最终达到具有一定的编译系统的实际开发能力有重要意义。
通过课程设计,主要达到以下目的:
1.帮助深入理解编译原理的有关理论和巩固编译原理相关知识。
2. 巩固学习的编译原理、程序设计语言、数据结构等课程的基础知识,训练分析和解决编译系统的相关问题的能力,提高我们的综合素质。
3. 从软件工程的角度来看,《编译原理》课程设计是一个很好的实例,可以训练我们软件设计的能力以及编码调试能力。
通过本次课程设计,明白了分析器的原理、构造方法及其实现。
基本掌握了递归这种有用的分析及实现方法,加深了对编译原理这门课程的理解。
通过本次课程设计我们还可以为以后的毕业设计做准备,熟悉了做毕业设计的格式、流程、方法。
学会了怎样
在图书馆查找相关的资料。
提高了我的自学能力和自制力,我想做课程设计不仅是要我们完成课业任务,更重要的是教会了我们学习方法,锻炼我们的意志,学会如何在独立的情况下更好的完成任务。
1.3 软件定义
LR分析法指从左至右扫描和自底向上的语法分析,且在分析的每一步,只须根据分析栈当前已移进和归约出的全部文法符号,并至多再向前看k个输入符号,能确定相对于某产生式左符号的句柄是否已在分析栈的顶部形式,从而就可以确定当前所应采用的分析动作(是移进还是按某一产生式进行归约)。
LR(0)分析不需要向前看输入符号就能判断。
1.4 开发环境
本系统使用TC开发。
适用内存不低于256M配备有Windows2000,Windows2003,WindowsXP系统的计算机
第2章需求分析
2.1 问题陈述
编译过程的核心部分是语法分析。
他的任务是在词法分析识别单词符号串的基础上,分析并判断程序的的语法结构是否符合语法规则。
语言的语法结构是用上下文无关文法描述的。
因此语法分析器的工作的本质上就是按文法的产生式,识别输入符号串是否为一个句子。
对于一个文法,当给你一串符号是,如何知道它是不是该文法的一个句子,这是这个课程设计所要解决的一个问题。
对输入的文法G,在程序终实现CLOSURE(1),GO(I,X),FRIST等的构造,并利用这些功能函数构造出LR(1)项目集族。
并且输出结果。
在此基础上构造G的LR(1)分析表,并对输入的句子进行语法分析表,给出分析结果。
LR分析法是给出一种能根据当前分析栈的符号串和向右顺序查看输入串的K 个符号就可以唯一地确定分析器的动作是移进还是归约和用哪个产生式归约,因而也就能唯一地确定句柄。
LR分析法的归约过程是规范推到的逆过程,所以LR分析过程是一种规范归约过程。
2.2 需完成的功能
从键盘输入一个文法(要求是上下文无关文法),保存到一个外部文件(或数据库)中。
判断是否是LR(1)文法。
从键盘接受一个符号串(源程序)或从一个文本文件中接受符号串(源程序),对其进行语法分析,并将分析过程信息和结果(语法树)保存到一个外部文件(或数据库)中。
具体的说就是,本课程设计所做的工作是建立一个针对LR(1)文法的编译器,本课程设计将定义好的文法书写的文件或从键盘接受的符号串作为输入,其中包括语法及语义动作。
然后根据给定的文法和LR分析表,构造LR分析器,并输出LR工作过程。
根据LR分析器分析过程算法,通过action()和goto()两个函数即可实现算法的功能。
本系统的主要功能包括以下几个部分:
★系统登录
★导入文法模块
★计算可归前缀
★项目规范族和文法判定
◆后继项目求解
◆后继状态生成
◆LR(0)的判定
★若无错误则构造LR(0)分析表
◆生成action表
◆生成goto表
★求follow集
★SLR文法判定
★计算出LR(1)项目规范族
◆生成后跟符运算
◆Closure(J)的运算
◆传递后跟符运算
★生成DFA
★构造LR(1)分析表
★设计分析算法
★由分析算法判断输入符号串是否为该文法的句型
★生成语法树
★退出
2.3数据流图
顶层图:
扫描项目集:
构造分析表:
填写ACTION表和GOTO表:
2.4 数据字典
2.4.1 数据项
数据项名:终结符
别名:VT
数据类型:CHAR
长度:40
取值范围:T001---T040
数据项名:非终结符
别名:VN
数据类型:CHAR
长度:30
取值范围:T001---T030
数据项名:文法产生式序号
别名:Mi
数据类型:INT
长度:80
取值范围:M001---M080
数据项名:项目产生式序号
别名:Ij
数据类型:INT
长度:200
取值范围:I001---I200
2.4.2数据结构
数据结构名:文法产生式
说明:用来生成项目集
组成:{产生式序号,左部,右部}
数据结构名:项目产生式
说明:用来产生移进或归约动作
组成:{项目产生式序号,左部,右部,.位置}
数据结构名:文法
说明:用来提供文法的信息
组成:{终结符,非终结符,开始符,{产生式序号,左部,右部}}
2.4.3数据流
数据流名:移进信息
数据流来源:扫描项目集产生式;
数据流去向:构造分析表;
数据结构:{项目产生式序号,左部,右部,位置}
数据流名:归约信息
数据流来源:扫描项目集产生式;
数据流去向:构造分析表;
数据结构:{项目产生式序号,左部,右部,.位置}
数据流名:终结符和非终结符
数据流来源:文法
数据流去向:判断
数据流名:核心项目集
数据流来源:产生项目集
数据流去向:项目集规范族表
数据结构:{项目产生式序号,左部,右部,.位置}
数据流名; rj
数据流来源:填写ACTION表
数据流去向:分析表
数据流名;Si
数据流来源:填写ACTION表
数据流去向:分析表
数据流名:产生式序号
数据流来源:文法
数据流去向:填写分析表
数据流名:项目产生式序号
数据流来源:查找移进的下一状态
数据流去向:填写分析表
2.4.4数据存储
数据存储名:项目集规范族表
输入的数据流:核心项目集
输出的数据流:移进的下一状态序号
组成:{项目产生式序号,左部,右部,.位置}
数据存储名:分析表
输入的数据流:rj ,Si,i
数据结构:{终结符,非终结符,项目产生式序号,rj ,Si,i}
2.4.5处理过程
处理过程名:生成项目集
输入:文法产生式;
输出:项目产生式序号,核心项目集
处理:该处理过程主要是用来生成项目集规范族表,以及将文法产生式转化成项目产生式;
处理过程名:判断动作
输入:项目产生式
输出:移进信息,归约信息
处理:该处理过程主要用来判断当前项目产生式的下个动作是移进还是归约处理过程名:查找移进的下一状态
输入:移进信息,项目集
输出:项目产生式序号i
处理:该处理过程用来查找移进的下个产生式的序号
处理过程名:填写分析表
输入:项目产生式序号i,文法产生式序号j;
处理:最终生成分析表
处理过程名:判断
输入:项目产生式序号i,终结符集和非终结集
输出:终结符,非终结符
处理:判断移进项目是终结符还是非终结符
2.5E-R图
文法的E-R图:
项目产生式的E-R图:
第3章逻辑设计3.1系统组织基本工作流程(以总体逻辑结构图表达)
3.2 系统设计框图
第4章总体设计
4.1 LR(1) 分析器工作流程图
图4.1 LR(1)分析器工作流程图
4.2 流程简介
所谓LR(1)分析法,就是指如果一个文法的LR(1)分析表中不含多重入口时,(即任何一个LR(1)项目集中无移近—规约冲突或规约—规约冲突),则该文法为LR(1)文法。
实现LR(1)分析的程序又称为LR(1)分析程序或LR(1)分析器。
如果一个文法能满足以下特性:无二义性,无左递归,无有害产生式,无多余产生式,无ε—产生式,那么就可以构造LR(1)分析表。
当文法满足条件后,先构造出LR(0)项目规范族,然后构造LR(0)分析表,当此分析表中含有移近—规约冲突或规约—规约冲突时,便计算FIRST和FOLLOW集合,构造SLR(1)分析表,如果此分析表中还出现移近—规约冲突或规约—规约冲突时,则运用closure算法,构造LR(1)项目规范族,最后构造LR(1)分析表,利用分析表,构造LR(1)分析器模拟构造器。
LR(1)的语法分析程序包含了四个部分,总控程序,LR(1)分析表,先进后出的状态栈,先进先出的扫描队列。
本程序也是采用了同样的方法进行语法分析,该程序是采用了C++语言来编写,其逻辑结构图如下:
图4.2 各模块调用关系图
对一个文法构造了它的LR(1)分析表后就可以在LR分析器的总控程序(驱动程序)控制下对输入串进行分析,即根据输入串的当前符号和分析栈的栈顶状态查找LR(1)分析表应采取的动作,对状态栈进行相应的操作即移进、归约、接受或报错。
具体说明如下:
1) 若ACTION[S,a]= S
,a为终结符,j移入状态栈。
j
,a为终结符或#号,则用第j个产生式归约,并将两个栈的
2) 若ACTION[S,a]= r
j
指针减去k,其中k为第j个产生式右部的符号串长度,这时当前面临符号为第j个产生式左部的非终结符。
3) 若ACTION[S,a]=acc,a应为'#'号,则为接受,表示分析成功。
4) 若GOTO[S,A]=j,A为非终结符,表明前一动作是用关于A的产生式归约的,当前面临非终结符A应移入符号栈,j移入状态栈。
对于终结符的GOTO[S,a]已和ACTION[S,a]重合。
5) 若ACTION[S,a]=空白,则转向出错处理。
4.3 LR(1) 分析思想
LR(1)分析的基本思想:LR(1)方法按每个具体的句型设置展望信息。
例:如果存在如下的一些句型…αAa…,…βAb…,…γAc…,则FOLLOW(A)={a,b,c}
处理到句型…αA,只当输入符号为a时归约;
处理到句型…βA,只当输入符号为b时归约;
处理到句型…γA,只当输入符号为c时归约
LR(1)分析
若[A→a•Bb]属于项目集I时,则[B→•g]也属于I,把FIRST(b)作为用产生式B→g归约的搜索符(用以代替SLR(1)分析中的FOLLOW(B)),并把此搜索符号的集合也放在相应项目的后面,这种处理方法即为LR(1)方法
(1) I的任何项目属closure(I);
(2)若[A→β1.Bβ2,a]∈closure(I),B→δ是一产生式,那么对于FIRST(β2a)中的每个终结符b,如果[B→.δ,b]不在closure(I)中,则把它加进去;
(3)重复(1)(2),直至closure(I)不再增大。
GO函数
若I是一个项目集,X是一个文法符号
GO(I, X)= closure(J)
其中J={ 任何形如[A→αX.β,a]的项目∣[A→α.Xβ,a]∈I}
LR(I)项目规范族C的构造算法类同LR(0)的,只是
初始时:C={ closure({[S’→.S,#]})};
LR(1)的优缺点:
优点:LR(1)分析对搜索符的计算方法比较确切,没有无效归约,适应的文法更广
缺点:LR(1)分析表的状态数目庞大
4.4 各模块流程图
LR(1)分析器构造及输入串分析流程:
求项目集规范族:
分析表构造流程
总控程序流程
第5章详细设计
负责模块:DFA生成算法
其中包括三个步骤:
(1)由正规式构造NFA,
(2)把NFA转化为与其等价的DFA,
(3)把DFA最小化。
5.1 正规式构造NFA
Input : 一个字母表(Σ)上的Regular Experssion r
Output : 一个接受L(r) 的NFA N
Method : 把r 解析成为子表达式(subexpressions),然后使用下面的1),2)规则,为r 中的基本符号(basic symbols,基本符号就是ε和Σ中的字符)构建NFA,基本符号符合1),2)关于正规式的定义,注意,假如symbol a 出现多次,那么它每次出现都要构建一个NFA。
之后,我们需要通过r 的语法结构,通过规则3)组合前面构建的NFA,直到得到整个NFA为止。
对于中间产生的NFA,它只有一个终态,没有进入开始装状态的边,也没有离开接受状态的边。
规则1对于空记号ε,生成下面的NFA。
每次构建时,i,f的值都不一样,因此可见构造一个识别ε 的NFA,会产生2个新的状态
规则2对于Σ的字母表中的元素a,生成下面的NFA。
同样,对于aaa,第一个a构造的NFA中的i,f不会和第2个a构造的i,f一样,因此可见构造一个识别Σ中的每个字符a 的NFA,会产生2个新的状态
规则3令正规表达式s和t的NFA分别为N(s)和N(t)。
a) 对于表达式s|t 构建NFA N(s|t)
b)对于表达式st ,构建N(st)
c) 对于正规式s*,构造N(s*)
d)对于(s),使用N(s)本身作为它的NFA,也就是不用构造新的NFA
5.2将NFA转化为DFA
Input : 一个NFA N
Output : 接受相同语言的DFA D
Method : 为D构架一个transition table(转换表) Dtran,每个DFA的状态是一个NFA的状态集合(这里一定要注意前面说过的1)2)两点)。
定义以下的操作:
ε-closure(s)从NFA的状态s出发,仅通过ε迁移能够到达的NFA的状态集合
ε-closure(T)从T中包含的某个NFA的状态s出发,仅通过ε迁移能够到达的NFA的状态集合
move(T, a)从T中包含的某个NFA的状态s出发,通过输入符号a迁移能够到达的NFA的状态集合
a.构造NFA N的状态K的子集算法:
令 Dstates 中仅包含ε-closure(s), 并设置状态为未标记;
while Dstates中包含未标记的状态T do
begin
标记T;
for 各输入记号a do
begin
U := ε-closure(move(T, a));
if U不在Dstates中 then
将 U 追加到 Dstates 中,设置状态为未标记;
Dtrans[T, a] := U;
end
end
b.ε-closure(T)的计算方法如下:
将T中的所有状态入栈;
设置ε-closure(T)的初始值为T;
while 栈非空 do
begin
从栈顶取出元素t;
for 从t出发以ε为边能够到达的各个状态u do
if u不在ε-closure(T)中 then
begin
将u追加到ε-closure(T)中; 将u入栈;
end
end
5.3把DFA最小化
通过NFA转化而成的DFA不一定是最简的,也就是说,有多余的状态可以被删除,对于每一个正规定义,我们一定可以得到一个唯一的最简的DFA
我们回顾一下Move函数,DFA的move函数:
move : (state, symbol) -> S
注意,这里(state, symbol)表示的是一个集合,这里规范的数学表达应该是:
move : { (state, symbol) | 所有属于DFA的state和symbol } -> S 或者
move : S ×Σ -> S
假如一个DFA的move函数不是全函数,那么必须引入死状态。
假如某个DFA的move 函数是全函数,那么每个状态在所有input symbol下都有出边,比如:
这个DFA每个状态都可以接受所有的input symbol,这里是a,b。
而下面的DFA:
先不要看红色部分,那么这个DFA的状态c,d,它们无法通过input symbol b 进入下一个状态,我们可以加上红色的部分,把这个move函数,转化成为一个全函数,并且,经过转化操作之后,新的DFA与原DFA等价。
这个红色部分标识的状态,被叫做死状态。
第6章测试
测试数据放在1.txt(任意)文本文件中,测试结果放在2.txt(任意)文本文件中。
测试数据:b(ab)*
运行界面如下:
测试的字符串:检验的匹配结果:
小结
编译原理是一门很重要的课程。
我们平常写小的C语言程序会感到困难,而编译原理则是关于编写编译器的技术,难度之大可想而知。
编译器的编写一直被认为是十分困难的事情,难怪第一Fortran的编译器据说花了18年的时间才完成。
当然编译原理和编译技术并不是相同的,编译原理更注重理论方面的知识,编译技术更注重实际编写编译器过程中用到的技术。
在编程序的过程中,有时会和一个小小的错误较上半天的劲,等到最后才发现只是由于语法用的不正确,算法是可行的。
这样在一个小小的语法错误上浪费许多时间是很不值得,所以在今后的语言学习中,我会重视语法的细节。
另外在程序设计上,以前自己倾向于直接写程序,很少使用流程图。
后来发现先设计出流程图,那么程序的结构就会清晰的多,编写的时候也会更节省时间。
我在编程过程中花的时间五天左右,因为自己只是编写和改动了部分代码,因为正规式转为NFA以及NFA的确定化和最小化,在书上和网上都有大量的资料可以让我们参考,不过我还是深入研究了程序代码及原理。
原理其实是最重要的,因为原理弄懂了,流程图出来后,代码的实现就简单多了。
然而在整个程序中,我认为其中逆波兰式的构造和自动机的构造都是比较难的,是通过对基础知识的详细深入回顾得出,特别是自动机的确定化过程烦锁又耗时,采用了邻接表进行存储。
上机的调试时间也不是很长,但程序的最大问题就是可读性不强,虽基本功能能达到理想的效果。
本人对此次课程设计最大的感受理论是实践的基础。
通过NFA的确定化程序的设计,我们很好的理解了NFA确定化过程的相关知识,很好的理解了子集法的演算过程。
其它方法在求ε闭包时,基本都是利用栈,用类似深度优先搜索的方法,一次求出一个状态的所有ε闭包,此程序是利用传递性,通过循环依次将一个状态的一个ε闭包加入集合。
致谢
首先,感谢我的父母,是他们心情培育,才让我有了读大学的机会,有了学习的机会。
其次我要感谢我系给我提供的这次课程设计的机会,使我得到了充分的锻炼。
还有我的指导老师周文老师,能在此次课程设计中给我这样一个锻炼的机会,论文的完成离不开周老师的悉心指导和关怀。
在本次课程设计中,我从周文老师身上学到了很多东西。
周文老师认真负责的工作态度,严谨的治学精神和深厚的理论水平都使我收益匪浅。
他无论在理论上还是在实践中,都给与我很大的帮助,使我得到不少的提高这对于我以后的工作和学习都有一种巨大的帮助。
最后,我要感谢在我设计过程中给我帮助的所有同学,是他们在我设计遇到困难的时候,伸出了援助之手,给我技术上的支持和精神上的鼓励,帮助我克服困难,完成了课程设计的任务。
同时也很感谢本组人员在彼此合作时所给我的帮助,因为现在回头想一想发现我已经学会了不少知识。
所以说知识就在于日常不断的积累。
作者:
年月日。