3

我看到了这篇关于 Scala 延续的不错的博客文章,它“模拟”了GOTOScala 语言中的语句。(在这里阅读更多关于延续的信息

我想在编程语言 Groovy 中也有同样的效果。我认为在Groovy 编译器阶段转换中是可能的。

我正在研究领域特定语言 (DSL),并且首选嵌入到 Groovy 中。我想要这个GOTO声明,因为 DSL 是一种非结构化语言(并且是从工作流程图生成的)。我需要一个“标记”的 goto 语句,而不是行号。

DSL 是一种用于工作流定义的语言,因为节点之间的箭头没有限制,所以goto需要 a。(或不可读的代码while等)

作为 Groovy 和 Scala 的初学者,我不知道是否可以将 Scala 解决方案翻译成 Groovy,但我认为 Groovy 中还有延续。

我正在寻找一种在 Groovy 中模拟标记 goto 的算法/代码。我想到的一种算法是eval重复使用;eval当你在时做goto。DSL 已被评估eval

我不是在寻找“while”循环之类的东西,而是在翻译这段代码以便它工作(其他一些语法没问题)

label1: 
a();
b();
goto label1; 

PS:如果我真的应该使用/想要 GOTO 语句,我不喜欢讨论。DSL 是一种规范语言,可能无法处理变量、效率等问题。

GOTOPS2:然后可以使用其他一些关键字。

4

4 回答 4

5

You might want to tell a little bit more about the language you are trying to build, perhaps it's simple enough that dealing with transformations would be overengineering.
Playing with the AST is something groovy people have been doing for years and it's really powerful.
The spock framework guys rewrite the tests you create annotating the code with labels. http://code.google.com/p/spock/

Hamlet D'Arcy has given several presentations on the matter. Several posts can also be found on his blog. http://hamletdarcy.blogspot.com/
Cedric Champeau describes an interesting transformation he built and its evolution http://www.jroller.com/melix/

Probably missing lots of other guys but those I remember.
A possible starting points that you probably already know but are really useful. http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations
http://groovy.codehaus.org/Building+AST+Guide

Long story short, I'd say its quite possible

于 2011-02-08T19:31:36.937 回答
1

只是把它扔在那里,也许你可以有一个作用域开关盒

因此,如果您的 DSL 这么说:

def foo() {
   def x = x()
   def y
   def z
   label a:
     y = y(x)
   if(y < someConst) goto a
   label b: 
    z = y(z)
    if(z > someConst) goto c
    x = y(y(z+x))
    z = y(x)
   label c:
    return z; 
}

你的“编译器”可以把它变成这样:

def foo() {
    String currentLABEL = "NO_LABEL"
    while(SCOPED_INTO_BLOCK_0143) {
       def x
       def y
       def z
       def retval
       switch(currentLABEL) {
       case "NO_LABEL":
          x = x()
       case "LABEL_A"
          y = y(x)

          if(y < someConst) {
            currentLABEL = "LABEL_A"
           break
          }
       case "LABEL_B"
          z = y(z)

          if(z > someConst) {
            currentLabel = "LABEL_C"
            break
          }
          x = y(y(z+x))
          z = y(x)
       case "LABEL_C"
          SCOPED_INTO_BLOCK_0143 = false
          retval = z
       }
    }
    return retval
}
于 2011-02-14T01:47:51.773 回答
1

您可以模拟ifgoto使用while循环。它不会很漂亮,它会引入许多不必要的代码块,但它应该适用于任何功能。有一些证据表明,这样重写代码总是可能的,但当然可能并不意味着它很好或容易。

基本上,您将所有局部变量移动到函数的开头并添加一个bool takeJump局部变量。然后为任何 goto+label 对添加一个while(takeJump){+}对,并将 while 之前和 while 结束之前的标志设置为您想要的值。

但老实说,我不推荐这种方法。我宁愿使用允许我使用标签和 goto 构建 AST 的库,然后将其直接转换为字节码。

或者使用基于 java vm 构建的其他语言,它支持goto. 我敢肯定有这样的语言。

于 2011-02-08T15:22:14.580 回答
1

您将无法尝试这样做,就像Groovygoto中的保留字(就像在 Java 中一样),因此在您的 DSL 中使用它会有问题。

它不是Scala 中的保留字,所以这不是问题

于 2011-02-08T15:17:12.133 回答