编译原理论文

合集下载

83 编译原理之美

83 编译原理之美

83 编译原理之美
编译原理是计算机科学中非常重要的一个领域,它涉及到程序
设计语言、编译器、解释器等方面,是计算机科学中的基础学科之一。

编译原理的美可以从多个角度来解释。

首先,编译原理的美可以体现在其理论体系的严谨性和完备性上。

编译原理涉及到形式语言、自动机理论、语法分析、语义分析
等多个方面的理论知识,这些理论知识构成了编译原理的理论基础,而这些理论又能够很好地解释和描述现实世界中的程序设计语言和
编译器的工作原理,这种理论体系的完备性和严谨性本身就是一种美。

其次,编译原理的美还可以从实践的角度来看。

编译原理的研
究成果直接应用在编译器和解释器的设计与实现上,而编译器又是
现代软件开发中不可或缺的重要工具。

一款高效、优秀的编译器不
仅能够将高级语言翻译成机器语言,还能够进行各种优化以提高程
序的性能,这种实际应用中的美也是编译原理的重要体现。

此外,编译原理的美还可以从其对计算机科学发展的推动作用
上来看。

编译原理的研究推动了计算机科学的发展,使得程序设计
语言的设计变得更加灵活多样,程序的开发变得更加高效和便捷,这种推动作用也是编译原理美的一种体现。

总的来说,编译原理之美体现在其严谨完备的理论体系、实践应用中的高效优秀编译器以及对计算机科学发展的推动作用上。

这些方面共同构成了编译原理的美丽之处。

申优论文 北航本科编译原理大作业

申优论文 北航本科编译原理大作业

How to Design a C++ Object-orientedCompiler罗杨37230118 AbstractThis system is a C++ object-oriented compiler using a extended C0 grammar as the input language. It can generate the assembly code according to the Intel 386 instructions set. You can use the Masm32v10 software to assemble and link the source code to get your 32-bit applications.摘要本系统实现了一个以扩充C0文法为输入语言的采用C++及面向对象思想设计的编译器,可以生成符合386指令集规范的汇编代码,用Masm32v10汇编可生成32位应用程序。

本系统考虑到不同版本的Masm的功能和使用方法的差异,以及用户手工键入汇编,连接命令多有不便,本系统自带了汇编器Ml.exe和连接器link.exe。

正文由于是目标是Windows平台下32位应用程序,有些文法中的功能如输入和输出无法再像16位汇编时调用DOS中断解决,因此对于这些问题我使用Microsoft提供的类似高级语言的设计方法——调用DLL函数来解决。

其实32位汇编语言在函数调用方面已与高级语言相差无异,可以调用系统API,C RunTime甚至是用户DLL中的函数。

本系统是一遍扫描编译程序,采用面向对象的方法进行构建,各个主要部分均抽象成类。

主要的类有:分析器类Parser,符号表管理器类SymbolTableMgr,四元式管理器类QuadrupleMgr,代码生成器类CodeGenerator,错误处理器类ErrorHandler,全局数据流分析器类GDAOptimizer,全局寄存器分配器类GRDOptimizer,局部公共子表达式删除器类CSDOptimizer,以上属于具有明显功能划分和界限区别的―高级类‖,他们的对象在全局main函数中分别构造和删除;系统中还有其它一些既具有数据结构意义又具有功能操作的―中级类‖,它们一般是―高级类‖或―中级类‖的成员,如基本块集合管理器BBSetMgr,由全局数据流分析器类GDAOptimizer构建,并为其它多个优化器类共享;还有一些相对意义上的―低级类‖,它们具有复杂的数据结构,却几乎没有功能操作,通常由―中级类‖或―高级类‖得数组成员进行管理,如项类Item,四元式类Quadruple,其中项类Item代表符号表中的每一项,四元式类Quadruple顾名思义代表一个四元式,并且四元式的三个操作数是指向项Item的指针。

编译原理实验课程教学设计的改进论文

编译原理实验课程教学设计的改进论文

编译原理实验课程教学设计的改进论文编译原理实验课程教学设计的改进论文编译原理课程是计算机科学与技术专业的重要专业课之一,课程内容抽象,理论性较强,学生普遍反应难学难懂,为此设置一定课时的实验课,有助于帮助学生深入理解概念,提高学生的逻辑思维能力、实践动手能力,有助于切实有效地提高学生的专业素质。

