形式语言与编译七 词法分析

词法分析

3型文法与我们前面讲的正则表达式、自动机家族(DFA、NFA、e-NFA)都是等价的。是描述正则语言的不同角度

3型文法(正规文法)从格式上有其特点:

\(A->\alpha B\) 或者 \(A -> \alpha\) 其中\(\alpha\)终结符构成的字符串。

2型文法(上下文无关文法)也可以看出其特点:

\(A - > \beta\) 其中\(\beta\)终结符或者非终结符构成的字符串

3型文法的严格定义用上面的四元组表示,S是开始符号,P是产生式集合。

3型文法中的 左线性文法:

如上面所示,非终结符B在左边

​ 右线性文法:

​ 非终结符在右边(这个好,我们后面再说)

正规文法与有限状态自动机的等价性

正规文发与有限自动机定义的语言是一样的,功能也是一样的

正则表达式、正规文法、有限自动机这3个都是研究正规语言定义的工具

这道题比较典型的解释了,正规文法转自动机的过程

这里我们使用正规文法的四元式形式 转 有限自动机的五元组形式

有正规文法的产生式形式 可以得到正规文法的四元组形式;再把四元组形式转有限自动机的五元组形式,进而可以转换成状态转移图形式。

\(\{V_N,V_T,S_0,P\}\) \(S_0\)表示初始状态 P表示这些产生式集合

自动机的五元组形式:

\(\{Q,\Sigma,\delta,q_0,F\}\) \(q_0\)表示初始状态 F表示结束状态集合

\(Q=V_N,\Sigma=V_T,\delta—P,q_0=S_0,F\) 是接受状态

每一个右线性文法都有对应的有限自动机
自动机转右线性文法

正规文法等价于正则式等价于有限自动机

有些语言容易用正规文法、有些容易用正则式、还有些容易用有限自动机表示

推导过程就是文法生成语言的过程

正规式转正规文法

例题

正规文法转正规式

规则

例题:

注意最后一步的经验,这在好多地方都用得到


词法分析的目的:扫描源程序的字符串,识别每一个单词,并将其表示成内部表示形式,即Token流。

其实就是把输入的单个字符(注意输进去的时候是一个一个的字符,把这些字符组成单词,有意义的单词)

词法分析过程也有一个目的是发现 错误单词(比如18..23,val#ue),像这样的错误得能够识别出来

字符->单词->语法单位

词法分析的工具:文法、有限自动机、正则表达式

Token的表示:<种属,值> 其中值是可以省略的,也就是把2元,减少到1元<种属,_>

Linux/Unix 回车换行用一个ASCII表示

Win回车/换行 用2个ASCII表示

这也就是有些编程语言 平台不兼容的原因

写出上面的字符流 Token流

注意由于实际的ASCII码文件最后有一个EOF,所以也要加上EOF。我们词法分析类似于干上面这件事。。

语法分析概要

语法分析就是把词法分析确定出来的Token流,依照上下文无关文法确定的语法规则,转化为语法单位。说白了,就是看Token之间都有哪些关系

语法分析 可以把token流合并,一直尽量合并,看看最终合并不了的时候,得到的这个结构会不会是语法框架(比如,看看合并的for语句满不满足for语法框架)

从语法分析树到中间表示

优化

目标代码

进行编译原理上面这些过程要用到一些表,保留字表,常数表、符号表。

做好表我们可以进行了

表的用途主要两方面:填|查

编译一次程序通常得扫5遍:

第一遍:词法分析扫ASCII

第二遍:语法分析扫Token

第三遍:语义分析扫语法树

第四遍:代码优化扫中间表示

第五遍:目标代码扫优化后的中间表示

每遍扫描后的输出,可以有内部表示(内存中数据结构),也可以有外部表示(存文件中)

词法分析、语法分析、语义分析比较成熟,可以打包,叫做LLVM。我们拿着LLVM做代码优化、目标代码生成(GCC就是这样,LINUX下的)

词法分析过程

自动机识别字符例子:

手工构造DFA,这样确实可以识别出有可能的token字符

whitechar比较厉害 可以检查tab、回车、space.

注意:每一个结束状态意味着可以识别出一个token 比如输入x1=0,就会识别出x1

上图8状态就可以识别 数字

​ d状态识别 界符

​ f、i识别 注释

​ 3 状态识别 标识符 (至于保留字,可以把保留字先定义在表中,然后用标识符比较,相同就是保留字,不用就是标识符)

所以上图这样一个自动机就可以描述界符、关键字、标识符、常数、运算符 不得不感叹自动机的强大。仅仅这里的一个应用就把我看呆了!!!

然后拿着这个DFA写程序

词法分析器的自动产生

这个词法分析生成器 就是给出 正则表达式 通过词法分析生成器 来自动得到DFA。不是像上面那样自动生成。

其实这里用到了前面我们学到的一些算法:

正则式-> NFA->DFA->最小化DFA

LEX编译器: 拿着正规式输入 得到 词法分析程序

Lex源程序就是正则表达式 经过贝尔实验室生产的Lex编译器 得到词法分析源程序;词法分析源程序再由C编译器,得到可执行的目标代码(01指令);再把需要编译的源程序输入词法分析机器指令,就得到Token流。

Lex编译器功能就是把 正规式——>NFA ——>DFA——>最小化DFA。我们不用管

参看《Lex与YACC》

正规式描述的Lex源程序如何描述:

{;语句} 表示重复0-n多次 ;语句一 ;语句二

Lex怎样写??

Lex语法定义:

只需一个上面语法规范的正则表达式,就能得到词法分析源程序

posted @ 2020-06-22 16:09  _Sandman  阅读(443)  评论(0编辑  收藏  举报