快速业务通道

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

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-20

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

时间:2011-01-30 Ted Neward

特定领域语言(Domain-specific languages,DSL)已经成为一个热门话题;很多函数性语言之所以受欢迎,主要是因为它们可以用于构建 DSL。有鉴于此,在 面向 Java 开发人员的 Scala 指南 系列的最后一篇文章中,Ted Neward 继续讨论一个简单的计算器 DSL,以展示函数性语言在构建“外部”DSL 的强大功能,并在此过程中解决将文本输入转换成用于解释的 AST 的问题。为了解析文本输入,并将它转换成上一篇文章中解释器使用的树结构,Ted 引入了 解析器组合子(parser combinator),这是一个专门为这项任务设计的标准 Scala 库。(在 上一篇文章 中,我们构建了一个计算器解析器和 AST)。

回忆一下我们的英雄所处的困境:在试图创建一个 DSL(这里只不过是一种非常简单的计算器语言)时,他创建了包含可用于该语言的各种选项的树结构:

二进制加/减/乘/除运算符

一元反运算符

数值

它背后的执行引擎知道如何执行那些操作,它甚至有一个显式的优化步骤,以减少获得结果所需的计算。

最后的 代码 是这样的:

清单 1. 计算器 DSL:AST 和解释器

package com.tedneward.calcdsl {   private[calcdsl] abstract class Expr   private[calcdsl] case class Variable(name : String) extends Expr   private[calcdsl] case class Number(value : Double) extends Expr   private[calcdsl] case class UnaryOp(operator : String, arg : Expr) extends Expr   private[calcdsl] case class BinaryOp(operator : String, left : Expr, right : Expr)   extends Expr   object Calc   {    /**    * Function to simplify (a la mathematic terms) expressions    */    def simplify(e : Expr) : Expr =    {     e match {      // Double negation returns the original value      case UnaryOp("-", UnaryOp("-", x)) => simplify(x)      // Positive returns the original value      case UnaryOp("+", x) => simplify(x)      // Multiplying x by 1 returns the original value      case BinaryOp("*", x, Number(1)) => simplify(x)      // Multiplying 1 by x returns the original value      case BinaryOp("*", Number(1), x) => simplify(x)      // Multiplying x by 0 returns zero      case BinaryOp("*", x, Number(0)) => Number(0)      // Multiplying 0 by x returns zero      case BinaryOp("*", Number(0), x) => Number(0)      // Dividing x by 1 returns the original value      case BinaryOp("/", x, Number(1)) => simplify(x)      // Dividing x by x returns 1      case BinaryOp("/", x1, x2) if x1 == x2 => Number(1)      // Adding x to 0 returns the original value      case BinaryOp("+", x, Number(0)) => simplify(x)      // Adding 0 to x returns the original value      case BinaryOp("+", Number(0), x) => simplify(x)      // Anything else cannot (yet) be simplified      case _ => e     }    }    def evaluate(e : Expr) : Double =    {     simplify(e) match {      case Number(x) => x      case UnaryOp("-", x) => -(evalu

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号