目前编译原理课程的实验设计通常是要求学生实现一个比较完整的编译程序,或者将其拆分成词法分析实验、语法分析实验和语义分析实验等几个部分,实验内容具有一定的难度,让很多学生知难而退,难以达到预期的实验效果。

究其原因是在实验设计上与学生的实际情况之间出现了诸多偏差,需要对实验的设计和组织进行改进,以更好地提高编译原理实验课的教学效果。

1编译课程实验的问题1.1学生对课程实验定位存在认知误区在教学实践中发现很多学生对编译原理实验课程的认识上存在很多误区,这些认识误区如果不加以及时纠正,加上课程内容抽象、逻辑性强等特点,很容易加重学生的畏难情绪,产生一系列不利于课程学习的消极负面影响。

一种认识误区是简单地认为编译原理的学习目的就是设计和开发编译器,认为毕业后很少有从事编译器研发的机会,所以得出课程学了没用的错误结论。

实际上编译原理包括的形式语言、自动机理论等语言定义、翻译与实现的基础知识,可以让学生领悟到计算机理论的精髓,可以让学生从程序编译的角度重新审视软件的开发,有助于提高学生对软件设计开发的认识,对于今后从事应用软件、语言开发平台甚至系统软件的开发等都是非常有好处的。

另一种认识误区是将编译的实验混淆于普通的程序设计实验,将实验重点没有放在算法的设计、原理的理解上,而是迷失在具体代码实现的细节上。

编译原理课程是一个综合性的专业课,编译程序使用的一些数据结构和算法是“数据结构”、“离散数学”以及“算法设计与分析”等课程相关知识的典型应用,能够进一步加深了学生对相关课程知识的综合运用和专业素质的提升。

1.2实验内容设计缺少层次性通常的编译原理实验课的教学设计,是将学生已经学过的一种高级语言的词法和语法进行简化,作为实验的模型语言。

编译原理中语法分析探讨及其应用

编译原理中语法分析探讨及其应用

(一)语法分析概述语法分析是对高级语言的句子结构进行分析,在编译过程中处于核心地位,它的主要任务是在词法分析识别出正确单词符号串的基础上,根据语言定义的语法规则,从单词符号串中识别出各种语法成分,并进行语法检查和错误处理,生成相应的语法树。

生成语法树的方法有两种,一种是自上而下另一种是自下而上。

[1]自上而下的语法分析方法是对由单词种别构成的源程序,尝试用所有可能的途径,从语法树的根结点出发,从上至下为输入符号串建立一棵语法树。

也可以说成是为输入符号串构造一个最左推导。

整个分析过程就是一种试探的过程,通过不断使用不同产生式谋求匹配输入符号串的过程。

自上而下的语法分析方法分为确定的和不确定的两种。

只有LL(1)文法才能进行确定的自上而下语法分析,在这种分析方法中面临两个问题,回溯和死循环。

通过对文法的产生式进行改造来解决这两个问题,在回溯中改造的方法是提取公共左因子,比如:A→αβ1|αβ2,改造后为A→αA’,A’→β1|β2。

死循环的改造方法是消除左递归,比如:A→Aα|β改造后为A→βA’,A’→αA’|ε。

而不确定的有递归下降分析和预测分析,前者适合手工实现,后者适合自动生成。

递归下降分析是用子程序来实现的,为每个非终结符创造一个子程序,每个子程序里面都有一个函数体,这个函数体是根据非终结符的产生式而定义展开的,当分析过程中遇到终结符时就直接匹配,如果遇到非终结符就调用相应的非终结符对应的子程序。

预测分析方法需要借助一个状态栈和一个二维分析表来实现,两者必须联合控制才能更好的实现预测分析方法。

自下而上的语法分析方法和自上而下的语法分析方法是完全不同的两种方法,但是它们产生的结果是相同的,都是构造一棵语法树,只是构造的过程不同罢了。

语法树创建的过程是把分析符号串的各个符号作为叶子结点,按照文法定义的规则,把产生式左部的非终结符作为父结点,自下而上构造此树的过程。

它的基本思想是“移进—归约”。

编译原理结课论文

编译原理结课论文

目录1. 绪论 (2)1.1概述 (2)1.2设计目的 (2)1.3设计题目及要求 (2)2.背景知识 (3)2.1语法制导翻译方法 (3)2.2属性文法 (3)2.3几种常见的中间语言 (4)2.4四元式的简介 (4)3.设计过程 (5)3.1设计思路 (5)3.2实现 (6)4.上机调试运行 (6)4.1代码调试界面及结果 (7)4.2执行及结果 (7)5.注意事项 (8)6.总结 (9)参考文献 (10)附录 (11)1.绪论1.1概述“编译原理”是一门研究设计和构造编译程序原理课程,是计算机各专业的一门重要的专业课。

编译原理这门课程蕴含着计算机学科中解决问题的思路和解决问题的方法,对应用软件和系统软件的设计与开发有一定的启发和指导作用。

“编译原理”是一门实践性很强的课程,要掌握这门课程中的思想,就必须要把所学到的知识应用于实践当中。

而课程设计是将理论与实践相互联系的一种重要方式。

1.2设计目的课程设计是对学生的一种全面综合素质训练,是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。

通常,设计题中的问题比平时的练习题要复杂很多,但也更接近实际。

编译原理这门课程安排的课程设计的目的是旨在要求学生进一步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容,选择合适的数据逻辑结构解决问题,然后编制算法和程序完成设计要求,从而进一步培养学生独立思考问题、分析问题、解决实际问题的能力。

1.3设计题目及要求基于这个学期所学习的内容以及自己所掌握到的知识,本次我所要设计的题目是赋值语句的四元式生成。

要求:(1)设计语法制导生成赋值语句的四元式的算法;(2)编写代码并上机调试运行通过;(3)输入一赋值语句;(4)输出相应的表达式的四元式;2.背景知识2.1语法制导翻译方法语法制导翻译的方法就是为每个产生式配上一个翻译子程序(称语义动作或语义子程序),并在语法分析的同时执行这些子程序。

语义动作是为产生式赋予具体意义的手段,它一方面指出了一个产生式所产生的符号串的意义,另一方面又按照这种意义规定了生成某种中间代码应做哪些基本动作。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的编译原理是计算机科学中的重要学科,它涉及到将高级编程语言转换为计算机能够理解和执行的机器语言。

本次实验的目的是通过实际操作和编程实践,深入理解编译原理中的词法分析、语法分析、语义分析以及中间代码生成等关键环节,提高我们对编译过程的认识和编程能力。

二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。

此外,还使用了一些相关的编译工具和调试工具,如 GDB 等。

三、实验内容(一)词法分析器的实现词法分析是编译过程的第一步,其任务是将输入的源程序分解为一个个单词符号。

在本次实验中,我们使用有限自动机的理论来设计和实现词法分析器。

首先,定义了各种单词符号的类别,如标识符、关键字、常量、运算符等。

然后,根据这些类别设计了相应的状态转换图,并将其转换为代码实现。

在实现过程中,使用了正则表达式来匹配输入字符串中的单词符号。

对于标识符和常量等需要进一步处理的单词符号,使用了相应的规则进行解析和转换。

(二)语法分析器的实现语法分析是编译过程的核心环节之一,其任务是根据给定的语法规则,分析输入的单词符号序列是否符合语法结构。

在本次实验中,我们使用了递归下降的语法分析方法。

首先,根据实验要求定义了语法规则,并将其转换为相应的递归函数。

在递归函数中,通过对输入单词符号的判断和处理,逐步分析语法结构。

为了处理语法错误,在分析过程中添加了错误检测和处理机制。

当遇到不符合语法规则的输入时,能够输出相应的错误信息,并尝试进行恢复。

(三)语义分析及中间代码生成语义分析的目的是对语法分析得到的语法树进行语义检查和语义处理,生成中间代码。

在本次实验中,我们使用了三地址码作为中间代码的表示形式。

在语义分析过程中,对变量的定义和使用、表达式的计算、控制流语句等进行了语义检查和处理。

对于符合语义规则的语法结构,生成相应的三地址码指令。

四、实验步骤(一)词法分析器的实现步骤1、定义单词符号的类别和对应的正则表达式。

编译原理的理解和应用

编译原理的理解和应用一、引言编译原理是计算机科学中的重要分支之一,其主要研究如何将高级语言代码翻译成计算机可执行的低级机器语言。

本文将分别从编译原理的定义、基本原理和应用等方面进行介绍和探讨。

二、编译原理的定义编译原理是一门研究如何将高级语言代码翻译成计算机可执行的低级机器语言的学科。

编译器是编译原理的主要应用工具,其主要作用是对程序进行语法分析、词法分析、语义分析和代码优化等处理,最终生成目标代码以供执行。

三、编译原理的基本原理1. 词法分析词法分析是编译器的第一步处理,其主要作用是将源代码转化为一系列的词法符号。

词法符号是语言的基本元素,包括标识符、字面值、运算符和分隔符等。

