算法重写修改转到语义语义、转到、重写、算法

2023-09-11 04:41:38 作者:空了一座城

我有一个大的一堆旧的code在一个旧的自我设想的脚本语言,我们编译/翻译成JavaScript。

I've got an large bunch of legacy code in an old self-conceived scripting language that we compile/translate into javascript.

这语言有一个条件跳转,跳转到一个标签。区别普通goto语句是,没有落后的跳跃是可能的。有没有嵌套的if语句,也没有循环使用该语言。

That language has a conditional jump, jumping to a label. Difference to common goto statement is, that no backward jumps are possible. There are no nested if statements nor loops in that language.

作为goto并不在JavaScript中存在的,我在寻找一种算法,变换转到mylabel mylabel:成语义等价的结构。

As goto does not exist in javascript, I'm looking for an algorithm that transforms goto mylabeland mylabel: into semantically equivalent structure.

我想用 IFS ,但发现由于GOTO标签任意嵌套它的不平凡。

I thought of using ifs but found it not trivial because of the arbitrary nesting of the goto labels.

例如:

if cond1 goto a
do something1
if cond2 goto b
do something2
a:
do something3
if cond3 goto c
do something4
c:
do something5
b:

可以被改写为:

Could be rewritten as:

lbl_b=false;
lbl_c=false;

lbl_a = cond1;
if (!cond1) {
  do something1;
  lbl_b = cond2;
  if (!lbl_b) {
    do something2;
  }
}
if (!lbl_b) {
  do something3;
  lbl_c = cond3;
  if (!lbl_c) {
    do something4;
  }
  do something5;
}

不过,我无法从中导出一个通用算法。

However, I was not able to derive a general algorithm from that.

推荐答案

这是通常称为的转到删除的,我们只有一次,学生工作,其中的任务是落实它C.一般你有循环工作(可悲的是,我们没有把这项工作网络)。但是当你有,你只能向前跳的限制是比较容易的:

This is usually called Goto Removal, we had just once a student work where the task was to implement it for C. In general you have to work with loops (sadly we did not put that work online). But as you have the restriction that you can only jump forward it is relatively easy:

解析一次,在所有线路,并收集所有的标签。创建每个标签标志skip_to_label。在初始化开始的所有标志为false。当您满足标签X中的条件跳转你现在prePEND每一行,直到标签符合如果不是skip_to_label,并设置标志设置为true。

Parse once over all lines and collect all labels. Create for every label a flag "skip_to_label". Initialize at beginning all flags to false. When you meet the conditional goto for label X you now prepend every single line , up to the label line with "if not skip_to_label" and set the flag to true.

这应该已经足够的工作,但当然不是很理想。

This should be already enough and work, but is of course not very optimal.

您可以如何优化它:相反$ P $的,如果ppanding,只是保持每行一组标志,而不是设置的东西假的,只是添加的行corrosponding标志的设置。

How you can optimize it: Instead of prepanding the if, just maintain a set of flags for every line, and instead of setting something to false, just add for the lines the corrosponding flag in the set.

现在可以使如果为一个组,它包含所有的行,其中该组不改变时,该条件是该组的布尔标志。

Now you can make the if for a group that contains all lines, where the set does not change, and the condition are the boolean flags of the set.

例如你给code:

set                    your code
empty                  if cond1 goto a 
skip_to_a,             do something1
skip_to_a,             if cond2 goto b
skip_to_a, skip_to_b   do something2
skip_to_a, skip_to_b   a:
skip_to_b              do something3
skip_to_b, skip_to_c   if cond3 goto c
skip_to_b, skip_to_c   do something4
skip_to_b, skip_to_c   c:
skip_to_b              do something5
skip_to_b              b:

现在你在每行前面写无论是如果(S),或者您从顶部开始,并作出是否块,只要设置保持不变。

Now you write in front of each line either the if(s) or you start at the top and make an if block as long as the set remains the same.

因此​​,当你开始你的第一次在空的,其条件GOTO所以不是你设置你的标志

So when you start you get your first at empty, its a conditional goto so instead you set your flag

if cond1 goto skip_to_a=true;

现在设定的变化,你介绍你的块,如果设定的:

now the set changes, and you introduce your block with the if of the set:

if (!skip_to_a) BEGIN
   do something1
   if cond2 skip_to_b=true;
   END

中集

接下来的变化,因此新的if块:

next change in set, so new if block:

if (!skip_to_a and !skip_to_b) BEGIN
   do something2
   END

等等(我猜你现在明白了吧)。

and so on (I guess you get now the idea).

修改:作为一个可以与集的例子是,一般不可能将它与嵌套IFS模型很好看,因为如与skip_to_a的线条和那些与skip_to_b重叠,但也包含了其他完整。

EDIT: As one can nicely see with the sets in the example it is in general not possible to model it with nested ifs, as e.g. the lines with skip_to_a and the ones with skip_to_b overlap, but neither contains the other complete.