消除了ANTLR 4语法中ALL(*)解析的需要

  • 本文关键字:ALL ANTLR 语法 antlr4
  • 更新时间 :
  • 英文 :


我正在为一种语言编写ANTLR 4语法,该语言将具有不允许出错的switch语句(类似于C#)。所有case语句都必须由break语句终止。多个case语句可以相互跟随,中间没有任何代码(同样,就像C#中一样)。下面是一段语法片段,可以捕捉到这一点:

grammar MyGrammar;
switchStmt : 'switch' '(' expression ')' '{' caseStmt+ '}' ;
caseStmt : (caseOpener)+ statementList breakStmt ;
caseOpener : 'case' literal ':'  
| 'default' ':' 
;
statementList : statement (statement)* ;
breakStmt : 'break' ';' ;

为了简洁起见,我省略了expressionstatement的定义。但是,需要注意的是,statement的定义包括breakStmt。这是因为break语句也可以用于中断循环。

一般来说,语法很好——它按预期解析输入。然而,我在解析过程中收到了警告,如"line18:0reportAttemptingFullContext d=10(statementList),input='break;"one_answers"line18:0 reportContextSensitivityd=10(statementList)、input='break;"这是有道理的,因为解析器不确定是将break语句匹配为statement还是breakStmt,需要回退到ALL(*)解析。我的问题是,如何更改语法,以消除解析过程中的语法需求,避免性能下降?甚至可以不改变语言语法吗?

您应该从caseStmt的末尾删除breakStmt引用,而是在解析完成后在侦听器或访问者中执行此验证。这为您提供了以下优势:

  1. 当用户省略所需的break语句时,改进了错误处理
  2. 通过消除caseStmt末尾的breakStmt和之前的statementList之间的歧义,改进了解析器性能

我将使用以下规则:

switchStmt
: 'switch' '(' expression ')' '{' caseStmt* '}'
;
caseStmt
: caseOpener statementList?
;
statementList
: statement+
;

相关内容

  • 没有找到相关文章

最新更新