Скажем, у меня есть следующий 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) координаты не точно представляют блоки в трехмерном пространстве. Дело в том, что у нас есть 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
script, а команды <0 → будут использовать команды blocks.jar
API. Я прочитал отличный Простой пример, который создает простой калькулятор с использованием ANTLR. Однако в этой ссылке существует класс ExpParser с методом eval()
:
ExpParser parser = new ExpParser(tokens);
parser.eval();
Проблема заключается в том, что в случае калькулятора tokens
представляет математическое выражение для оценки, а eval()
возвращает оценку выражения. В случае интерпретатора tokens
будет представлять мой BlockSpeak script, но вызов 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 для вызова различных фрагментов кода (упакованных внутри blocks.jar
), когда он сталкивается с определенными грамматиками в BlockSpeak script? Что еще важнее, может ли кто-нибудь дать мне пример псевдокода?