2011-10-01 7 views
7

में इंफिक्स ऑपरेटरों के लिए वास्तविक प्राथमिकता मई 24, 2011 Scala Language Specification में here की खोज के रूप में खंड 6.12.3 में एक टाइपो है। मेलिंग सूची पर यह acknowledged था।स्कैला

इंफिक्स ऑपरेटरों के लिए वास्तविक प्राथमिकता क्या है?

उत्तर

23

मैंने सोचा कि यह परीक्षण करके इसे समझने में मजेदार होगा, मैंने निम्नलिखित कोड को आरईपीएल में निष्पादित किया था। दिया गया:

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

पहले इंटरमीडिएट स्कैला फ़ाइल उत्पन्न करें जो ऑपरेटरों का उपयोग और परीक्षण करें।

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

तो कल्पना के साथ मुख्य अंतर यह है < > जरूरतों = ! साथ स्विच किया जा रहा है:

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 वर्ग लोड करें, चलाने के परीक्षण और लोड

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

यह प्रिंट comps।

+0

बहुत चालाक। +1 –