快速业务通道

面向Java开发人员的Scala指南 - 构建计算器,第3部分 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-20
   }    def evaluate(e : Expr) : Double =    {     simplify(e) match {      case Number(x) => x      case UnaryOp("-", x) => -(evaluate(x))      case BinaryOp("+", x1, x2) => (evaluate(x1) + evaluate(x2))      case BinaryOp("-", x1, x2) => (evaluate(x1) - evaluate(x2))      case BinaryOp("*", x1, x2) => (evaluate(x1) * evaluate(x2))      case BinaryOp("/", x1, x2) => (evaluate(x1) / evaluate(x2))     }    }   } }

面向Java开发人员的Scala指南 - 构建计算器,第3部分(2)

时间:2011-01-30 Ted Neward

……我们使用了一个由 Scala 解析器组合子构建的文本解析器,用于解析简单的数学表达式……

清单 3. 前端

package com.tedneward.calcdsl {   // ...   object Calc   {    object ArithParser extends JavaTokenParsers    {     def expr: Parser[Any] = term ~ rep("+"~term | "-"~term)     def term : Parser[Any] = factor ~ rep("*"~factor | "/"~factor)     def factor : Parser[Any] = floatingPointNumber | "("~expr~")"     def parse(text : String) =     {      parseAll(expr, text)     }    }    // ...   } }

……但在进行解析时,由于解析器组合子当前被编写为返回 Parser[Any] 类型,所以会生成 String 和 List 集合,实际上应该让解析器返回它需要的任意类型(我们可以看到,此时是一个 String 和 List 集合)。

要让 DSL 成功,解析器需要返回 AST 中的对象,以便在解析完成时,执行引擎可以捕获该树并对它执行 evaluate()。对于该前端,我们需要更改解析器组合子实现,以便在解析期间生成不同的对象。

清理语法

对解析器做的第一个更改是修改其中一个语法。在原来的解析器中,可以接受像 “5 + 5 + 5” 这样的表达式,因为语法中为表达式(expr)和术语(term)定义了 rep() 组合子。但如果考虑扩展,这可能会引起一些关联性和操作符优先级问题。以后的运算可能会要求使用括号来显式给出优先级,以避免这类问题。因此第一个更改是将语法改为要求在所有表达式中加 “()”。

回想一下,这应该是我一开始就需要做的事情;事实上,放宽限制通常比在以后添加限制容易(如果最后不需要这些限制),但是解决运算符优先级和关联性问题比这要困难得多。如果您不清楚运算符的优先级和关联性;那么让我大致概述一下我们所处的环境将有多复杂。考虑 Java 语言本身和它支持的各种运算符(如 Java 语言规范中所示)或一些关联性难题(来自 Bloch 和 Gafter 提供的 Java Puzzlers),您将发现情况不容乐观。

因此,我们需要逐步解决问题。首先是再次测试语法:

清单 4. 采用括号

package com.tedneward.calcdsl {   // ...   object Calc   {    // ...    object OldAnyParser extends JavaTokenParsers    {     def expr: Parser[Any] = term ~ rep("+"~term | "-"~term)     def term : Parser[Any] = factor ~ rep("*"~factor | "/"~factor)     def factor : Parser[Any] = floatingPointNumber | "("~expr~")"     def parse(text : String) =     {      parseAll(expr, text)     }    }    object AnyParser extends JavaTokenParsers    {     def expr: Parser[A

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号