Scala 中中缀运算符的实际优先级

发布于 2024-12-07 16:04:09 字数 439 浏览 0 评论 0原文

2011 年 5 月 24 日的 Scala 语言规范 在第 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风为裳 2024-12-14 16:04:09

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

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

首先生成一个使用和测试运算符的中间 scala 文件。

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

: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
|
^
&
! =?
< >
:?
+ -
* / %
?

所以与规范的主要区别是 < > 需要用 = ! 切换。

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
)

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

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)

This prints:

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文