字句解析器
字句解析器に手をいれていきます。
必要となるものは、"datatype"というキーワードを定義することだけです。
Scalaのソースコードを読んでみる その3で書いたように、キーワードを追加するには、
src/compiler/scala/tools/nsc/ast/parser/Tokens.scalaにキーワード用の定数を追加する。
src/compiler/scala/tools/nsc/ast/parser/Scanner.scalaのallKeywordsというリストに1で定義した定数を追加する。
メソッドinFirstOfStat, inLastOfStat に必要に応じて、1で定義した定数を追加してやる。
src/reflect/scala/reflect/internal/StdNames.scala のclass Keywordsに追加したいキーワードを定義しておく。
の4つです(推測ですが)。
順番に作業していきます。
Tokens.scalaに定数を追加
final val LAZY = 61
final val MACRO = 62 // not yet used in 2.10
final val THEN = 63 // not yet used in 2.10
final val DATATYPE = 64 // ←追加した行
/** special symbols */
Scanner.scalaのallKeywordsに定数を追加
nme.CLASSkw -> CLASS,
nme.DATATYPEkw -> DATATYPE, // ←追加した行
nme.DEFkw -> DEF,
Scanner.scalaのメソッドinFirstOfStat, inLastOfStat
'datatype'が「文の最初にくることが可能なトークンかどうか」というと、文の最初にくることが可能ですので、inFirstOfStatは真になります。なので、特に変更を加える必要はありません(case文に列挙されていないキーワードは真、なので)。
また、「文の最後にくることが可能なトークンかどうか」は偽になります。
よって、inLastOfStatも変更を加える必要はありません(case
文に列挙されていないキーワードは偽なので)。
StdNames.scalaにキーワードを定義
abstract class Keywords extends {
private val kw = new KeywordSetBuilder
final val ABSTRACTkw: TermName = kw("abstract")
final val CASEkw: TermName = kw("case")
final val CLASSkw: TermName = kw("class")
final val CATCHkw: TermName = kw("catch")
final val DATATYPEkw: TermName = kw("datatype") // ←追加した行
final val DEFkw: TermName = kw("def")
字句解析器の修正は以上です。
(つづく)