Page 80 - 《软件学报》2021年第6期
P. 80
1654 Journal of Software 软件学报 Vol.32, No.6, June 2021
4 代码生成位置表的构造
在上一节中,我们已经对模型中所有的组件进行了分支标记,这些分支标记就是这些组件的控制流信息,有
了这些信息,最直接的生成代码的方法就是逐层逐组件地生成组件代码,如果组件受到分支影响,就在组件的执
行代码前加上条件约束.显然,这样做会生成大量的冗余的条件判断语句.为了尽可能地减少冗余的条件判断代
码,生成控制逻辑更加清晰的代码,我们构造一个代码生成位置表,通过向分支控制的语句块插入伪代码的方式
来确定完整的基于控制流的组件执行顺序.一个完整的代码生成位置表可能会包含以下几种元素,见表 1.
Table 1 Elements contained in the code generation location table
表 1 代码生成位置表中包含的元素
元素 参数 对应的代码 描述
ActorExe Actor,DataSrc Execution code of Actor 以 DataSrc 为参数,生成对应的 Actor 的执行代码
Branch BranchPaths If/Else if/Else/Switch 表示分支的开始,依据 BranchPaths 生成分支判断代码
Inserter BranchPaths Null 表示后续满足 BranchPaths 分支条件的组件的插入位置
代码生成位置表的构造方法见算法 3 所述.
算法 3. 代码生成位置表的构造算法.
输入:确定调度顺序的数据流模型 ModelLayers,模型中所有组件的分支标记 BranchInfos;
输出:代码生成位置表 CGLT(code generation location table).
1: CGLT=∅
2: CGLT.insertInserter(0,{{0}})
3: for each layer in ModelLayers
4: for each actor in layer
5: branchPathsWithDataSrc=BranchInfos[actor]
6: branchPaths=branchPathsWithDataSrc.values
7: if not isBranchPathsConflict(branchPaths) then
8: for each branchPath in branchPaths
9: subBranchPath=branchPath
10: while not CGLT.findInserter(subBranchPath) do
11: subBranchPath=subBranchPath[0:−1]
12: end while
13: CGLT.removeInserterContain(subBranchPath)
14: CGLT.insertGapBranchAndInserter(branchPath,subBranchPath)
15: CGLT.insertActorExe(branchPath,actor,branchPathsWithDataSrc[branchPaths])
16: end for
17: else
18: CGLT.removeInserterContain({0})
19: CGLT.insertCombinedBranchPathsAndInserter({0},branchPaths)
20: CGLT.insertActorExe(branchPath,actor,branchPathsWithDataSrc[branchPaths])
21: end if
22: end for
23: CGLT.update(⋅)
24: end for
25: CGLT.removeEmptyBranch(⋅)
26: CGLT.removeAllInSerter(⋅)