🙌
【No.2】ミニ字句解析器をつくる
字句解析器の仕様
字句解析器と言っても、ここで作成するものは極めて簡単なものです。
以下の2つの機能を持ちます。
- ソースコードを1つの文字列として読み込み、
その文字列を「トークン」と呼ばれる最小単位に分割する。
作成した「トークン」の集合は、コレクションとして保持する。 - 外部からの要求に応じて「トークン」を提供する。
字句解析器の実装
上記の使用をプログラムで表現すると、以下のようになるでしょう。
-
コンストラクタの引数として文字列(ソースコード)を受け取り、
これを「トークン」に分割する。
「トークン」の集合は、配列として保持。 -
getTokenメソッドは、トークンを提供する。
indexフィールドは、次に提供するトークンの場所を保持。
この観点から作成した単体テストです。
LexerTest
package lexer;
import static org.junit.Assert.*;
import org.junit.jupiter.api.Test;
class LexerTest {
@Test
void testLex() {
String sourceCode = "go right left";
Lexer lexer = new Lexer(sourceCode);
assertEquals(lexer.getToken(), "go");
lexer.nextToken();
assertEquals(lexer.getToken(),"right");
}
}
以下が実装です。
Lexer
package lexer;
public class Lexer {
private String[] tokens;
private int index;
public Lexer(String code){
tokens = code.split("\\s+");
}
public String getToken() {
return tokens[index];
}
public void nextToken() {
index ++ ;
}
}
課題
現時点のプログラムには、以下のような課題があります。
-
プログラムの終端をindexが超過した場合に、良い感じの例外が投げられない。
-
字句解析の機能とトークン提供の機能が、同一のクラスに存在している。
別のクラスに分離すべき。(単一責任の原則)
Discussion