C语⾔编译器之词法分析(包含源码)
编译器之词法分析
基本概念
理论知识
1. 编译器会将我们输⼊的代码看作是字符串序列,所以,词法分析器的主要⼯作就是从字符串中识别出正确的单词进⾏区分,⽐如,我
们输⼊的 “int a”,编译器应该做到识别出int 和a,并且能够在后续的处理中,清楚的知道a是⼀个变量名,不是函数名,并且后续可以进⾏赋值等操作。
2. 虽然很多单词可以通过空格区分开,但是在写代码的时候,我们通常是不会主动的打空格的,⼤多数都是编译器主动为我们添加上空
格,或者是编译器不进⾏任何处理,所以,词法分析器的主要⽬的即使将字符串中的单词出来。
3. 所以,词法分析器的主要难点就在于怎么识别出单词,要知道,代码中的单词是⽆穷⽆尽的,所以,我们要设计⼀些规则来告诉编译
器什么样的是单词,并且,我们要清楚,编译器在拿到这些规则之后怎么正确的识别单词。
单词&模式&词素
1. 单词:字符串集合,每个字符串的类别,⽐如,标识符(变量)、数字、关键字,这些都是单词,他们都是⼀个类别,int a中的a就是
⼀个变量,它属于的类别就是标识符
2. 模式:模式就是这个类别所有单词的共同属性
3. 词素:就是单词中确切的符号串,单词是符号串集合,词素就是集合中具体的符号串,模式,就是这个集合的特点
正则表达式
定义
1. 我们前⾯提到了单词和模式,所以,我们的主要⼯作就是定义单词的模式,这个定义⽅法就是正则
表达式
2. 正则表达式:
正则表达式运算
| :或(并)、连接、闭包,他们对应的都是字符串的运算,所以,知道了字符串的特性,运算的性质也很显然。
正则表达式⽆法描述的语⾔
NFA
状态转换图
正则表达式定义了单词的描述规则,那么在知道了单词的规则之后应该怎么识别单词?
我们知道输⼊的代码时字符串,所以,我们的第⼀想法就是根据定义从头到尾遍历,判断⽬前的字符符合哪个规则,⽽字符的长度在按照最长匹配的原则,⽐如,有⼀个识别的时aaa,另⼀个识别的是aaab,那么,如果输⼊的是aaaa就会将前三个aaa识别为单词⼀,如果输⼊的是aaab,就会将字符串识别为单词⼆,这种想法很简单。
他的更明显的展现形式就是NFA,不确定状态转换图。
注意状态6,他表⽰的是刚刚识别了>,并不表⽰对应的是>和≥
整个算法的流程就是从初态(0号状态)开始,如果下⼀个字符是>,就去⼀号状态,到达⼀号状态后,如果下⼀个字符是=,则到达7号状态,如果是其余字符,则进⼊8号状态,我们把7号状态叫做终态,终态对应的就是明确的单词,这⾥⾯就是≥,需要注意的是,终态对应的也是单词,就是符号串集
合,并不是字符串,⽐如识别标识符和终态就应该对应很多符号串
具体定义
DFA
定义
NFA和DFA的区别就是⼀个是确定的,⼀个是不确定的,确不确定就体现在状态转换图的边上,NFA的状态转换图多条边上可以写同样的字符,也就是意味着,接收下⼀个字符可以去多个状态,这就意味着如果某个状态突然⽆法识别了,就需要进⾏回溯,DFA就是确定的,明确每⼀条边上的字符否是不同的。
除此之外,很重要的就是,NFA的边上可以是空字符串,就代表两个状态时相同的,但是为什么会有空字符串后⾯就知道了,DFA的边上就不会是空字符串。
中断驱动⽅式
I/O控制器从CPU接受⼀个指令,然后从外围设备读,⼀旦数据读⼊到控制器的数据寄存器,便通过控制线给CPU发出中断信号,表⽰已经准备好
优点:CPU和I/O可并⾏,利⽤率提⾼
缺点:每个字都会触发⼀次中断
正则表达式→NFA
Thompson构造法
c语言如何去学
NFA→DFA 字集构造法
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论