【发布时间】:2014-07-15 18:55:26
【问题描述】:
假设我有以下所有打包为 blocks.jar 的 Java API:
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 操作。我阅读了优秀的Simple Example,它使用 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 脚本中遇到特定语法时,如何指示 ANTLR 调用各种代码(封装在 blocks.jar 中)? 更重要的是,谁能给我一个伪代码示例?
【问题讨论】:
-
你考虑过 Xtext 吗?那会给你一个很好的编辑器,等等。在使用 Xtext 和 Xtend 实现特定领域的语言中,作者在第 8 章展示了如何实现解释器。(虽然如果你不习惯使用 eclipse 作为依赖,你也可以创建独立的应用程序。)
-
谢谢@GáborBakos (+1) - 我很欣赏这个建议,但我正在寻找一个基于 ANTLR 的解决方案,原因超出了这个问题的范围!
-
没问题。 (虽然Xtext也是基于antlr的。)
标签: java antlr grammar interpreter scripting-language