编译器结构的知识补充
编译器包含三个部分,整体架构分为前端、中端和后端,之前的文章中已经说明了。前端Front End,主要负责将源代码翻译成IR(中间表示);中端的Optimizer主要负责代码优化,将前端翻译过来的IR代码优化得更高效;后端Back End则将优化后的IR编译成010101的机器码。
为了防止生态过于碎片化,安卓只为第三方开放了简单的编译代码优化模板,代码优化空间有限。
编译器经典结构
上面的图基本上不用我叙述了,大家都能看明白基本流程了,下面就重点要说一下编译器的前端部分。
编译器前端部分
前端包括词法分析器(Scanner)、词法解析器(Parser)、语义规则(Semantic Elaboration),其中程序代码是一串字符流的形式进入词法分析器的,拆分出来的有意义的单元进入词法解析器中,但词法解析器需要参照语义规则进行解析,解析出来的结果再传入到中端(IR)进行处理。
我简单画一下关系图。
词法分析
RE—regex,正则表达式,我用自己的话直接解释了,就是一种明确格式的字符,比如我规定了“yyyy-MM-dd”,这串日期的字符必须是严格按这个规范来的,符合这个标准的必须是“2019-12-18”。
词法分析中,先对符合正则表达的字符流进行处理,取出这类字符。
NFA&DFA&mDFA—非确定性&确定性的(最小)有限自动机,其实也很简单FA(有限自动机)就是一个识别器,可以识别正规的语言或正则表达规定的内容。
FA前面的限定词都是提高效率或者针对输入的字符内容不确定状态,所开发的相应能力的识别器。编译器的前端需要经历上述三类限定的自动识别这个过程。
整个词法分析器就是上述内容的循环实现。
之前有个同学在研究数据结构问题,其中数据对接就是重点是两个数据的RE部分,通过中间循环流程实现两个不同格式的数据对接。但中间限制还是比较多,如果这个数据完全无序无规则,需要自己探寻的话,我建议使用大数据深度学习方式来确定正则和自动识别器关键词选取,不过因为库会比较大,这样生成的数据对接模式只适合成为一款插件。
语法分析
词法分析器与语法分析是互相对应的,词法分析后将整段的文字分解成了一串一串的字符流,接下来语法分析器就开始工作了,利用识别算法将这些字符流整理形成一条主线,然后像英语的语法一样,主谓宾、定状补都是主线上的单元,于是就以语法结构为主干,以相应的数据元素为枝叶,形成了语法结构树。
语法树的鲜明特点就是它的各个元素都是已经按规则划分到相关的枝干位置上,中间层IR是以这种语法结构树的框架进行解析和优化的,所以词法分析器的输出对于中间层是可以被识别和继续优化的。
对于词法分析器,将输入的字符流进行解析,拆分和转换,最终形成语法结构树的过程,需要靠一种算法,而这种识别算法就是词法分析器的核心所在。识别算法可以自己设计调试,也可以直接采用现有的经典算法,比如多文法识别、二义性分析等。