当前位置: 首页 > 知识库问答 >
问题:

ANTLR4-不能正确使用岛语法?

龙才俊
2023-03-14

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

List<MyObject> items = [SELECT Field1,Field2 FROM MyObject];
if ([SELECT Field1,Field2 FROM MyObject]!=null) {  }
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']'
;    

但这会导致第一个括号字符上的令牌识别错误。

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

共有1个答案

益清野
2023-03-14

如果您转储令牌流以查看lexer实际上在做什么,则更容易诊断此类问题。这里,在lexer中,打开的方括号被识别为open_query,关闭的方括号被识别为close_query。因此,作为隐式令牌的字面括号,即在解析器中指定为“[”和“]”,并不存在于令牌流中。

通过更改为

queryExpression
    : OPEN_QUERY SELECT QueryIdentifier FROM QueryIdentifier CLOSE_QUERY
    ;    
 类似资料:
  • 我一直在开发一个支持嵌入式SQL语句的COBOL语法。对于不熟悉COBOL的人,这里有一个示例。 “exec SQL”和“end-exec”之间的代码使用了(经过特殊扩充的)SQL语法,这是孤岛语法的一个完美示例。 我知道这可以在ANTLR4中用Lexer模式实现。但我有另一个要求,即SQL语法应该与COBOL语法分离,以便SQL语法在嵌入到其他语言(如PL1)中时可以重用,而无需复制粘贴编程。

  • 我需要antlr4来解析一些简单的HTML文件。我已经将语法分为解析器语法和lexer语法,这样我就可以对标记内部的东西( )使用孤岛语法,如“确定的ANTLR4引用”中所述。antlr4反复告诉我“令牌识别错误”。 解析器语法: 示例HTML文件: ANTLR4的输出:

  • 我想与您分享一个我必须在ANTLR4中实现的岛屿解决方案。 > 语言的结构。我必须为其编写语法的语言是从PL/SQL派生出来的,带有一些附加的构造。我在这里不做更多的详细说明,因为这与主题无关。 该语言定义了一个特殊的命令,其结构如下: 。 我的解决办法是: 任何反馈都是非常欢迎的!问候,沃尔夫冈·哈默

  • 我一直在试图调试为什么我的DropDownChoice在一个简单的表单中只有下拉和提交按钮,但几个小时来没有正常工作。

  • 刚接触 GraphQL,我在通过 GraphiQL 发送查询时遇到问题。 这是我的方案. js 当我在 graphiql 上运行以下查询时: 我收到“语法错误 GraphQL 请求 (3:9) 预期名称,找到字符串”,但我希望获得 ID 为“23”的用户。 我错过了什么?

  • 看起来lexer操作中的getText()无法检索正确匹配的令牌。这是正常的行为吗?例如,我的部分语法有以下规则用于解析C++样式的标识符,这些规则支持\u序列将unicode字符嵌入到标识符名称中: 使用包含带有不正确unicode转义序列的标识符的1行输入进行测试: 但是,IDENTIFIER lexer规则操作的getText()会产生以下错误结果: 为什么lexer规则的getText()