我使用Antrl4来解析类似Java的语言,其中可以使用专有查询语言在括号内编写表达式。想象一下,在Java方法中,应该允许以下行:
List<MyObject> items = [SELECT Field1,Field2 FROM MyObject];
任何表达式中也应允许使用查询语言,例如
if ([SELECT Field1,Field2 FROM MyObject]!=null) { }
也应该被允许。我的解析器需要使用两种模式的元素定义规则(当处于类似Java的模式时,处于查询语言模式时)。
我正试图将其作为一个孤岛语法来处理,正如最终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']'
;
但是这会在第一个括号字符上产生令牌识别错误。
这种方法有什么问题吗?谁能指出我正在制造的错误?
答案 0 :(得分:1)
如果您转储令牌流以查看词法分析器实际执行的操作,则此类问题更容易诊断。在这里,开放括号在词法分析器中被识别为OPEN_QUERY
并且关闭为CLOSE_QUERY
。因此,作为隐式标记的文字括号即。在解析器中指定为“['和']',不会出现在标记流中。
通过更改为
进行简单修复queryExpression
: OPEN_QUERY SELECT QueryIdentifier FROM QueryIdentifier CLOSE_QUERY
;