《Programming In Scala》第15章 Case Classes and Pattern Matching 例子
源程序:
/**
* 《Programming In Scala》第15章 Case Classes and Pattern Matching 例子
*/
package org.stairwaybook.expr
import layout.Element.elem
import layout.Element
//表达式基类
sealed abstract class Expr
//变量
case class Var(name: String) extends Expr
//数字
case class Number(num: Double) extends Expr
//一元操作符表达式
case class UnOp(operator: String, arg: Expr) extends Expr
//两元操作符表达式
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
class ExprFormatter {
// 以升序定义操作符的优先级,同一Set内的元素为同一优先级
private val opGroups =
Array(
Set("|", "||"),
Set("&", "&&"),
Set("ˆ"),
Set("==", "!="),
Set("<", "<=", ">", ">="),
Set("+", ""),
Set("*", "%")
)
// 生成操作符优先级Map,Map项目为操作符及它所在的索引号
private val precedence = {
val assocs =
for {
i <- 0 until opGroups.length
op <- opGroups(i)
} yield op -> i
Map() ++ assocs
}
//一元操作符的优先级最高
private val unaryPrecedence = opGroups.length
//由于除法操作符使用竖向排版所以给予特殊优先级
private val fractionPrecedence = -1
private def format(e: Expr, enclPrec: Int): Element =
e match {
//变量
case Var(name) =>
elem(name)
//数字
case Number(num) =>
def stripDot(s: String) =
if (s endsWith ".0") s.substring(0, s.length - 2)
else s
elem(stripDot(num.toString))
//一元操作符
case UnOp(op, arg) =>
elem(op) beside format(arg, unaryPrecedence)
//除法竖向排版
case BinOp("/", left, right) =>
//被除数
val top = format(left, fractionPrecedence)
//除数
val bot = format(right, fractionPrecedence)
//中间的横线
val line = elem('-', top.width max bot.width, 1)
//三部分合并
val frac = top above line above bot
//前一操作符不是/
if (enclPrec != fractionPrecedence) frac
//前一操作符是/,则两边加空格防止与两边的操作符相连
else elem(" ") beside frac beside elem(" ")
//两元操作符
case BinOp(op, left, right) =>
//优先级
val opPrec = precedence(op)
//左边操作数
val l = format(left, opPrec)
//右边操作数
val r = format(right, opPrec + 1)
//横向排版
val oper = l beside elem(" "+ op +" ") beside r
//前一操作符优先级 <= 本操作符优先级
if (enclPrec <= opPrec) oper
//前一操作符优先级 > 本操作符优先级, 打破了优先级默认规则所以加()
else elem("(") beside oper beside elem(")")
}
//使用默认优先级(0)来格式化。
def format(e: Expr): Element = format(e, 0)
}
//文件主单例对象,作为本文件的主执行程序
object Express extends Application {
val f = new ExprFormatter
// 1 / 2 * (x + 1)
val e1 = BinOp("*", BinOp("/", Number(1), Number(2)),
BinOp("+", Var("x"), Number(1)))
// (x / 2) + (1.5 / x)
val e2 = BinOp("+", BinOp("/", Var("x"), Number(2)),
BinOp("/", Number(1.5), Var("x")))
// e1 / e2
val e3 = BinOp("/", e1, e2)
//定义打印函数
def show(e: Expr) = println(f.format(e)+ "\n\n")
//打印每一元素
for (val e <- Array(e1, e2, e3)) show(e)
}
执行结果:
1
- * (x + 1)
2
x 1.5
- + ---
2 x
1
- * (x + 1)
2
-----------
x 1.5
- + ---
2 x
分享到:
相关推荐
基于springboot的招聘求职系统源码数据库文档.zip
基于springboot的校园自助洗衣服务管理系统源码数据库文档.zip
基于java的家乡特产网上商城的开题报告.docx
基于java的校园跑腿管理系统的开题报告
毕业设计&课设_ 健身房管理系统 Java 后端,含多种功能模块,代码完整开源.zip
基于springboot的小学家校互联平台源码数据库文档.zip
基于java的线上选课系统的开题
基于springboot+vue的桂林旅游网站系统源码数据库文档.zip
基于springboot协同过滤算法的个性化音乐推荐系统源码数据库文档.zip
基于SpringBoot的中药材管理系统源码数据库文档.zip
基于springboot的电缆行业生产管理系统源码数据库文档.zip
最新HTML一键打包EXE工具2.0.0, 采用了新的内核, 相比1.x版本, 支持更多最新浏览器特性. HTML一键打包EXE工具能把任意HTML项目(址)一键打包为单个exe文件,在脱离浏览器及服务器的情况下直接运行,支持课件,游戏,址等各类项目.
基于SpringBoot的社区居民诊疗健康管理系统源码数据库文档.zip
上传【mysql数据库项目】资源
压缩文件(3).zip
安装office2010时经常会提示MSXML未安装等问题,导致无法继续安装,使用此一键修复工具可以完美解决
基于springboot的网上商城源码数据库文档.zip
详情介绍 html实现的破碎拼接文字动画特效代码是一段会自动产生文字依次破碎再拼接的效果,非常的炫。欢迎对此段代码感兴趣的朋友前来下载使用。
基于springboot高考志愿智能推荐系统源码数据库文档.zip
Oracle数据库是一种功能强大的关系型数据库管理系统,在企业中被广泛使用。为了方便用户进行数据库管理和操作,Oracle提供了丰富的命令集。 《Oracle常用命令速查手册》将介绍一些常用的Oracle命令和其用法,比如数据导入导出命令、存储过程和触发器的管理以及性能监控等方面的常用命令,通过简单明了的示例,展示了每个命令的用法和效果,以帮助读者更好地理解和使用Oracle数据库