2. 语法分析语法分析是编译器的核心处理,其主要作用是将词法符号转化为语法树。

语法树是一种树形结构,用于表示程序的结构和执行顺序,其中每个节点代表一条语句或表达式。

3. 语义分析语义分析是编译器的重要处理之一,其主要作用是对程序进行语义检查和类型推导等处理。

语义分析对于生成高效和正确的代码至关重要,其中包括类型和作用域等检查。

4. 代码优化代码优化是编译器的最后一步处理,其主要作用是对程序进行优化,提高程序的执行效率。

代码优化有多种方式,包括常量折叠、寄存器分配和死代码消除等。

四、编译原理的应用编译原理在计算机科学和工程中具有广泛的应用,包括编译器设计、解释器设计和语言翻译等。

编译器是编译原理的主要应用工具之一,其广泛应用于软件开发、数字信号处理和嵌入式系统等领域。

同时,编译原理也是计算机科学和工程中的核心课程之一,其对于学生的编程和计算机基础能力的提升具有重要作用。

深入理解编译原理的基本原理和应用,将有助于学生更好地掌握计算机科学和工程的核心知识,提高其计算机科学和工程的能力。

五、结论编译原理是计算机科学和工程中的重要分支之一,其主要研究如何将高级语言代码翻译成计算机可执行的低级机器语言。

编译原理的基本原理包括词法分析、语法分析、语义分析和代码优化等。

编译原理课程教学论文

编译原理课程教学研究【摘要】目前的编译原理课程的教学中存在以下问题:1、教学内容偏重于原理;2、实验内容的语言不合理;3、实践环节太薄弱。

针对此做出了如下的改变:1、区分不同层次的学生合理组织教学;2、灵活应用多种教学方法;3、加强学生动手能力。

【关键词】编译原理改革教学方法动手能力组织教学一、引言编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法。

内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。

编译原理是计算机专业设置的一门重要的专业课程。

虽然只有少数人从事编译方面的工作,但是这门课在理论、技术、方法上都对学生提供了系统而有效的训练,有利于提高软件人员的素质和能力。

二、在教学过程中存在的问题在编译原理课程的教学实践中,我们发现需要解决下列问题:1. 教学内容比较偏重于原理。

编译原理中的核心理论是词法分析和语法分析这两部分,如果说不去做题的话是不可能学懂的。

那么按照这样的教学内容教课,就容易给学生造成误解,认为学编译原理关键就是会做题。

但是事实上是不对的,编译原理不同于一般我们所学的纯理论课,它的实践性也是很强的。

2. 实验内容所使用的语言不合理。

目前大多数教材中的实验内容使用pl/0语言的编译程序。

但是事实上因为pl/0语言是pascal的子集,而现在很多学生已经不再学习pascal语言了,所以大多数的程序是看不太明白的。

3. 实践环节太薄弱。

纵观整个编译原理的教学,事实上所偏重的都是理论教学,而真正的实践实在是少之又少,以致学生搞不太清楚研究编译原理到底有什么意义。

而且由于编译原理涉及的理论知识较多,形成了一种抽象层面上的数据变换,许多学生难以理解,曾一度被视为天书。

有些学生在专业课学习时还存在考研或实用的偏爱,投入到编译原理的学习时间相对来说就较少,给教学带来一定的影响。

三、对这些问题做出的一些改进方法针对以上的这些问题,我们有必要对编译原理这门课程做出一些改革。

毕业设计(论文)-基于LLVM的编译器的设计与实现

毕业设计(论文)-基于LLVM的编译器的设计与实现题目:基于LLVM的编译器的设计与实现设计人:指导教师:所属系部:计算机科学与技术学院专业班级:计算机082001班2012年 6月 4日太原科技大学毕业设计(论文)任务书学院: 计算机科学与技术学院学生姓名学号 200820010114 专业班级计算机082001 同组人无任务下发时间 2012年3月任务完成时间 2012年6月设计(论文)题目基于LLVM的编译器的设计与实现设计高质量应用软件的开发,需要高效的编程语言和编译器的支持。

目的为了加深学生对编程语言和编译器的理解,要求学生设计一个类似C要求的小源语言,然后利用LLVM实现该语言的编译器。

在深刻理解编译原理,掌握文法设计和编译器构造方法,并且熟悉LLVM的基础上,完成编程语言和编译器的设计。

主要内容包括: 设计 (1)设计源语言,要求包括变量声明,基本赋值语句,数组访问,主要条件分支语句,循环语句,函数定义,和函数调用等。

