Scala中的中缀运算符的实际优先级 [英] Actual precedence for infix operators in Scala

查看:53
本文介绍了Scala中的中缀运算符的实际优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2011年5月24日《斯卡拉语言规范》 出现了错字在6.12.3节中被发现这里.这是邮件列表上的已确认.

The May 24, 2011 Scala Language Specification has a typo in section 6.12.3 as discovered here. This was acknowledged on the mailing list.

中缀运算符的实际优先级是什么?

What is the actual precedence for the infix operators?

推荐答案

我认为通过测试来弄清楚它会很有趣,我编写了以下要在REPL中执行的代码.鉴于:

I thought it would be fun figuring it out by testing it, I wrote the following code to be executed in the REPL. Given:

val ops = List(
  "letter", "|", "^", 
  "&", "<", ">", "!", 
  "+", "-", "*", "/", "%", "?", 
  "=?", // add ? to prevent assignment
  ":?"  // add ? to prevent right-association
)

首先生成一个使用和测试操作员的中间scala文件.

First generate an intermediate scala file that use and test the operators.

import java.io._

// generate a class with all ops operators defined
// where operator combines in a way we can figure out the precedence
val methods = ops.map("""def %s(o: Op) = Op("["+o.v+v+"]")""".format(_))
val body = methods.mkString("\n")
val out = new PrintWriter(new FileWriter("Op.scala"))
out.println("case class Op(v: String) {\n%s\n}".format(body))

// generate tests for all combinations and store in comps
// Op(".") op1 Op(".") op2 Op(".") v returns "[[..].]" when op2 > op1
// returns "[.[..]]" when op1 <= op2
def test(op1: String, op2:String) = {
  """("%s","%s") -> (Op(".") %s Op(".") %s Op(".")).v.startsWith("[[")""".
    format(op1, op2, op1, op2)
}
val tests = for (op1 <- ops; op2 <- ops) yield { test(op1, op2) }
out.println("val comps = Map[(String, String), Boolean](%s)".format(
  tests.mkString(",\n")))
out.close

然后加载Op类,运行测试并加载comps

Then Load Op class, run tests and load comps

:load Op.scala

// order operators based on tests
val order = ops.sortWith((x,y) => comps(x -> y))

// if op1 or op2 don't have higher precedence, they have the same precedence
def samePrecedence(op1: String, op2: String) = 
  !comps(op1 -> op2) && !comps(op2 -> op1)

def printPrecedenceGroups(list: List[String]): Unit = {
  if (list != Nil) {
    val (same, rest) = list.span(op => samePrecedence(op, list.head))
    println(same.mkString(" "))
    printPrecedenceGroups(rest)
  }
}

printPrecedenceGroups(order)

此打印:

letter
|
^
&
! =?
< >
:?
+ -
* / %
?

因此与规格的主要区别在于< >需要使用= !进行切换.

So the main difference with the spec is < > needs to be switched with = !.

这篇关于Scala中的中缀运算符的实际优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