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

Posted

技术标签:

【中文标题】Scala中中缀运算符的实际优先级【英文标题】:Actual precedence for infix operators in Scala 【发布时间】:2011-11-28 22:55:15 【问题描述】:

2011 年 5 月 24 日 Scala Language Specification 在第 6.12.3 节中发现了一个错字here。这是邮件列表中的acknowledged。

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

【问题讨论】:

【参考方案1】:

我认为通过测试来弄清楚它会很有趣,我编写了以下代码以在 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
|
^
&
! =?
< >
:?
+ -
* / %
?

所以与规范的主要区别是&lt; &gt;需要与= !切换。

【讨论】:

以上是关于Scala中中缀运算符的实际优先级的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中,如何确定用户定义的中缀运算符的运算符优先级?

Haskell 中缀函数应用优先级

在中缀表达式中反转运算符优先级

Scala Operators, File & RegExp

中缀表达式实现简单计算器

将中缀表达式转换为后缀表达式