内容 (2)学习LLVM,完成词法分析,语法分析,和语法制导翻译(翻译成LLVM IR)工作,最后利用LLVM实现代码优化和代码生成功能。

设计毕业论文提交外文资料翻译资料编译器软件学生签名指导教师签名系主任签名主管院长签名太原科技大学学士学位论文中文摘要开发高性能的应用软件,除了一个良好的软件架构外,还需要高效的编程语言和高质量的编译器的支持。

现有语言的改动和新语言的创造,都会带来编译器的开发需求。

本文设计了一门新的编程语言leechee,定义了此种语言的文法结构、词法规则,并在linux环境下实现了leechee编程语言的编译器。

具体实现方式为首先利用Flex完成词法分析,而后使用Bison完成文法设计、语法分析和语法制导翻译,把源代码翻译成LLVM IR,最后利用LLVM实现代码优化和代码生成功能。

关键字:编程语言;编译器;语法制导翻译;LLVM IR;代码优化太原科技大学学士学位论文The Design and Implementation ofLLVM based CompilerAuthor: Liang Guanlin Tutor: Liu AiqinABSTRACTIn addition to a good software-architecture, the development of high-performance applications also needs the support of an efficient programming language and a high-quality compiler. Changes to existing languages and creation of new languages, will bring the developmentneeds of the compilers. This paper designs a new programming language leechee, defines its grammaticalstructures, lexical rules, and implements its compiler under Linux environment. The specific approach is, first, finishes the scanner with Flex, and then completes the grammar design, parser, syntax directed translation with Bison, implements the translation to LLVM IR, andfinally use the LLVM to do the code optimization and code generation.Keywords: programming language; compiler; syntax directed translation; LLVM IR; code optimizationI太原科技大学学士学位论文目录第一章绪论 ....................................................................0 1.1 什么是编译器 ........................................................... 0 1.2 总会有编译器的开发需求 . 01.3 为什么做这个项目 ....................................................... 1 第二章设计什么样的编译器和语言 (3)2.1 做一个什么样的编译器 (3)2.1.1 利用LLVM实现一门新语言 (3)2.1.2 利用flex和bison完成词法分析和语法分析 (4)2.2 设计一个什么样的语言 (5)2.2.1 计算机可以做什么 (5)2.2.2 本设计的语言——leechee ......................................... 6 第三章相关技术的介绍 .......................................................... 7 3.1Flex ...................................................................73.1.1 Flex输入文件的格式 .............................................. 7 3.2Bison ..................................................................83.2.1 Bison的语法文件 (8)3.2.2 文法规则的语法 (9)3.2.3 文法设计需要注意的问题 ......................................... 10 3.3LLVM ..................................................................113.3.1 LLVMIR (11)3.3.2 LLVM对三段式设计的实现 (12)3.3.3 利用LLVM完成代码优化 .......................................... 14 第四章语言和编译器的设计 ..................................................... 16 4.1 语言设计 .. (16)4.1.1 leechee的数据组成 (16)4.1.2 leechee的文法规则 (17)II太原科技大学学士学位论文4.1.3 leechee的词法规则 (24)4.1.4 leechee的输入输出 (26)4.2 抽象语法树 (27)4.2.1 抽象语法树的用处 (27)4.2.2 leechee语法树的设计 (28)4.3 语法制导翻译 (30)4.3.1 利用Bison实现语法制导翻译方案 (31)4.3.2 均分代码生成工作 ............................................... 31 第五章编译器的实现 .. (32)5.1 抽象语法树的实现 (32)5.1.1NodeAST (32)5.1.2 类型 (33)5.1.3 表达式 (35)5.1.4 语句 (41)5.1.5 声明 (45)5.2 符号表 (49)5.3 分析栈 (50)5.4 中间代码生成的上下文 (51)5.5 输入输出 (52)5.6 代码优化 .............................................................. 54 第六章用例说明 (55)6.1 用例程序 (55)6.2 使用步骤 .............................................................. 57 结束语 ..................................................................... ... 58 致谢 ..................................................................... ..... 59 参考文献 ......................................................................60 附录 ..................................................................... .. (61)附录? 英文资料翻译 (61)III太原科技大学学士学位论文附录? 程序代码 (73)IV太原科技大学学士学位论文第一章绪论1.1 什么是编译器编译器(compiler)也是一个计算机程序,它把用某种编程语言(源语言)编写的代码转变成另一种计算机语言(目标语言,通常是二进制形式的目标代码)。

