代码之家  ›  专栏  ›  技术社区  ›  jordiburgos

如何使用异步/等待方法来编写Antlr访问者或侦听器?

  •  0
  • jordiburgos  · 技术社区  · 6 年前

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

    然后我想使用async/await在访问者或侦听器中调用异步函数。

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

    这是怎么做到的?

    1 回复  |  直到 6 年前
        1
  •  1
  •   sepp2k    6 年前

    你不能用 async 因为侦听器方法不能返回任何内容(或者更确切地说,它们的返回值没有被使用),所以对返回的承诺什么也不做。

    但是,使用 异步的 在里面 参观者 工作得很好。定义你的 visitFoo 方法 异步的 和使用 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) 只返回 this.visitSleep(command) (或其他适用的方法),这将是一个承诺。所以你在等待着 visitSleep 一切顺利。

    注意不要使用默认值 visitChildren 当你的方法是 异步的 因为那会造访所有的孩子 等待 对他们。但是,您可以轻松定义自己的版本:

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