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

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

我正在创建一个语法来将解析器编译为 JavaScript 解析器。

那我想用async/await在visitor或listener中调用异步函数

由于默认生成的代码不包含函数中的异步,因此不允许等待。

这是如何实现的?

您不能真正使用 async 定义侦听器,因为侦听器方法不能 return 任何东西(或者更确切地说,它们的 return 值未被使用),所以什么都不会完成 returned 承诺。

但是,在 visitors 中使用 async 效果非常好。只需将 visitFoo 方法定义为 async 并根据需要使用 await 即可。例如:

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.visit(command) 只是 return 是 this.visitSleep(command)(或任何其他适用的方法)的结果,这将是一个承诺。因此,您正在等待 visitSleep 做出的 return 承诺,一切正常。

请注意,当您的方法是 async 时,您不应该使用默认的 visitChildren 方法,因为那样会访问所有子对象而不 await 访问它们。不过,您可以轻松定义自己的版本:

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