👻

【No.5】字句解析器のリファクタリング

2023/02/13に公開

ここでは、字句解析器のリファクタリングを行います。

現在の字句解析器には、以下のような問題があると考えています。

  1. ソースコードが小文字なのは、なんとなく好みではない。

  2. 字句解析の機能とトークン提供の機能が、同一のクラスに存在している。
    別のクラスに分離すべき。(単一責任の原則)

  3. 構文解析器にて、メソッドでトークンの種類を判別できるようにしたい。
    そのため、字句解析器にてトークンの種類を区別しておく。
    (現在は入力されたコードを空白で分解しただけ。)

  4. プログラムの終端をindexが超過した場合に、良い感じの例外が投げられない。

これらの問題に対し、以下のような対応を実施します。

  1. ソースコードの見た目に関する変更です。
    「program go go end」は何となく好みではなかったので、
    「PROGRAM GO GO END」に変更しました。
    じつは、すでに実施済みです。

  2. 次の機能拡張を視野に入れたリファクタです。
    字句解析の部分は大きくなりそうなので、今のうちに分離しておきます。
    今回実施します。

  3. 次回実施。

  4. これは、文法ミスのソースコードが読み込まれた場合の対応です。
    構文解析器のリファクタと同時に実施しようと思います。
    また今度ですね。

字句解析の機能とトークン提供の機能を分離

字句解析の機能をAnalyzerクラスに分離しました。
現時点で大きなメリットがあるわけではないですが、次の機能拡張には役立つはずです。

Lexer.java
package lexer;

public class Lexer{
	
	private String[] tokens;
	private int index = 0;
	
	public Lexer(String code){
		this.lexicalAnarise(code);
	}
	
	private void lexicalAnarise(String sourceCode) {
		tokens = new Analyzer().conduct(sourceCode);
	}
	
	public String getToken() {
		return tokens[index];
	}
	
	public void nextToken() {
		index ++ ;
	}
}
Analyzer.java
package lexer;

public class Analyzer{

	String[] conduct(String sourceCode){
		return sourceCode.split("\\s+");
	}
}

あとがき

今回は簡単なリファクタを実施しました。
次回は長くなりそうです。

Discussion