отобразить структуру только с частичным соответствием - PullRequest
1 голос
/ 20 августа 2010

У меня есть древовидная структура абстрактных классов и case-классов, представляющих абстрактное синтаксическое дерево небольшого языка.

Для верхнего абстрактного класса я реализовал метод map:

abstract class AST {
...
  def map(f: (AST => AST)): AST = {
     val b1 =  this match {
      case s: STRUCTURAL => s.smap(f) // structural node for example IF(expr,truebranch,falsebranch)
      case _ => this // leaf, // leaf, like ASSIGN(x,2)
    }
    f(b1)
  }
...

Smap определяется как:

 override def smap(f: AST => AST) = {
    this.copy(trueb = trueb.map(f), falseb = falseb.map(f))
  }

Теперь я пишу различные «преобразования» для вставки, удаления и изменения узлов в AST.

Например, удалить соседние узлы NOP из блоков:

def handle_list(l:List[AST]) = l match {
  case (NOP::NOP::tl) => handle_list(tl)
  case h::tl => h::handle_list(tl)
  case Nil => Nil
}

ast.map {
  case BLOCK(listofstatements) => handle_list(listofstatements)
}

Если я напишу так, я получу MatchError, и я смогу "исправить это", изменив приведенную выше карту на:

ast.map {
  case BLOCK(listofstatements) => handle_list(listofstatements)
  case a => a
}

Должен ли я просто жить со всеми этими case a => a или я мог бы каким-то образом улучшить свой метод map (или другие части)?

Ответы [ 2 ]

4 голосов
/ 20 августа 2010

Сделать аргумент map a PartialFunction:

def map(f: PartialFunction[AST, AST]): AST = {
  val idAST: PartialFunction[AST, AST] = {case a => a}
  val g = f.orElse(idAST)

  val b1 =  this match {
    case s: STRUCTURAL => s.smap(g)
    case _ => this
  }
  g(b1)
}
4 голосов
/ 20 августа 2010

Если преобразования дерева являются более чем второстепенным аспектом вашего проекта, я настоятельно рекомендую вам использовать модуль Rewriter Kiama для их реализации. Он реализует стратегически-подобные стратегические преобразования. Он имеет очень богатый набор стратегий и комбинаторов стратегий, которые позволяют полностью отделить логику обхода (которую в подавляющем большинстве случаев можно взять «с полки» от поставляемых стратегий и комбинаторов) от (локальных) преобразований (которые специфичные для вашего AST, и вы, конечно, поставляете).

...