Программная проверка, является ли строка зарезервированным словом в Scala - программирование
Подтвердить что ты не робот

Программная проверка, является ли строка зарезервированным словом в Scala

Есть ли простой способ реализовать следующую функцию?

то есть. чтобы решить, нужно ли цитировать данный фрагмент текста с обратными окнами или нет при генерации кода.

def isReservedWord(text: String): Boolean

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

Конечно, я мог бы просто сохранить список ключевых слов на основе Scala Резюме синтаксиса в конце спецификации языка и проверить на это, но есть ли лучший способ?

4b9b3361

Ответ 1

Компилятор поддерживает список ключевых слов, к которым можно легко получить доступ:

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)

К счастью, Scala уже предоставляет 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)

Ответ 2

Грепинг источника компилятора, я нашел следующее:

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

Это private-package для html, поэтому вам может понадобиться написать оболочку. Вероятно, проще просто скопировать этот массив в собственный источник.

Во внутреннем API имеется больше информации, например. scala.reflect.internal.StdNames. И scala.reflect.internal.Printers имеет метод quotedName, но вам нужен весь торт для доступа к ним. Может быть, вы можете получить любой из них через официальный API отражения?