Page 79 - 《软件学报》2021年第6期
P. 79
苏卓 等:基于分支标记的数据流模型的代码生成方法 1653
24: if len(branchPathsWithSameDataSrc)>1 then
25: if canBranchPathsMerge(branchPathsWithSameDataSrc) then
26: SimpleBranchPathsWithDataSrc.insert({subBranchPath,dataSrcs})
27: SimpleBranchPathsWithDataSrc.remove(branchPathsWithSameDataSrc)
28: curPos=curPos−len(branchPathsWithSameDataSrc)+1
29: continue
30: end if
31: end if
32: curPos=curPos−1
33: end while
34: return SimpleBranchPathsWithDataSrc
下面以图 2 中的模型为例,对整个分支标记算法进行讲解.首先对第 1 层进行标记,由于我们默认模型最开
始就处于一个单独的分支中,所以我们对 A 组件标记{{0}},其中,0 代表第 1 个分支,且不带有数据源.分支标记
逐层进行,接下来对第 2 层中的 B 组件进行标记.因为分支会对其后面所有组件有影响,所以分支标记要向后续
组件传递,所以 B 组件也要标记{{0}}.但此时 B 接收来自 A 的输出数据,所以记录在该分支下接受 A 的数据,记
为{{0}:A}.接下来标记第 3 层.由于 B 组件产生了两个分支,所以 C 组件要受到 B 组件第 1 个分支的影响,同时,C
组件也仍然在最开始的 A 组件所在的分支的控制之下,所以 C 组件要标记为{{0,0B}:B},表示其在最初的{0}分
支的控制下又在 B 的第 1 个分支控制下,并且接收来自 B 组件的数据.同理,D 和 E 组件标记为{{0,1B}:B}.第 4
层的 F 和 G 组件会继续嵌套分支,第 5 层的所有组件相比第 3 层组件的分支标记会多出来由 F 和 G 组件所带
来的分支,例如,H 组件的分支标记为{{0,0B,0F}:F},I 组件的分支标记为{{0,0B,1F}:F}.第 6 层的 M 组件的分支
标记和前面的组件有些不同,M 组件汇聚了来自 H 和 I 组件的两个分支,虽然他们的两个分支合并到了一起,但
是 M 组件仍要区分这两个分支,因为在这两个分支下,一个传递的是 H 组件的数据,另一个传递的是 I 组件的数
据.显然,M 组件的代码不能写在 F 分支代码的控制范围之外,要分别在 F 分支代码的两个控制区域中写入带有
不同数据源的 M 组件的代码.所以,M 组件的分支标记有两个分支路径和{0,1B,1G},而其中,{0,0B,0F}和{0,0B,
1F}这两个分支路径都带来的是 M 组件的输出数据,所以可以将 0F 和 1F 进行合并.最终,N 组件的分支标记为
{{0,0B}:M,{0,1B,0G}:J,{0,1B,1G}:K}.最后,O 组件汇聚所有分支,根据算法 2,{0,1B,0G}和{0,1B,1G}可以合并为
{0,1B},而{0,1B}和{0,0B}再次合并为{0},并且 O 组件只接收来自 N 组件的数据,所以 O 组件的分支标记为
{{0}:N}.针对图 2 中的分支标记结果,可直接如图 3 所示.
{0,0B,0F}:F {0,0B,0F}:H
{0,0B}:C H L
{0,0B,0F}:H
{0,0B}:B F {0,0B,1F}:F
{0,0B,1F}:I
{0} {0}:A C I M
{0,0B}:M
B
A {0,1B}:B {0,1B,0G}:G {0,1B,0G}:J {0}:N
{0,1B,1G}:K
D {0,1B}:D J N O
{0,1B}:B G {0,1B,1G}:G
E K
层1 层2 层3 层4 层5 层6 层7 层8
Fig.3 Result of the branch marking of the model in Fig.2
图 3 图 2 中模型的分支标记结果