🙌

【No.8】変数を使用する

2023/02/21に公開

はじめに

ここでは、前回作成した変数を使用できるようにします。
REPEAT文(?)では、数値しか使用できませんでしたが、変数を使用できるようにします。

BNFの変更

BNFを以下のように変更しました。
<repeat command>のところが変更点です。

<program> ::= PROGRAM <command list>
<command list> ::= <command>* END | <substitution> END
<substitution> ::= <variable> = <number>
<command> ::= <repeat command> | <primitive command>
<repeat command> ::= REPEAT  <number>|<variable>  <command list>
<primitive command> ::= GO | RIGHT | LEFT

実装の変更点

構文解析器のクラスを少し変更しただけです。

RepeatCommand.java
package parser;

import java.util.List;
import java.util.Map;

import lexer.Lexer;

public class RepeatCommand  implements AstNode {

	private AstNode child;
	private boolean isVariable = false;
	private int number;
	private String variableName;

	@Override
	public AstNode parse(Lexer lexer) {
		lexer.nextToken();
		if(lexer.getToken().isNumberToken()) {
			number = lexer.getToken().getNumber();	
		}
		else if(lexer.getToken().isVariableToken()) {
			variableName=lexer.getToken().getContents();
			isVariable = true;
		}
		lexer.nextToken();
		child = new CommandList().parse(lexer);
		return this;		    
	}
	
	@Override
	public void eval(List<String> list, Map<String,Integer> nameTable) {
		int repeatNumber;
		
		if(isVariable) {
			repeatNumber = nameTable.get(variableName);
		}else {
			repeatNumber= this.number;
		}
		
		for(int i=0 ;i<repeatNumber ;i++) {
			child.eval(list,nameTable);
		}
	}
}

課題

「継ぎ足し」のような形で機能追加を行っていると、次第にコードが汚くなってきました。
次回あたりは、リファクタリングを実施します。

Discussion