【编译原理】看书笔记
参考书籍:《编译系统透视_图解编译原理》
1. 词法分析
1.1 如何理解上下文无关法?
编译器用生成式来对代码进行词法和语法解析,只需要使用生成式约定的规则,就可以从一串文本中,确定一个符合语法的语句后,就可以明确这个语句的含义,不需要这条语句前面的内容(即上文),和下面的内容(即下文)来确定这条语句所表达的含义,也就是说语句所表达的含义不会有歧义。
这里容易误解的是,根据生成式解析代码的过程中,是需要查看一定的上下文的,因为我们需要根据已经解析的符号,加上后面出现的符号,来判断语句的类型和内容,这个过程本身就是一种上下文分析的过程,只不过这个上下文范围很小。一旦根据生成式解析出来一条语句,这条语句的含义就确定了,不存在歧义,这条语句的所有想表达的信息,都可以由自身表达出来,不依赖上下文去确定其含义,其含义也不会受到上下文内容的影响。关于这一点,大家要仔细揣摩,加深理解。
这样公式化的解析方式,实现起来很简单,有利于编译器的设计和实现。
1.2 词法分析
词法解析是编译的第一步,它的规则相对来说比较简单,它是语法解析的基础。语法解析在词法解析结果的基础上,又增加了很多灵活的语法规则。这种设计可以看做是对系统的分层设计。
词法分析分析出来的词,一般叫做 token。也就是说,词法分析,会把源码文本流,转为token流。
不管词法分析还是语法分析,都是根据生成式描述的规则去解析的。只要满足生成式的规则,就能100%确定一个token的类型和内容,不依赖于其他内容(上下文无关)。试想一下,如果依赖于其他内容,那我们是不是要把整个源码全部读取出来以后,才能确定其中某个部分的真实含义?如果这样设计编译器,编译器会非常复杂,而且设计出来的编程语言,需要根据语境去判断代码含义,很容易出现歧义,这是工程上我们不想看到的,我们需要稳定安全的机制,保证产品的稳定安全。
生成式在我们前面的文章中有讲解过。简单来说,一个token或一条语句的生成式就是:
语句 = 起始符 + 中间内容 + 结束符。
其中,中间内容又可以包含其他语句,形成嵌套结构。
根据以上思路去编写代码,只需要:
- 先根据起始符号,判断语句可能是哪种类型,这一步缩小了判断的范围,便于后续的解析;
- 再持续向下解析,进一步判断语句的类型以及获取语句的成分,内容;
- 最后判断解析结束符,明确语句的边界,完成语句解析。
有些教材大篇幅讲BNF,看得头疼。亲自写一写能更好地理解。
《编译系统透视_图解编译原理》书中的状态转移图相对于生成式更好理解,建议采用书中的状态转移图去画生成式。