首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ANTLR4如何等待所有规则的处理?

ANTLR4如何等待所有规则的处理?
EN

Stack Overflow用户
提问于 2022-04-26 16:23:57
回答 1查看 73关注 0票数 1

我已经使用语言服务器协议创建了自己的基于Xtext的DSL和基于vscode的编辑器。我用TextDocument解析来自当前antlr4ts的模型。下面是监听器的代码片段

代码语言:javascript
复制
class TreeShapeListener implements DebugInternalModelListener {

  public async enterRuleElem1(ctx: RuleElem1Context): Promise<void> {
    ...
    // by the time the response is received, 'walk' function returns
    var resp = await this.client.sendRequest(vscode_languageserver_protocol_1.DefinitionRequest.type,
            this.client.code2ProtocolConverter.asTextDocumentPositionParams(this.document, position))
                .then(this.client.protocol2CodeConverter.asDefinitionResult, (error) => {
                    return this.client.handleFailedRequest(vscode_languageserver_protocol_1.DefinitionRequest.type, error, null);
            });
    ...
    this.model.addElem1(elem1);
  }

  public async enterRuleElem2(ctx: RuleElem2Context): void {
    ...
    this.model.addElem2(elem2);
  }

在这里,我创建解析器和树遍历器。

代码语言:javascript
复制
  // Create the lexer and parser
  let inputStream = antlr4ts.CharStreams.fromString(document.getText());
  let lexer = new DebugInternaModelLexer(inputStream);
  let tokenStream = new antlr4ts.CommonTokenStream(lexer);
  let parser = new DebugInternalModelParser(tokenStream);
    
  parser.buildParseTree = true;
  let tree = parser.ruleModel();

  let model = new Model();
  ParseTreeWalker.DEFAULT.walk(new TreeShapeListener(model, client, document) as ParseTreeListener, tree);
  console.log(model);

问题是,在处理规则之一(enterRuleElem1)时,我有一个异步函数(client.sendRequest),它在ParseTreeWalker.DEFAULT.walk返回后返回。我怎样才能让walk等到所有规则完成?

编辑1:不确定这是否是walk函数的工作方式,但是尝试用下面的最小代码重新创建上述场景

代码语言:javascript
复制
function setTimeoutPromise(delay) {
    return new Promise((resolve, reject) => {
      if (delay < 0) return reject("Delay must be greater than 0")
  
      setTimeout(() => {
        resolve(`You waited ${delay} milliseconds`)
      }, delay)
    })
}

async function enterRuleBlah() {
    let resp = await setTimeoutPromise(2500);
    console.log(resp);
}

function enterRuleBlub() {
    console.log('entered blub');
}

function walk() {
    enterRuleBlah();
    enterRuleBlub();
}

walk();

console.log('finished parsing');

输出是

代码语言:javascript
复制
entered blub
finished parsing
You waited 2500 milliseconds

编辑2:,我尝试了答案中的建议,现在它起作用了!我的解决方案如下:

代码语言:javascript
复制
    public async doStuff() {
        ...
        return new Promise((resolve)=> {
            resolve(0);
        })
    }

    let listener = new TreeShapeListener(model, client, document);
    ParseTreeWalker.DEFAULT.walk(listener as ParseTreeListener, tree);

    await listener.doStuff();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-27 06:42:08

树遍历是完全同步的,不管您是否使侦听器/访问者规则异步。最好将请求与can分开,后者只应该收集所有需要知道发送什么的信息,然后在处理这个集合并实际发送请求之后,您可以等待这些请求。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72017372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档