Antlr4-仅在前一个规则匹配时匹配规则

时间:2019-07-12 01:36:40

标签: parsing antlr4

我有一个解析器,其布局类似于(虽然不完全一样):

compilationUnit: statement* EOF;
methodBody:      statement*;
ifBlock:         IF '(' expression ')' '{' statement* '}' ;
statement:       methodBody | ifBlock | returnStatement | ... ;

此解析器工作正常,我可以使用它。但是,它具有returnStatement会解析的缺陷,即使它不在方法主体中也是如此。理想情况下,我可以对其进行设置,以使returnStatement仅在其下一个父级为statement时才符合methodBody规则。有办法吗?

2 个答案:

答案 0 :(得分:0)

您必须将methodBody内的语句与该作用域外的语句区分开。理想情况下,您将有两种不同的作品。像这样:

compilationUnit: member* EOF;
member:          method | class | ... ;
method:          methodName  '(' parameters ')' '{' methodBody '}' ;
methodBody:      statement*;
statement:       methodBody | ifBlock | returnStatement | ... ;
ifBlock:         IF '(' expression ')' '{' statement* '}' ;

答案 1 :(得分:0)

您正在尝试以错误的级别解决此问题。它不应该在语法级别进行处理,而应在以下语义阶段(用于查找逻辑/语义错误,而不是语法错误的语法阶段,解析器要处理的内容)进行处理。您可以在C grammar中看到相同的方法。 statement规则引用jumpStatement规则,该规则依次与return语句匹配(除其他外)。

处理此类语义错误也可以提供更好的错误消息。代替“没有可行的替代项”,您可以打印一个错误,指出“仅在函数体中允许返回”或类似的错误。为此,请检查生成的语法分析树,搜索return语句,并检查该子树的父上下文以了解其是否有效。