str*_*cer 5 algorithm programming-languages goto
我用一种旧的自我构思的脚本语言得到了大量遗留代码,我们将其编译/转换为javascript.
该语言有条件跳转,跳转到标签.与常见的goto语句的区别在于,不能进行向后跳转.该语言中没有嵌套的if语句和循环.
由于goto中不存在goto,我正在寻找一种转换goto mylabel
并mylabel:
进入语义等效结构的算法.
我想使用ifs
但发现它不是微不足道的,因为goto标签的任意嵌套.
例:
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:
Run Code Online (Sandbox Code Playgroud)
可以改写为:
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;
}
Run Code Online (Sandbox Code Playgroud)
但是,我无法从中推导出一般算法.
这通常称为Goto Removal,我们只有一次学生工作,其任务是为 C 实现它。一般来说,您必须使用循环(遗憾的是我们没有将该工作放到网上)。但由于你有只能向前跳跃的限制,所以相对容易:
对所有行进行一次解析并收集所有标签。为每个标签创建一个标志“skip_to_label”。在开始时将所有标志初始化为 false。当您满足标签 X 的条件 goto 时,您现在将在每一行前面添加“if not skip_to_label”,直到标签行,并将标志设置为 true。
这应该已经足够并且可以工作了,但当然不是很理想。
如何优化它:不必预先添加 if,只需为每一行维护一组标志,也不必将某些内容设置为 false,只需为行添加集合中相应的标志即可。
现在,您可以为包含所有行的组创建 if,其中集合不会更改,条件是集合的布尔标志。
您给定代码的示例:
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:
Run Code Online (Sandbox Code Playgroud)
现在,您可以在每行前面写入 if(s),或者从顶部开始并创建一个 if 块,只要集合保持不变即可。
因此,当你开始时,你的第一个是空的,它是一个条件跳转,所以你设置你的标志
if cond1 goto skip_to_a=true;
Run Code Online (Sandbox Code Playgroud)
现在集合发生了变化,并且您使用集合的 if 引入了您的块:
if (!skip_to_a) BEGIN
do something1
if cond2 skip_to_b=true;
END
Run Code Online (Sandbox Code Playgroud)
集合中的下一个更改,因此新的 if 块:
if (!skip_to_a and !skip_to_b) BEGIN
do something2
END
Run Code Online (Sandbox Code Playgroud)
等等(我想你现在明白了)。
编辑:正如人们可以很好地看到示例中的集合一样,通常不可能使用嵌套的 if 来对其进行建模,例如,带有skip_to_a的行和带有skip_to_b的行重叠,但两者都不包含另一个完整的行。
归档时间: |
|
查看次数: |
336 次 |
最近记录: |