🙌
【No.8】変数を使用する
はじめに
ここでは、前回作成した変数を使用できるようにします。
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