我想要创建一个特殊的计算器。我认为case class是操作的好主意:
sealed class Expr
case class add(op1:Int, op2:Int) extends Expr
case class sub(op1:Int, op2:Int) extends Expr
case class mul(op1:Int, op2:Int) extends Expr
case class div(op1:Int, op2:Int) extends Expr
case class sqrt(op:Int) extends Expr
case class neg(op:Int) extends Expr
/* ... */现在,我可以使用匹配案例来解析输入。也许,我也应该使用traits (即:trait Distributivity、trait Commutativity等),这是可实现的吗?这是个好主意吗
发布于 2010-09-03 11:59:23
在你开始添加附加价值不那么清晰的特性之前,你应该正确地掌握基本知识。您现在这样做使这些类不太有用,至少在构建经典AST (或“解析树”)时是如此。想象4* (3+5)。在使用乘法运算之前,必须先计算加法。这让事情变得复杂了。你通常想要的是“立即”写出公式的能力,例如Mul(4,Add(3,5))。但是,这样做是行不通的,因为您无法在您自己的类层次结构中获得Ints或Double。通常的解决方案是数字的包装类,比如"Num“。然后我们有: Mul(Num(4),Add(Num(3),Num(5))。这看起来可能很复杂,但是现在您可以“一次性”地做一些事情,比如引入常量和变量,简化(例如Mul(Num(1),x) -> x),派生.
为了得到这个,你需要一些类似的东西
sealed trait Expr {
def eval:Int
}
case class Num(n:Int) extends Expr {
def eval = n
}
case class Neg(e: Expr) extends Expr {
def eval = - e.eval()
}
case class Add(e1: Expr, e2: Expr) extends Expr {
def eval = e1.eval + e2.eval
}
...现在,您可以编写一个解析器,将"4*(3+5)“转换为Mul(Num(4),Add(Num(3),Num(5)),并通过对该表达式调用eval获得结果。
Scala已经包含了一个称为解析器组合子的解析库。有关接近上述代码的示例,请参阅http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html
https://stackoverflow.com/questions/3634222
复制相似问题