Javascript中的ANTLR:无法再次解析部分代码

时间:2019-03-20 11:32:10

标签: javascript antlr4

我试图用JavaScript开发UI来解析ANTLR4语法中描述的特定代码。我使用访客来解析代码的所有部分并生成调查表。然后,根据用户以JavaScript形式输入的内容,我解析代码的最后一部分以生成结果(它接近于ANTLR书中起草的计算器机制)。到目前为止,一切都很好。尽管如此,我还是想修改JavaScript表单中的输入,并再次解析以重新生成并重新计算一些结果。此时,AST树变为空。我试图重新初始化语法分析器,例如访问器,以创建语法分析器的新实例。似乎以前的解析器和词法分析器仍处于活动状态,并且不可能“向上移动光标”以再次解析我的源代码的特定块。 感谢您的宝贵帮助。 克里斯

在摘要文件和脚本下面。 语法G4

pre
    :   title ('\n')+
        author ('\n')+
    ;               

peri
    :   (statement ('\n')+)*
        (answer ('\n')+)*
    ;   

post
    :   (feedback ('\n')+)* 
    ;

exercise
        :   pre peri post
        ;
//End of Grammar

javascript主类:

class MyExercise {

constructor(){
    this.chars = antlr4.CharStreams.fromBuffer(input,'utf-8');
    this.lexer = new MyLexer(this.chars);
    this.tokens  = new antlr4.CommonTokenStream(this.lexer);
    this.parser = new MyParser(this.tokens);
    this.visitor = new LabeledVisitor(this.exercise,this.parser);
    this.parser.buildParseTrees = true;
    tree = this.parser.pre();
    this.visitor.visitPre(tree);
    tree = this.parser.peri();
    this.visitor.visitPeri(tree); 
    this.generateAnswersHTML() // generate HTML results and also inputfields to collect values from user.
    this.generateSubmitButton(); // generate submit HTML button
}

generateSubmitButton(){
    var button = document.createElement('input');
    button.setAttribute('type','submit');
    button.setAttribute('value','Check answer');
    button.addEventListener("click",this.checkAnswers.bind(this)); 
    document.getElementById("answer").appendChild(button);
}

checkAnswers(object){
   var tree = this.parser.post();
   this.visitor.visitPost(tree);
  this.generateFeeback(); //Generate HTML feedbacks (function of inputed values by user)
}
}

第一次运行良好,但是当我再次单击调用checkAnswer()方法的checkanswer按钮时,树变为空。

1 个答案:

答案 0 :(得分:0)

有两种方法可以重新解析您的输入:

  1. 每次都重新创建输入流,令牌源+解析器。
  2. 通过

    重置输入流和令牌源
    • 重新创建输入流或将新文本加载到现有文本中。
    • 调用parser.reset()。
    • 在令牌源中再次设置输入流(要重置它,只需调用.reset()不会将其切断)。 lexer.setInputStream(input);
    • 出于相同的原因,再次在令牌流中设置令牌源。 tokens.setTokenSource(lexer);