简体   繁体   English

如何使用async / await在其方法上编写ANTLR访问者或侦听器?

[英]How an ANTLR visitor or listener can be written with async/await on its methods?

I am creating a grammar to compile the parser as a JavaScript parser. 我正在创建一个语法来将解析器编译为JavaScript解析器。

Then I would like to use async/await to call asynchronous functions within the visitor or listener. 然后,我想使用async / await在访问者或侦听器中调用异步函数。

As the default generated code does not include async in the functions, await is not allowed. 由于默认生成的代码在函数中不包含异步,因此不允许等待。

How could this be achieved ? 如何实现呢?

You can't really define listeners using async because listener methods can't return anything (or rather their return values aren't used), so nothing would be done with the returned promises. 您实际上不能使用async定义侦听器,因为侦听器方法无法返回任何内容(或者不使用其返回值),因此返回的promise不会做任何事情。

However, using async in visitors works perfectly fine. 但是,在访问者中使用async效果很好。 Just define your visitFoo methods as async and use await as you please. 只需将visitFoo方法定义为async方法,然后根据需要使用await For example: 例如:

class Interpreter extends MyLangVisitor {
    async visitSleep(sleepCtx) {
        let p = new Promise(function (resolve) {
            setTimeout(resolve, sleepCtx.amount.text)
        });
        await p;
    }

    async visitProgram(programCtx) {
        for(let command of programCtx.commands) {
            await this.visit(command);
        }
    }
}

This will work fine because this.visit(command) simply returns the result of this.visitSleep(command) (or whichever other method applies), which will be a promise. 这将很好地工作,因为this.visit(command)只是返回的结果this.visitSleep(command) (或适用取其其他方法),这将是一个承诺。 So you're awaiting the promise returned by visitSleep and everything works out fine. 因此,您正在等待visitSleep返回的承诺,并且一切正常。

Do note that you shouldn't use the default visitChildren method when your methods are async because that will visit all the children without await ing them. 请注意,当您的方法async时,您不应使用默认的visitChildren方法,因为它将访问所有子级而无需await它们。 You can easily define your own version though: 不过,您可以轻松定义自己的版本:

async visitChildren(ctx) {
    for(let child of ctx.children) {
        await this.visit(child);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM