对所有设计和实现的来说 都不存在一个适当的决策方法 只能承担后果 后果自负
但是这里可以使用一个有趣的小技巧 某些数学表达式可以简化 因而(潜在地)优化了表达式的求值(因此展示了 AST 的有用性)
●任何加上 的运算数都可以被简化成非零运算数●任何乘以 的运算数都可以被简化成非零运算数●任何乘以 的运算数都可以被简化成零
不止这些 因此我们引入了一个在求值前执行的步骤 叫做 simplify() 使用它执行这些具体的简化工作
清单 计算器(src/calc scala)
def simplify(e : Expr) : Expr ={e match {// Double negation returns the original valuecase UnaryOp( UnaryOp( x)) = x// Positive returns the original valuecase UnaryOp( + x) = x// Multiplying x by returns the original valuecase BinaryOp( * x Number( )) = x// Multiplying by x returns the original valuecase BinaryOp( * Number( ) x) = x// Multiplying x by returns zerocase BinaryOp( * x Number( )) = Number( )// Multiplying by x returns zerocase BinaryOp( * Number( ) x) = Number( )// Dividing x by returns the original valuecase BinaryOp( / x Number( )) = x// Adding x to returns the original valuecase BinaryOp( + x Number( )) = x// Adding to x returns the original valuecase BinaryOp( + Number( ) x) = x// Anything else cannot (yet) be simplifiedcase _ = e}}
还是要注意如何使用模式匹配的常量匹配和变量绑定特性 从而使得编写这些表达式可以易如反掌 对 evaluate() 惟一一个更改的地方就是包含了在求值前先简化的调用
清单 计算器(src/calc scala)
def evaluate(e : Expr) : Double ={simplify(e) match {case Number(x) = xcase UnaryOp( x) = (evaluate(x))case BinaryOp( + x x ) = (evaluate(x ) + evaluate(x ))case BinaryOp( x x ) = (evaluate(x ) evaluate(x ))case BinaryOp( * x x ) = (evaluate(x ) * evaluate(x ))case BinaryOp( / x x ) = (evaluate(x ) / evaluate(x ))}}
还可以再进一步简化 注意一下 它是如何实现只简化树的最底层的?如果我们有一个包含 BinaryOp( * Number( ) Number( )) 和 Number( ) 的 BinaryOp 的话 那么内部的 BinaryOp 就可以被简化成 Number( ) 但外部的 BinaryOp 也会如此 这是因为此时外部 BinaryOp 的其中一个运算数是零
我突然犯了作家的职业病了 所以我想将它留予读者来定义 其实是想增加点趣味性罢了 如果读者愿意将他们的实现发给我的话 我将会把它放在下一篇文章的代码分析中 将会有两个测试单元来测试这种情况 并会立刻失败 您的任务(如果您选择接受它的话)是使这些测试 — 以及其他任何测试 只要该测试采取了任意程度的 BinaryOp 和 UnaryOp 嵌套 — 通过
结束语
显然我还没有说完 还有分析的工作要做 但是计算器 AST 已经成形 我们无需作出大的变动就可以添加其他的运算 运行 AST 也无需大量的代码(按照 Gang of Four 的 Visitor 模式) 而且我们已经有了一些执行计算本身的工作代码(如果客户机愿意为我们构建用于求值的代码的话)
lishixinzhi/Article/program/Java/hx/201311/25735
Spark 中用 Scala 和 java 开发有什么区别Scala到底是什么?在目前众多java和scala代码的JVM语言当中java和scala代码,Scala无疑是最引人注意的语言之一 。Scala是一个静态语言 , 更适合大型工程项目 , Scala直接编译成Java字节码 , 性能接近Java 。Scala是一个多范式的语言,java和scala代码你可以混合使用函数式和面向对象编程,混合使用可变类和不变类,混合使用Actor和传统的Java并发库 。
短短一个月的时间,Scala于本月冲进了TIOBE的前五十名 。一个 Twitter 的开发人员说过,Scala 将会成为现代 Web2.0 的发起语言 。LinkedIn 也用这种语言 。同样许多其他大的公司如 Sony Picture, EDF, SAP 也开始使用这种语言 。为什么Scala发展这么迅猛,可以获得如此热烈的社区支持 。
- mysql游标和存储过程是什么 mysql游标表名为变量
- mysql子查询和连接查询 mysql子查询插入
- 纯phpmysql
- mongodb存储图片和文件实践 mongodb存文件和表
- java查询数组中是否包含某一个值 javamongodb数组查询
- 数据库和redis数据不一致 h2数据库和redis
- mongodb 权威指南 mongodb权威指南和实战
- mongo 新建数据库 mongodb创建用户和数据库
- redis怎么和数据库交互 redis数据结合
- redis实战电子书 redisjava书籍
