词法分析器
在早期编译1.0时代,我们的目标是完成程序语言到机器语言的翻译,所以重点在编译器前端,于是我们花费大量时间研究词法分析、语法分析、语义分析等内容。如今的本科编译原理课程,基本上也就到这一层面吧。
在编译2.0时代,我们的目标变了,我们的重点在于生成高效的代码。于是,我们的重点在编译器中端和后端,我们研究循环优化,研究指令调度,研究目标平台优化等内容。如今的研究生高级编译原理教程,会涉及到这一层面。
但是,我们已经在编译3.0时代了,我们的目标是要跳出编译器这个领域,因为我们有太多太多的领域需要编译优化,如安全、数据库、深度学习等等领域,于是,我们需要有一个可以脱离编译器,却又能利用编译优化的东西,而目前最适合的就是LLVM,因为它的模块化设计、它的IR、它的License等等。
所以,要学好用好LLVM,首先需要有一个编译的整体观,我到底要用LLVM做什么?我是要去做C++前端吗?那我的重点是在C++语言,是在语义分析、是在LLVM IR代码生成。我是要去做一个后端优化吗?那我的重点是在LLVM后端,是在IR优化,是在后端代码生成,是在后端指令调度。我是要用LLVM在我的项目中来进行编译优化吗?那我的重点是在IR优化,是在结合我的业务写自定义的Pass优化。
1.手工构造
要实现一门语言,第一要务就是要能够处理文本文件,搞明白其中究竟写了些什么。
传统上,我们会先利用“词法分析器”(也称为“扫描器”)将输入切成“语元(token)”,然后再做处理。
词法分析器返回的每个语元都带有一个语元编号,此外可能还会附带一些元数据(比如某个数值)。
llvm 实现语法分析器和AST
2.自动构造
小作业参考 XLEX生成器:
XLEX生成器:
正则表达式–>NFA—>DFA–>DFA最小化–>词法分析程序
FLEX 代码参考
RE 正则表达式
正则表达式 “一行胜千言”
通用的字符串表达框架
是用来简洁表达一组字符串的表达式。
针对字符串表达“简洁”和“特征”思想的工具
判断某字符串的特征归属
正则表达式在文本处理中十分常用:
表达文本类型的特征(病毒、入侵等)
同时查找或替换一组字符串
匹配字符串的全部或部分
主要应用在字符串匹配中
正则表达式的使用:
编译:将符合正则表达式语法的字符串转换成正则表达式特征
我们可以说正则表达式是某一种语法格式,但是在程序中我们必须用字符串的形式来表达他,但是字符串就是字符串,他不是一组字符串,所以我们需要通过编译的形式,将一个字符串变成一个特征,而这个特征可以表达一组字符串,这就是编译的作用。我们也可以认为编译后的特征与一组字符串是对应的,而编译之前的正则表达式只是一个符合正则表达式语法的单一字符串,但他并不是真正意义上的正则表达式。
正则表达式语法由字符和操作符构成
正则表达式的常用操作符
操作符 说明 实例. 表示任何单个字符,它可以代表字符表上所有出现的一个字符 [ ] 字符集,对单个字符给出取值范围 [abc]表示a、b、c,[a-z]表示a到z单个字符[^ ] 非字符集,对单个字符给出排除范围 [^abc]表示非a或b或c的单个字符,(出现一个字符,但这个字符不是a,不是b,也不是c)* 前一个字符0次或无限次扩展 abc*表示ab、abc、abcc、abccc等+ 前一个字符1次或无限次扩展 abc+表示abc、abcc、abccc等? 前一个字符0次或1次扩展 abc?表示ab、abc| 左右表达式任意一个 abc|def表示abc、def{m} 扩展前一个字符m次 ab{2}c表示abbc注意,大括号只对大括号前的一个字符进行扩展 {m,n} 扩展前一个字符m至n次(含n) ab{1,2}c表示abc,abbc^ 匹配字符串开头 ^abc表示abc且在一个字符串的开头$ 匹配字符串结尾 abc$表示abc且在一个字符串的结尾() 分组标记,内部只能使用|操作符 (abc)表示abc,(abc|def)表示abc、def\d 数字,等价于[0-9]\w 单词字符,等价于[A-Za-z0-9_]
经典正则表达式实例:
^[A-Za-z]+$ 由26个字母组成的字符串^[A-Za-z0-9]+$ 由26个字母和数字组成的字符串^-?\d+$ 整数形式的字符串^[0-9]*[1-9][0-9]*$ 正整数形式的字符串[1-9]\d{5} 中国境内邮政编码,6位[\u4e00-\u9fa5] 匹配中文字符 采用utf-8编码来约定了中文字符的取值范围\d{3}-\d{8}|\d{4}-\d{7} 国内电话号码,010-68913536
FA有限自动机 不确定的有限自动机(NFA)
NFA是一个五元组,M=(S,Σ,move,s0,F):
1. S是有限个状态的集合
2. Σ是有限个输入字符(包括ε)的集合
3. move是一个状态转移函数,move(si,ch)=sj表示当前状态si下若遇到输入字符ch,则迁移到状态sj
4. s0是唯一的初态
5. F是终态集,它是S的子集,包含了所有的终态
确定的有限自动机(DFA)
DFA是NFA的一个特例:
没有状态具有ε状态转移,即状态转换图中没有标记ε的边
对每一个状态s和每一个字符a,最多有一个下一个状态
与NFA相比,DFA的特点就是它的确定性