定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,“语言”是指使用规定格式和语法的代码。
其中,Context类用于存储解释器之外的一些全局信息;NumberNode类称作终结符表达式;SymbolNode类称作非终结符表达式;非终结符表达式中包含其他非终结符表达式或终结符表达式,非终结符表达式中的interpret方法通常以递归方式执行。
public interface Node {
Float interpret(Context context);
}
public class NumberNode implements Node {
private String key;
public NumberNode(String key) {
this.key = key;
}
@Override
public Float interpret(Context context) {
return context.getNode().get(key);
}
}
public class SymbolNode implements Node {
private Node leftNode;
private Node rightNode;
private String symbol;
public SymbolNode(Node leftNode, Node rightNode, String symbol) {
this.leftNode = leftNode;
this.rightNode = rightNode;
this.symbol = symbol;
}
@Override
public Float interpret(Context context) {
switch (this.symbol) {
case "+":
return leftNode.interpret(context) + rightNode.interpret(context);
case "-":
return leftNode.interpret(context) - rightNode.interpret(context);
case "*":
return leftNode.interpret(context) * rightNode.interpret(context);
case "/":
return leftNode.interpret(context) / rightNode.interpret(context);
default:
return null;
}
}
}
public class Context {
private String text;
private Map<String, Float> node;
public Context(String text) {
this.text = text;
node = new LinkedHashMap<>();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Map<String, Float> getNode() {
return node;
}
public void interpret() {
String[] split = text.split(" ");
for (String textSplit : split) {
if (!"+".equals(textSplit) && !"-".equals(textSplit) && !"*".equals(textSplit) && !"/".equals(textSplit)) {
node.put(textSplit, new Random().nextFloat());
}
}
Node leftNode = null;
Node rightNode = null;
LinkedList<Node> nodeList = new LinkedList<Node>();
nodeList.push(new NumberNode(split[0]));
for (int i = 1; i < split.length; i++) {
if ("+".equals(split[i]) || "-".equals(split[i]) ||"*".equals(split[i]) || "/".equals(split[i])) {
leftNode = nodeList.pop();
rightNode = new NumberNode(split[i + 1]);
nodeList.push(new SymbolNode(leftNode, rightNode, split[i]));
}
}
System.out.println(nodeList.pop().interpret(this));
}
}
@Test
public void interpreterTest() {
Context context = new Context("number1 * number2 / number3 + number4 - number5");
context.interpret();
}