0

我正在尝试学习 kframework,作为练习,我想尝试创建一种高级语言,该语言可以编译为视频游戏的脚本语言。这种高级语言没有真正的执行,只是编译成带有重写规则的脚本语言。

下面的原始脚本语言语法示例

variables {
  0: 'message'
}

init {
  SetVariable("message", "Test message");
}

rule("press button") {
  conditions {
    IsButtonPressed(EventPlayer, INTERACT_KEY);
  }
  actions {
    SendMessage(EventPlayer, GetVariable("message"))
  }
}

我希望我的高级语言允许正确的变量声明,所以我可以写这样的东西,它会编译成上面的脚本。

init {
  var message = "Test message";
}

rule("press button") {
  conditions {
    IsButtonPressed(EventPlayer, INTERACT_KEY);
  }
  actions {
    SendMessage(EventPlayer, message)
  }
}

我知道如何制定一个简单的重写规则来用 替换变量声明var x = ySetVariable("x", y)但我怎么还能附加到顶部的变量声明块?

我很可能误解了 K 的能力,或者我应该如何去做这件事。任何帮助,将不胜感激。

4

1 回答 1

1

通常,在 K 中将一个输入程序转换为另一个输出程序的方法是在构建输出程序时拥有一个包含输出程序的输出单元,并具有一系列规则,这些规则从输入单元中迭代地删除语句和声明,并将它们添加到以您期望的任何修改形式输出单元格。如果您遇到这样的情况,您想乱序插入一些东西,通常的做法是让第二个单元格包含输出程序的一部分,并且处理变量声明的规则会修改两个输出单元格。然后一些规则将在稍后匹配并将输出组合在一起。在这种情况下,该规则可能会在输入程序已用尽时适用。

这大致是在 K 中的样子:

rule <k> var X:Id = E:Expr => . ... </k>
     <output> init { D:Declarations => append(D, SetVariable(Id2String(X), E)) } </output>
     <variables> variables { D:Declarations => append(D, !Y:Int : Id2String(X)) } </variables>
rule <k> . </k>
     <output> P:Program => append(P2, P) </output>
     <variables> P2:Program => . </variables>

请注意,您必须自己编写列表附加函数。如果您真的关心性能,您可能应该使用 List 排序或附加到 cons 列表的前面,然后将其反转,但为了解释的目的,我进行了简化。

于 2020-03-02T17:35:00.537 回答