词法分析—编译原理结课论文

编译原理结课论文题目:词法分析:Email:教师:递交日期:2013 年11 月28 日摘要词法分析作为编译的基础,其主要任务是对构成源程序的字符流进行扫描,然后根据构词规则识别单词符号,而这恰是源代码逆向分析过程中必不可少的一步。

随着软件逆向工程的不断发展,词法分析被广泛应用于源代码逆向分析。

本文就词法分析在源代码逆向分析过程中的应用进行探讨,尝试用简明易懂的方式去获得逆向分析后续工作所需的单词符号的各类信息。

关键词词法分析;逆向分析;源代码;单词符号前言编译原理是一个十分复杂的加工处理程序。

它将便于人们阅读但不能直接在计算机上执行的源程序翻译成语义上等价并且可在计算机上执行的目标程序。

为了处理各种使用于不同目的的源程序,一般将整个编译过程划分为五个处理阶段,分别是词法分析、语法分析、中间代码生成(语义分析)、代码优化和目标代码生成。

在编译程序结构中,词法分析程序通常作为子例程被语法分析调用,每一次调用返回一个单词。

一个源程序有许多单词组成,词法分析程序被调用较频繁,它的频率直接决定编译程序的效率。

词法分析对源程序进行自左至右的扫描,将它从外部形式(字符串)变换成便于后几个阶段处理的内部形式,即分解出一个个有独立语法意义的单元,称之为单词(又称符号或者特征),同时识别出与其相关的属性。

优化阶段对语义分析所产生的中间代码进行改造,以获得等价但更为高效(指时间和空间的节省)的中间代码。

目标代码生成阶段根据中间代码和表格信息,进行存储分配,选择代码,形成可在计算机上执行的目标程序。

如果目标代码生成阶段产生的代码为汇编语言程序,那么嗨应再经过汇编阶段才能产生机器代码程序。

基于上述,本文通过设计、编制、调试一个具体的词法分析程序,对词法分析器的具体实现。

正文1、词法分析词法分析程序又称扫描器,它是编译过程的第一个阶段。

其主要任务是从左到右依次描描字符串形式的源程序的各个字符,逐个识别出其中的单词,并将其转换成为内部编码形式的单词符号串输出,用于进行语法分析。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

正则表达式的剖析摘要随着互联网技术和计算机科学的蓬勃发展,传统的字符串精确匹配技术逐渐被正则表式匹配所代替。

正则表达式具有字符串所不具备的强大和灵活的表达能力,能够准确地表达出复杂的特征。

其正则表达式的原理大致基于以下三种:基于NFA的正则表达式匹配;基于DFA的正则表达式匹配;基于过滤方法的正则表达式匹配。

其中,基于过滤方法的正则表达式匹配方法目前使用的比较多,查询性能较高,但是现有的过滤方法只是针对某些结构的正则表达式效果较明显,正则表达式本身的结构非常复杂,如何选择一种更优的过滤方法来满足正则表达式的查询需求整体提高正则表达式的查询性能是一项很具挑战性的工作。

由于 DFA 与NFA 相比更适合在网络应用中使用,我们一般研究基于DFA 的正则表达式匹配。

虽然 DFA 具有先天的速度优势,但是匹配消耗空间过大和规则集规模较大时性能下降严重是它的两大缺点。

关键字:正则表达式;DFA;NFA;过滤方法;匹配;词法分析一、正则表达式的简介正则表达式(Regular Expression)概念最初是由美国科学家Stephen Kleene 于 1956 年提出来的,之后 Unix 的主要发明人Ken Thompson 将正则表达式这一成果应用于计算搜索算法的一些早期研究,将符号系统引入编辑器 QED,并最后引入进了人们所熟悉的 grep 工具,自此以后,正则表达式被广泛地应用到各种UNIX或类似于UNIX的工具中,如大家熟知的Perl。

Perl 的正则表达式源自于 Henry Spencer 编写的 regex,之后已演化成了 pcre(Perl兼容正则表达式 Perl Compatible Regular Expressions),pcre 是一个由 Philip Hazel 开发的、为很多现代工具所使用的库。

正则表达式的第一个实用应用程序即为Unix中的 qed 编辑器。

目前,正则表达式在各种计算机语言或各种应用领域得到了广大的应用和发展,在最近的六十年中,正则表达式逐渐从模糊而深奥的数学概念,发展成为在计算机各类工具和软件包应用中的主要功能。

