假设我有以下Java API,并将其全部打包成blocks.jar
:
public class Block {
private Sting name;
private int xCoord;
private int yCoord;
// Getters, setters, ctors, etc.
public void setCoords(int x, int y) {
setXCoord(x);
setYCoord(y);
}
}
public BlockController {
public static moveBlock(Block block, int newXCoord, int newYCoord) {
block.setCooords(newXCoord, newYCoord);
}
public static stackBlocks(Block under, Block onTop) {
// Stack "onTop" on top of "under".
// Don't worry about the math here, this is just for an example.
onTop.setCoords(under.getXCoord() + onTop.getXCoord(), under.getYCoord());
}
}
不要担心数学和(x,y)坐标不能准确地表示3D空间中的方块。重点是我们有Java代码,编译为JAR,在方块上执行操作。我现在想要构建一个轻量级的脚本语言,允许非程序员调用各种块API方法并操作块,并且我想使用ANTLR(最新版本为4.3)来实现其解释器。
这个脚本语言,我们称之为BlockSpeak,可能看起来像这样:
block A at (0, 10) # Create block "A" at coordinates (0, 10)
block B at (0, 20) # Create block "B" at coordinates (0, 20)
stack A on B # Stack block A on top of block B
这可能相当于以下的Java代码:
Block A, B;
A = new Block(0, 10);
B = new Block(0, 20);
BlockController.stackBlocks(B, A);
因此,这个ANTLR生成的解释器将以
*.blockspeak
脚本作为输入,并使用该脚本中的命令来调用blocks.jar
API操作。我阅读了一个优秀的简单示例,它使用ANTLR创建了一个简单的计算器。但是在链接中,有一个名为ExpParser的类和一个eval()
方法:ExpParser parser = new ExpParser(tokens);
parser.eval();
这里的问题在于,对于计算器而言,
tokens
代表需要计算的数学表达式,而eval()
返回的是表达式的结果。但对于一个解释器来说,tokens
应该代表我的BlockSpeak脚本,但调用eval()
时不应该进行任何计算,而应该知道如何将各种BlockSpeak命令映射到Java代码中:BlockSpeak Command: Java code:
==========================================
block A at (0, 10) ==> Block A = new Block(0, 10);
block B at (0, 20) ==> Block B = new Block(0, 20);
stack A on B ==> BlockController.stackBlocks(B, A);
所以我的问题是,我在哪里执行这个“映射”?换句话说,当ANTLR遇到BlockSpeak脚本中的特定语法时,我如何指示它调用blocks.jar
内部打包的各个代码块?更重要的是,有人能给我一个伪代码示例吗?