2017-01-20 4 views
1

まず、算術式の評価ツリーを構築したいと考えています。評価ツリー

私は定義された以下のケースクラスがあります、

abstract class Expr 
case class Num(n: Integer) extends Expr 
case class Plus(e1: Expr, e2: Expr) extends Expr 

私のパーサをそれが表現を見たときに1 + 1 + 1は、以下のツリー生成:

Plus(Plus(Num(1), Num(1)), Num(1)) 

を、私は、次のデータを持っています定義されているタイプ:

ここではひどく描かれた評価ツリーです:

Num(1)   Num(1) 
----------------------------  
    Plus(Num(1), Num(1))   Num(1) 
--------------------------------------- 
    Plus(Plus(Num(1),Num(1)), Num(1)) 

これを表すツリーデータ構造を構築したいと思います。だから、評価の結果の出力は次のようになります。それは、この評価ツリーを表現し、もしそうなら、私はどのように行くことができます正しい方法

def eval(e: Expr, t: Tree[Expr]): Tree[Expr] = (e, t) match { 
    // Do the matching on Num 
    case Num(n) ........ => 
    case Plus(e1, e2) ...... => 
} 

です:

Tree(
    Plus(Plus(Num(1), Num(1)), Num(1)), 
    List(Tree(Plus(Num(1),Num(1), 
     List(Tree(Num(1), List()), 
      Tree(Num(1), List()))), 
    Tree(Num(1), List()))) 

は、私は、メソッドのevalを持つようにしたいですそのようなネストされたツリーデータ構造の作成について。

EDIT:@puhlenが示唆するようにしかし、あなたがより良いTreeを省略したい

def toTree(e: Expr): Tree[Expr] = e match { 
    case Plus(e1, e2) => Tree(e, List(eval(e1), eval(e2))) 
    case _ => Tree(e, List()) 
} 

:ここで追加する方法の評価は

def eval(e: Expr): Tree[Expr] = e match { 
    case Num(n) => Tree(Num(n), Nil) 
    case Plus(e1, e2) => Tree(Plus(e1, e2), List(eval(e1), eval(e2))) 
} 
+0

を使用する場所にちょうどそれを使用しています。あなたは入れ子になったばかりの木だけを作成しています。すでに – puhlen

+0

私のプロジェクトではありません。私のパーサーは初期の表現であるネストされた木を作りました。私は私のポストに評価木を描きました。上記の投稿を更新し、追加だけの言語のためのソリューションを考え出しました。 – StudentOfLogic

+0

私は割り当てについて何も言わなかった。私はまだTreeクラスの利点を見逃しています、Plusクラスはすでに独自のツリーです。 – puhlen

答えて

2

あなたはこのようにそれを持っていることです。以下の方法では十分なはずです:

def children(e: Expr): List[Expr] = e match { 
    case Plus(e1, e2) => List(e1, e2) 
    case _ => List() 
} 

あなたは私はあなたが木のクラスを必要としないと思うTree.children

+0

もう一つの質問。この評価ツリーは、HTMLを生成するために使用されます。各ケースクラスにはラムダをラムダ文字などで表示するかなりの印刷方法があります。しかしこれは正しいデータ構造で、これを横断してHTMLにレンダリングしますか? – StudentOfLogic

+0

この構造にはまだ問題はありません。 'pretty'は' children'に似たパターンマッチングで簡単に実装できます。 –

+0

私はhttps://zeroturnaround.com/rebellabs/parsing-lambda-calculus-in-scala/と似たような文章を書いて、これを私のより精巧な言葉に適用しました。これまでは大丈夫だったようですが、ケースクラスで実装されたExprの特性について疑問を持っていました。加えて、タイプがあるときはPrettyPrinterを組み込むことが難しいと感じました。型はExprではなく、型の型であるため、多分PrettyPrinterを多態型のプリンタにする必要があります。何かご意見は? – StudentOfLogic