我正在尝试使用antlr4 编写我自己的语言。我设法创建自己的语法并创建自己的访问者来编译我的语言。
现在,我正在尝试为我的语言构建简单的 GUI 界面。然而,我很困惑如何做到这一点,或者是否可能。 情况是这样的。
我的语言支持简单的函数声明。假设我的 html 页面上有简单的文本区域,它加载我的代码构建解析器和通常的 antlr 内容。之后我调用运行我的代码的访问者。
var chars = new antlr4.InputStream(inputText);
var lexer = new TinyLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
var parser = new TinyParser(tokens);
parser.buildParseTrees = true;
var tree = parser.parse();
var visitor = new Visitor();
visitor.visit(tree);
我的语言:
def rock()
println("You selected ROCK")
end
rock()
这正在工作并将消息打印到我的输出窗口。但是现在我添加了对我的语言的按钮的支持,这些按钮可以在单击时调用某些函数。 这将创建简单的 html 按钮,单击时应调用函数 rock():
Button btn1("MyButton", "rock()")
访问 newButtonCall 时我的想法是这样的
Visitor.prototype.visitNewButtonCall = function (ctx) {
var buttonId = ctx.Identifier().getText();
var buttonName = this.visit(ctx.exprList().expression(0));
var buttonFunction = this.visit(ctx.exprList().expression(1));
var button = document.createElement('button');
button.onclick = function(){
if(buttonFunction in this.myFunctions){
return this.myFunctions[buttonFunction].invoke();
}
};
};
当然,这不起作用,因为访问者完成了其工作,并且不再保留任何内容的引用,因此 this.myFunctions 不再存在。 但是我不知道如何使这项工作有效(除了再次调用整个访问者进程)。
有什么帮助吗?非常感谢!
最佳答案
Of course, this cant work cause visitor finished its job and it is no more keeping reference about anything so this.myFunctions doesnt exist anymore
这并不是它不起作用的原因。函数可以从其周围范围访问对象,并且这些对象将与函数一起存在。
您的代码不起作用,因为将在按钮上调用 onclick
,因此 this
将是按钮,而不是您的访问者。您可以将 this
分配给变量,同时它仍然引用访问者(即在 onclick
函数之外),然后使用该变量而不是 this
:
var visitor = this;
button.onclick = function(){
if(buttonFunction in visitor.myFunctions){
return visitor.myFunctions[buttonFunction].invoke();
}
};
PS:关于术语的注释:您正在编写的不是编译器。编译器生成另一种语言的代码(通常是机器代码/汇编,但在 Web 环境中,语言通常也被编译为 JavaScript(或非 GC 语言的 Web 汇编))。您的访问者直接执行代码,使其成为解释器。
关于javascript - Antlr4 基于事件的访客 (javascript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50065509/