Antlr4 - 无法获得岛屿语法吗?

Antlr4 - Cannot get island grammars right?

问题

我正在使用 Antrl4 来解析类似 java 的语言,其中可以使用专有查询语言在括号内编写表达式。假设在 Java 方法中,应该允许以下行:

List<MyObject> items = [SELECT Field1,Field2 FROM MyObject];

任何表达式中也应允许使用查询语言,例如

if ([SELECT Field1,Field2 FROM MyObject]!=null) {  }

应该也可以吧。我的解析器需要使用来自两种模式的元素定义规则(当处于 Java 类模式时,当处于查询语言模式时)。

我使用孤岛语法的方法

我正在尝试将其作为一种孤岛语法来处理,如 Definitive Antlr4 参考文献所述,但我无法使其正常工作。

我正在按如下方式构建我的词法分析器语法

OPEN_QUERY : '['    -> pushMode(INSIDE_QUERY);

JavaIdentifier: JavaLetter JavaLetterOrDigit* ;
// omitting fragments and loads of other lexer tokens for brevity

mode INSIDE_QUERY;

CLOSE_QUERY : ']' -> popMode ;
SELECT : 'select';
FROM : 'from';
QueryIdentifier: QueryLetter QueryLetterOrDigit*;
// omitting fragments definition for brevity

在我的解析器语法中,我正在尝试做这样的事情:

expression: normalExpression | queryExpression;

queryExpression
: '[' SELECT QueryIdentifier FROM  QueryIdentifier']'
;    

但这会导致第一个括号字符出现标记识别错误。

这种做法有什么问题吗?谁能指出我犯的错误?

如果转储令牌流以查看词法分析器实际在做什么,则此类问题更容易诊断。在这里,左括号在词法分析器中被识别为 OPEN_QUERY 并被识别为 CLOSE_QUERY。因此,作为隐式标记的文字括号 在解析器中指定为“[”和“]”,在标记流中不存在。

更改为

即可轻松修复
queryExpression
    : OPEN_QUERY SELECT QueryIdentifier FROM QueryIdentifier CLOSE_QUERY
    ;