不仅仅众多 UNIX 工具支持正则表达式,近二十年来,在 Windows 的阵营下,正则表达式的思想和应用在大部分Windows 开发者工具包中得到支持和嵌入应用。

正则表达式本身是一种功能强大、方便快捷、高效率的文本处理工具,赋予了使用者以强大的描述和分析文本的能力,利用正则表达式,我们可以方便的对文本数据进行相应的修改。

正则表达式的这些功能和其元字符(meta-character)和限定符是分不开的。

二、基于NFA的正则表达式的匹配NFA的构造方法主要有两种,Thompson构造法为每一个基本的正则表达式建立了一个自动机,然后利用epsilon变换将这些小自动机片段合并到一起,包括连接、重复和或操作,最后将各个NFA片段连接成完整的结果。

Thompson存在空转移,当不输入字符和输入空字符串的时候都会发生状态转移。

Gloshkov自动机的状态数是固定的,为m+1 (/?表示正则表达式中的字符数),没有空转移。

通过只对正则表达式五中字符计数,将每个字符在表达式中的位置标记出来,记为RE,,每个字符的位置表示经过该字符后到达的状态号,据此在上构造自动机,最后消除所有位置索引,抽取出Glushkov自动机。

正则表达式一般都会被解析成解析树的形式,然后将解析树转化为非确定性有限自动机(NFA),常用的构造NFA的方法有两种,一种是Thompson构造法,一种是Glushkov构造法,在转化为NFA后还可以进一步转化为确定性有限自动机(DFA),在文本中进行匹配。

NFA之所以被称为非确定性有限自动机,是因为在匹配过程中会激活多个状态,当已知一个状态和一个输入字符,它的转移状态不是唯一的,需要保存多个活动状态,并且每一步都需要更新活动状态列表,因此匹配速度比较慢,已渐渐失去了竞争力,但它需要的存储空间并不多,并且是许多后继工作的基础,许多有竞争力的算法都是在NFA的基础上提出来的。

对于使用NFA进行正则表达式的匹配。

我们假设已知正则表达式RE=ATC*(CT|TG),查看字符串:S=ATCCT是否与RE匹配。

下图显示了由RE转化为的GloshkovNFA以及使用该NFA进行搜索的过程,首先对RE建立NFA,初始状态是0,终止状态是4和6,下面的大圆表示每读入一个字符到达的一个状态,大圆里面左面的列表示当前的活动状态列表,右面的列表示下一步可能到达的活动状态列表。

初始活动状态只有0,依次读入文本中的字符,读入/1后活动状态变为1,读入r后活动状态变为2,下一步可接收的字符是C和T,可能到达的活动状态是3、4和6,以此类推,最后到达活动状态5、6,其中5为终止状态,搜索停止,字符串和正则表达式RE完全匹配。

三、基于DFA的正则表达式匹配对于上述的基于NFA的正则表达式的匹配而言,当使用NFA遍历文本时,会经过很多状态转移,因此在每一次读入字符时都会激活一个状态集合,大大降低了搜索的速度。

相反,DFA则不同,在每读入一个字符时都只会到达一个确定的活动状态,所以搜索速度比NFA要快很多,目前大多数正则表达式搜索算法也都是基于DFA的,本文所使用的查询算法也是在构建DFA的基础之上。

DFA的构造可以建立在NFA的状态集合上,因此可以先建立一个ThompsonNFA或GloshkovNFA,然后将其转化为DFA,DFA当前的唯一状态就是NFA的当前活动状态集合。

因为每输入一个字符则进行一次状态转移,所以DFA的搜索时间是线性的00),n为待查询文本T的长度。

下图显示的是将上述基于NFA的正则表达式的匹配中RE=ATC*(CT|TG)的NFA转化成的DFA。

其中,NFA中的状态3和状态4经合并形成一个新的状态3,NFA 中的状态5和状态6经合并形成一个新的状态5,现状态4是原来NFA中的状态6。

0仍然为初始状态,状态5和状态6由于包含原来NFA的终止状态而成为DFA的终止状态。

经过转变之后,保证了在每个状态下,给定一个字符,只会激活一个活动状态。

但是,为了能够在文本中搜索,需要在原有NFA的基础上进行改进,在NFA的初始状态上加入一个自环,使字符表中的任何一个字符都可以通过这个自循环。

以基于NFA的正则表达式匹配的这个NFA为例,就是在初始状态0处加入自环,即状态0分别经过丄C、G、r都可以回到状态0,改进后的NFA相当于正则表达式(A|C|G|T)*ATC*(CT|TG)。

