2011-10-01 32 views

Trả lời

23

Tôi nghĩ sẽ thật thú vị khi tìm ra nó bằng cách kiểm tra nó, tôi đã viết đoạn mã sau để được thực hiện trong REPL. Given:

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

Đầu tiên tạo tệp scala trung gian sử dụng và kiểm tra toán tử.

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 

sau đó tải lớp Op, kiểm tra chạy và tải Comp

: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) 

này in:

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

Vì vậy, sự khác biệt chính với spec là < > cần phải được chuyển sang với = !.

+0

Rất thông minh. +1 –

Các vấn đề liên quan