首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Kiama/Scala中有条件地重写术语

在Kiama/Scala中有条件地重写术语
EN

Stack Overflow用户
提问于 2013-04-05 03:47:18
回答 1查看 548关注 0票数 2

我正在尝试在Kiama中实现一个“提交的选择”操作(以及一些以类似方式工作的其他函数)。

我想重写一个术语,只要它的一个子术语可以成功重写(其想法是,一旦你开始任何一个分支,你就是承诺的)。

目前,我可以这样做:

代码语言:javascript
复制
import org.kiama.rewriting.Rewriter
import org.junit.Test

case class B(l:L,r:L)
case class L(s:String)
class RewriteExperiment extends Rewriter {
  def r1 = rule {
    case L(l) if l.s == "X" => L("Did stuff")
  }

  def r2 = strategy {
    case B(l,r) => r1(l) match {
      case Some(x:L) => Some(B(x,"Avoided"))
      case _ => None
    }
  }

  implicit def s2l(s:String) : L = L(s)
}

class RewriteTest extends RewriteExperiment {
  @Test
  def testPruning : Unit = {
    println( rewrite(r2)(B("P","b")) )
    println( rewrite(r2)(B("X","b")) )
  }
}

因此,只有当r2可以成功地将r1应用于第一个子项时,它才会触发。

这感觉不是很Kiama-ish。我有一种感觉,我应该使用同余,但我不能从文档中弄清楚它们是如何工作的。

有没有人能推荐一种更优雅、更具Kiamaish风格的方法呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-08 18:38:06

同余可能是一种方法,但不幸的是,在Kiama中,它们需要一些样板。如果您想朝这个方向发展,请参阅Kiama的lambda2示例。AST.scala定义树节点类型的同余关系,ParLazySubst.scala等文件使用它们来定义策略。例如,在App (s, id)中,如果s在节点的第一个子节点上成功,则App是同余,并且App (s, id)策略在App节点上成功(id是身份策略)。

另一种选择是使用child,这是一种针对单个子对象的通用同余,您可以通过给出其编号来说明要对哪个子对象进行操作。(或者,如果您不知道它是哪个子对象,或者您希望对多个子对象进行操作,则可以使用allonesome。)

例如,我认为下面是一种更清晰的方法来完成上面所做的事情:

代码语言:javascript
复制
  def r1 =
    rule {
      case L (l) if l.s == "X" => L ("Did stuff")
    }

  def r2 =
    rule {
      case B (l, r) => B (l, "Avoided")
    }

  val r3 = (child (1, r1)) <* r2

然后使用r3。

请注意,子项(...)策略在原始输入项上操作,因此我们可以使用正常排序(<*)来决定是否也将r2应用于该项。由于r2不需要了解任何关于r1的知识,因此这个解决方案更具可组合性。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15820362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档