2014-02-26 41 views
10

是否有簡單的方法來實現以下功能?以編程方式檢查字符串是否是Scala中的保留字

即決定在生成代碼時是否需要用反引號引用給定的文本片段。

def isReservedWord(text: String): Boolean 

isReservedWord("type") // true 
isReservedWord("foo") // false 

當然,我可能只是維持基於在語言規範結尾Scala的語法摘要關鍵字的列表,並覈對,但有沒有更好的辦法?

回答

10

編譯器保持它可以很容易地訪問關鍵字列表:

scala> import scala.tools.nsc._ 
import scala.tools.nsc._ 

scala> val compiler = new Global(new Settings) 
compiler: scala.tools.nsc.Global = [email protected] 

scala> compiler.nme.keywords 
res0: Set[compiler.TermName] = Set(abstract, >:, true, val, do, throw, <-, package, _, macro, @, object, false, this, if, then, var, trait, ., catch, with, def, else, class, type, #, lazy, null, =, <:, override, protected, =>, private, sealed, finally, new, implicit, extends, final, for, return, case, import, forSome, :, super, while, yield, try, match, <%) 

scala> compiler.javanme.keywords 
res1: Set[compiler.TermName] = Set(abstract, strictfp, short, int, do, goto, interface, throw, float, package, implements, enum, this, long, if, switch, native, throws, boolean, catch, else, const, class, assert, public, void, instanceof, protected, static, default, private, finally, synchronized, new, char, extends, final, volatile, for, return, continue, case, import, double, super, byte, while, break, try, transient) 

幸運的是,斯卡拉已經提供反射API,這只不過是由一個公共API訪問的編譯器別的。您可以訪問符號表,其中包含所有的定義,當你施放公衆型的內部之一:

scala> val st = scala.reflect.runtime.universe.asInstanceOf[scala.reflect.internal.SymbolTable] 
st: scala.reflect.internal.SymbolTable = [email protected] 

scala> st.nme.keywords 
res10: Set[st.TermName] = Set(abstract, >:, true, val, do, throw, <-, package, _, macro, @, object, false, this, if, then, var, trait, ., catch, with, def, else, class, type, #, lazy, null, =, <:, override, protected, =>, private, sealed, finally, new, implicit, extends, final, for, return, case, import, forSome, :, super, while, yield, try, match, <%) 

裏面的REPL,你也可以使用:power模式以訪問直接編譯:

scala> :power 
** Power User mode enabled - BEEP WHIR GYVE ** 
** :phase has been set to 'typer'.   ** 
** scala.tools.nsc._ has been imported  ** 
** global._, definitions._ also imported ** 
** Try :help, :vals, power.<tab>   ** 

scala> nme.keywords 
res3: Set[$r.intp.global.TermName] = Set(abstract, >:, true, val, do, throw, <-, package, _, macro, @, object, false, this, if, then, var, trait, ., catch, with, def, else, class, type, #, lazy, null, =, <:, override, protected, =>, private, sealed, finally, new, implicit, extends, final, for, return, case, import, forSome, :, super, while, yield, try, match, <%) 

scala> javanme.keywords 
res4: Set[$r.intp.global.TermName] = Set(abstract, strictfp, short, int, do, goto, interface, throw, float, package, implements, enum, this, long, if, switch, native, throws, boolean, catch, else, const, class, assert, public, void, instanceof, protected, static, default, private, finally, synchronized, new, char, extends, final, volatile, for, return, continue, case, import, double, super, byte, while, break, try, transient) 
+0

謝謝!那很完美。 –

1

Grepping編譯器源,我發現:

scala.tools.nsc.doc.html.SyntaxHigh.reserved 

即包和私營部門爲html,所以你可能需要編寫一個包裝。將這個數組複製到自己的源代碼可能更容易。

內部API中有更多內容,例如scala.reflect.internal.StdNamesscala.reflect.internal.Printers有一個方法quotedName,但你需要整個蛋糕來訪問這些。也許你可以通過正式的反射API獲得這些嗎?

相關問題