当前位置:七道奇文章资讯编程技术Java编程
日期:2011-01-26 02:54:00  来源:本站整理

<b>面向Java开辟人员的Scala指南: 构建计算器,第3 部份</b>[Java编程]

赞助商链接



  本文“<b>面向Java开辟人员的Scala指南: 构建计算器,第3 部份</b>[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
特定范畴语言(Domain-specific languages,DSL)已经成为一个热门话题;环绕函数性语言谈论得最多的话题是构建这种语言的本领.在构建了 AST 情势和基本前端解析器 之后(用于获得文本和生成合适注释的对象图形),作者在这篇文章中将这些知识无缝地整合起来(固然有点麻烦).然后他将举荐一些合适 DSL 语言及其注释器的扩大.

    欢送勇于摸索的读者回到我们的系列文章中!本月持续摸索 Scala 的语言和库支持,我们将改革一下计算器 DSL 并终究 “完成它”.DSL 本身有点简单 — 一个简单的计算器,目前为止只支持 4 个基本数学运算符.但要记着,我们的目标是成立一些可扩大的、机动的对象,并且今后可以轻松加强它们以支持新的功效.

    持续上次的谈论……

    阐明一下,目前我们的 DSL 有点零乱.我们有一个抽象语法树(Abstract Syntax Tree ),它由大量 case 类构成……

    清单 1. 后端(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

}

    ……对此我们可以供应近似注释器的行为,它能最大限度地简化数学表达式……

    清单 2. 后端(注释器)

package com.tedneward.calcdsl
{
  // ...

  object Calc
  {
    def simplify(e: Expr): Expr = {
      // first simplify the subexpressions
      val simpSubs = e match {
        // Ask each side to simplify
        case BinaryOp(op, left, right) => BinaryOp(op, simplify(left), simplify(right))
        // Ask the operand to simplify
        case UnaryOp(op, operand) => UnaryOp(op, simplify(operand))
        // Anything else doesn't have complexity (no operands to simplify)
        case _ => e
      }

      // now simplify at the top, assuming the components are already simplified
      def simplifyTop(x: Expr) = x match {
        // Double negation returns the original value
        case UnaryOp("-", UnaryOp("-", x)) => x
 
        // Positive returns the original value
        case UnaryOp("+", x) => x
 
        // Multiplying x by 1 returns the original value
        case BinaryOp("*", x, Number(1)) => x
 
        // Multiplying 1 by x returns the original value
        case BinaryOp("*", Number(1), x) => 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)) => 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)) => x
 
        // Adding 0 to x returns the original value
        case BinaryOp("+", Number(0), x) => x
 
        // Anything else cannot (yet) be simplified
        case e => e
      }
      simplifyTop(simpSubs)
    }
 
    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))
      }
    }
  }
}

    ……我们利用了一个由 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().关于该前端,我们需求更改解析器组合子实现,以便在解析期间生成差别的对象.


  以上是“<b>面向Java开辟人员的Scala指南: 构建计算器,第3 部份</b>[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:

  • <b>hosts是什么 hosts文件在什么位置 若何改正hosts</b>
  • <b>在 Windows 8 中手动安装语言包</b>
  • <b>五个常见 PHP数据库问题</b>
  • Windows中Alt键的12个高效快速的利用本领介绍
  • <b>MySQL ORDER BY 的实现解析</b>
  • <b>详解MySQL存储历程参数有三种范例(in、out、inout)</b>
  • <b>Win8系统恢复出来经典的开始菜单的办法</b>
  • <b>Win8系统花屏怎么办 Win8系统花屏的办理办法</b>
  • <b>Windows 7系统下无线网卡安装</b>
  • <b>为什么 Linux不需求碎片整理</b>
  • <b>Windows 8中删除账户的几种办法(图)</b>
  • <b>教你如安在win7下配置路由器</b>
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .