2017-01-20 15 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)) 

Я тогда следующие данные тип, определенный:

case class Tree[Expr](e: Expr, children: List[Tree[Expr]]) 

Вот плохо обращается дерево оценка:

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

Я хочу создать структуру данных дерева, представляющую это. Таким образом, в результате чего выход оценки будет:

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:

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

ли это правильный путь, чтобы представить это дерево оценки, и если да, то как я могу пойти о создании такой вложенной структуры данных дерева.

EDIT: Вот метод Eval для того только

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 toTree(e: Expr): Tree[Expr] = e match { 
    case Plus(e1, e2) => Tree(e, List(eval(e1), eval(e2))) 
    case _ => Tree(e, List()) 
} 

Однако, вы бы лучше опустить Tree в @puhlen предлагает. Следующий метод должен быть достаточно:

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

Просто использовать его везде, где вы будете использовать Tree.children

+0

Другой вопрос. Это дерево оценки будет использоваться для генерации HTML для него. Каждый класс case будет иметь довольно метод печати, который будет отображать лямбда в виде лямбда-символа и т. Д. Однако, это правильная структура данных, чтобы идти об обходе и отображать ее в HTML? – StudentOfLogic

+0

У меня пока нет проблем с этой структурой. 'pretty' может быть легко реализована с учетом соответствия шаблону, аналогичного' children'. –

+0

Я написал что-то похожее на это: https://zeroturnaround.com/rebellabs/parsing-lambda-calculus-in-scala/ и продолжил применять это к моему более сложному языку. Пока это выглядит нормально, но мне также было интересно узнать, что имеет свойство Expr, которое реализовано классами case, а затем каждый переопределяет симпатичный метод. Кроме того, мне трудно было включить PrettyPrinter, когда у меня есть типы. Типы не являются Expr, они имеют тип Type, поэтому мне, вероятно, потребуется сделать PrettyPrinter полиморфным типом принтера. Есть предположения? – StudentOfLogic

 Смежные вопросы

  • Нет связанных вопросов^_^