将NFA改进后,再以此为基础建立DFA,如果原始的自动机DFA能够识别的语言为L(RE)改进后的DFA可以识别的语言为∑*L(RE)。

并展示了将加入初始自环的NFA转化为的DFA以及在此自动机上进行搜索的过程。

DFA下面表示的是用该自动机搜索时所经历的状态转移过程,Tpos表示当前处理到文本的哪个位置。

例如文本T=AGATCTG,依次读入文本中的字符,当读入A时,活动状态由0转移到1,读入G时活动状态再次回到0,依此类推,当读入文本r中的第4个字符r 时到达自动机的终止状态4,说明已找到一个匹配,将文本位置4返回,继续查找,读入第5个字符G,又到达了一个终止状态5,这时将5也作为一个结果返回,已到达文本末尾,搜索结束。

共找到两个匹配,结束位置分别是4和5。

四、基于过滤方法的正则表达式匹配在前面描述的两种正则表达式方法中,都需要对文本中的字符逐个检验,这样会大大影响到正则表达式的匹配速度。

在2.1节本文介绍了几种简单字符串的查找方法,在查找的过程中,通过滑动窗口的滑动,直接跳过不可能的区域,这样可以过滤掉很多文本中的位置。

在正则表达式匹配中,也需要使用一定的过滤手段来避免逐个的读入字符处理,先找到候选位置,再对其附近的区域进行验证。

在正则表达式中加入过滤策略后,会加快它的查找速度。

在这一小节中,本文详细阐述下现有的几种正则表达式过滤策略。

前缀过滤,又称MultiStringRE方法,是Bruce W. Watson于1996年提出来的一种算法。

首先计算出正则表达式RE的最短成功匹配长度Lmin,然后求出及五中所有长度为Lmin的前缀集合Pref(RE)。

例如正则表达式RE =ATC*(CT]TG),先建立一棵对应的解析树,使用递归方法来计算Lmin的值。

如果节点是连接操作符“.”,那么以这个节点为根的子树求得的Lmin等于下面两棵子树的Lmin之和,如果节点是重复操作符“*”,那么以这个节点为根的子树求得的Lmin等于0,如果节点是或操作符“1”,那么以这个节点为根的子树求得的Lmin等于下面两棵子树的Lmin的最小值。

对于该解析树,符号节点旁标注的数字代表以这个结点为根的子树Lmin的值,最终求得该正则表达式的Lmin值为4,对应的前缀集合为{ATCT,ATCC,ATTG }。

得到前缀集合后,使用类似于Cormnentz-Walter的多字符串匹配算法查找出前缀集合在文本中出现的位置。

因为正则表达式的每次成功匹配一定是从乃r/i?幻中的某一个字符串幵始的,每当发现一个前缀,就找到了一个候选位置,只要继续对后在文本中开始的位置开始验证即可。

所以利用一个长度为的窗口在文本r上滑动,查找到前缀后向后进行验证,验证的方法可以使用中提到的基于DFA的搜索方法,使用的DFA就可以,不需要在初始状态加入自环,直接向后验证即可。

然以前面兄RE =ATC*(CT]TG)这个正则表达式为例来说明使用前缀过滤的算法过程。

给定文本序列T= GATCCTGATCCCATATTG,使用多字符串匹配算法得到的前缀位置集合为{1,7, 14},使用图2.7中的DFA进行验证。

前缀集合可以用一个trie结构来表示,因为它容易生成,并且在搜索中也会用到。

首先对前缀集合中的各个字符串做预处理,求出每个字符串在自动机DFA上所能到达的状态号,标注在该前缀在trie上所对应的节点上。

这样在文本中查找到前缀以后,直接在DFA上接着这个前缀到达的状态继续验证即可,直到遇到一个终止状态,或者没有活动状态,或者到达文本的末尾。

经过计算,求得前缀WrCT对应的活动状态是5, JrCC对应的活动状态是3,ATTG对应的活动状态是6。

验证的过程如图2.10所示,最后位置集合{1,14}作为最终结果返回。

前缀过滤这种方法可以过滤掉很多文本中的位置,而减少了验证的次数。

但是,这种方法存在一定的问题,它的有效性主要依赖于两个值: Lmin和pref(RE)的大小。

Lmin越大,找到的前缀越长,过滤能力越强,搜索的速度越快。

pref(RE)前缀的数量越少,多字符串匹配中需要查询的字符串也就越少,所以过滤能力越强,搜索的速度就会变快。

相关文档
最新文档