1、基于 python的简易编译器实现IRs Code GenerationScanner Parser记号列表 Semantic AnalysisCFG源码分析树CFG 定义输出TypeDefinition编译器架构Parser部分目录1.CFG2.LRItem3.LRItemSet4.Action & Goto5.Parser.parse()Action & Goto生成自动机、并生成 Action & Goto表LR(1)项目集自动机算法Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F
2、- .int_const, $/*/+/-START - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-E, F, int_const, (, T1. 获取所有出边Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F - .int_const, $/*/+/-START - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $E
3、, F, int_const, (, TE2. 遍历出边,计算新项目集核心Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F - .int_const, $/*/+/-START - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $E, F, int_const, (, TE3. 求当前项目集的闭包现在这个项目集的闭包和它的核心是一样的 所以没有变化It
4、em Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F - .int_const, $/*/+/-START - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $E, F, int_const, (, TE4. 将这个 ItemSet加入队列中Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F -
5、 .( E ), $/*/+/-F - .int_const, $/*/+/-START - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $Item Set 2T - F., $/*/+/-E, F, int_const, (, TEF重复上述过程Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F - .int_const, $/*/+/-START
6、- .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $Item Set 2T - F., $/*/+/-Item Set 3F - int_const., $/*/+/-E, F, int_const, (, TEF重复上述过程Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F - .int_const, $/*/+/-START - .E, $T - .
7、F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $Item Set 2T - F., $/*/+/-Item Set 3F - int_const., $/*/+/-Item Set 4F - (.E ), $/*/+/-E, F, int_const, (, TEF(重复上述过程Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F - .int_const, $/*/+/-S
8、TART - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $Item Set 2T - F., $/*/+/-Item Set 3F - int_const., $/*/+/-Item Set 4E - .E + T, )/+/-E - .E - T, )/+/-E - .T, )/+/-F - (.E ), $/*/+/-F - .( E ), )/*/+/-F - .int_const, )/*/+/-T - .F, )/*/+/-T - .T *
9、F, )/*/+/-E, F, int_const, (, TEF(这里这个项目的闭包就不一样了,扩大了很多重复上述过程Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F - .( E ), $/*/+/-F - .int_const, $/*/+/-START - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $Item Set 2T - F., $/*/+/-Item Set 3F -
10、int_const., $/*/+/-Item Set 4E - .E + T, )/+/-E - .E - T, )/+/-E - .T, )/+/-F - (.E ), $/*/+/-F - .( E ), )/*/+/-F - .int_const, )/*/+/-T - .F, )/*/+/-T - .T * F, )/*/+/-E, F, int_const, (, TItem Set 5E - T., $/+/-T - T.* F, $/*/+/-EF(T重复上述过程Item Set 0E - .E + T, $/+/-E - .E - T, $/+/-E - .T, $/+/-F
11、 - .( E ), $/*/+/-F - .int_const, $/*/+/-START - .E, $T - .F, $/*/+/-T - .T * F, $/*/+/-Item Set 1E - E.+ T, $/+/-E - E.- T, $/+/-START - E., $Item Set 2T - F., $/*/+/-Item Set 3F - int_const., $/*/+/-Item Set 4E - .E + T, )/+/-E - .E - T, )/+/-E - .T, )/+/-F - (.E ), $/*/+/-F - .( E ), )/*/+/-F - .
12、int_const, )/*/+/-T - .F, )/*/+/-T - .T * F, )/*/+/-E, F, int_const, (, TItem Set 5E - T., $/+/-T - T.* F, $/*/+/-EF(新生成的 ItemSet又会有新的出边,继续搜出新的项目集TBFS初始化BFS核心BFS核心获取出边BFS核心计算闭包很耗时,而哈希不怎么费时用字典存储 item核心到其闭包的映射,加速运算获取出边BFS核心计算闭包很耗时,而哈希不怎么费时用字典存储 item核心到其闭包的映射,加速运算用一个字典将已经计算过的项目集映射到编号顺便判断当前项目集是否已经存在获取出边
13、填 Action & Goto表Parser.parse()句法分析器核心根据 Action & Goto分析输入 token list并建树。句法分析器是用来干什么的 ?子树子树Reduce using grammer 2: E - (+, T, E)+ T EE移进时创建节点归约归约前创建 父节点 ,将 pop出来的节点作为 子节点移进时创建节点归约移进时创建节点归约归约前创建 父节点 ,将 pop出来的节点作为 子节点return ParseTree(nodeStack-1)把产生的分析树打印出来之后的样子Query_|_| | | | | |select Columns from Tables where Expr| | _|_Column TableName | | | | Expr and CondColumnName students | _|_| Cond | | |name _|_ Column CMP Constant| | | | | |Column CMP Constant ColumnName 18 age|agereturn ParseTree(nodeStack-1)把产生的分析树打印出来之后的样子(部分)感谢围观