2014-02-26 40 views
1

我想我可以在scala-reflection或scala編譯器中找到它,但是我一直無法找到一個記錄的API。有沒有辦法在運行時執行此操作?如何判斷Scala中的標識符是否無效?

例如def isValidIdentifer(s:String)

(我沒有興趣在保留關鍵字,我可以寫我自己閱讀手冊的實際列表)

編輯:

基於@ sschaef的答案,更多的規格:它應該處理任何

import scala.tools.reflect.{ToolBox, ToolBoxError} 

lazy val tb = scala.reflect.runtime.universe.runtimeMirror(getClass.getClassLoader).mkToolBox() 

def isIdentifier(ident: String): Boolean = { 
    if (ident.startsWith(" ") || ident.endsWith(" ")) { 
    return false 
    } 
    try { 
    val tree = tb.parse(s"val $ident:Int = 0") 
    if (tree.toString().length != ident.length + 13) { 
     return false 
    } 
    tree.children match { 
     case c0 :: c1 :: Nil if 
     c0.children.isEmpty && c0.productArity == 1 && c0.productElement(0).toString == "Int" 
     && c1.children.isEmpty && c1.productArity == 1 && c1.productElement(0).toString == "Constant(0)" => true 
     case _ => false 
    } 

    } catch { 
    case _: ToolBoxError => false 
    } 
} 
:如果 s是一個有效的標識符

我想擴大這個答案類型的輸入並返回true

這成功以下惡性案件:b:Intb = 0; cb/*comment*/

回答

2

展望,我發現這個編譯器:

case 'A' | 'B' | 'C' | 'D' | 'E' | 
     'F' | 'G' | 'H' | 'I' | 'J' | 
     'K' | 'L' | 'M' | 'N' | 'O' | 
     'P' | 'Q' | 'R' | 'S' | 'T' | 
     'U' | 'V' | 'W' | 'X' | 'Y' | 
     'Z' | '$' | '_' | 
     'a' | 'b' | 'c' | 'd' | 'e' | 
     'f' | 'g' | 'h' | 'i' | 'j' | 
     'k' | 'l' | 'm' | 'n' | 'o' | 
     'p' | 'q' | 'r' | 's' | 't' | 
     'u' | 'v' | 'w' | 'x' | 'y' | // scala-mode: need to understand multi-line case patterns 
     'z' => 
     putChar(ch) 
     nextChar() 
     getIdentRest() 

這是scanner的一部分。此外,看看解析標識符休息的section。它看起來不像您可以輕鬆複製或使用代碼。

我建議使用工具箱:

scala> import scala.tools.reflect.{ToolBox, ToolBoxError} 
import scala.tools.reflect.{ToolBox, ToolBoxError} 

scala> val tb = scala.reflect.runtime.universe.runtimeMirror(
    getClass.getClassLoader).mkToolBox() 
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = [email protected] 

scala> def isIdentifier(ident: String) = 
    try { tb.parse(s"val ($ident) = 0"); true } 
    catch { case _: ToolBoxError => false } 
isIdentifier: (ident: String)Boolean 

scala> isIdentifier("hello") 
res0: Boolean = true 

scala> isIdentifier("hello_-") 
res1: Boolean = true 

scala> isIdentifier("hello-") 
res2: Boolean = false 

scala> isIdentifier("`hello-`") 
res3: Boolean = true 
+0

該解決方案的空白正確不處理。 'isIdentifier(「x = 0; val b」)' – mauhiz

+0

@mauhiz我用括號包圍了插入的代碼,希望這足夠安全。通過從網站輸入文本字段來評估此功能的用例不是問題中提到的要求...;) – sschaef

+0

對,我並不十分清楚。仍然是'isIdentifier(「x)= 0; val(b」)';)只要我們盲目地允許輸入包含空格,try-to-parse解決方案對於注入將會很弱。 – mauhiz

相關問題