微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在此ANTLR语法中删除一些随机替代项会影响C ++中的自适应预测?

如何解决为什么在此ANTLR语法中删除一些随机替代项会影响C ++中的自适应预测?

我的语法here有所减少(调试问题时,我会尝试进一步减少语法)。我已经尽力缩小了。可以在输入中重现该问题:

SELECT强制转换(a AS b)

后跟EOF Ctrl + D

我得到一个错误

第1:19行的输入')'不匹配,期望AS

使用更多详细的自定义错误侦听器表明,解析器尝试匹配columnExpr AS? identifier替代项而不是columnIdentifier,以便可以将AS关键字解析为CAST外部的一部分替代。

如果我删除了一些语法行,即| showStmtquery的替代项),错误就消失了。我试图跟踪执行情况,结果发现区别在于:

getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input,<some number>,_ctx)

如果输入为SELECT cast (a AS b);错误也消失了。

问题:我的语法有什么问题吗?还是应该以某种方式处理此错误,然后再尝试解析器?我不熟悉不同的错误处理策略和预测器模式,但这也许就是问题所在。


main.cpp文件很简单:

#include "testLexer.h"
#include "testParser.h"

#include <CommonTokenStream.h>

#include <iostream>
#include <iterator>
#include <string>

int main()
{
    using namespace antlr4;

    std::istreambuf_iterator<char> begin(std::cin),end;
    std::string query(begin,end);

    ANTLRInputStream input(query);
    testLexer lexer(&input);
    CommonTokenStream tokens(&lexer);
    testParser parser(&tokens);

    parser.queryStmt();
}

构建线也很简单:

antlr4 -Dlanguage=Cpp test.g4 && clang++ -std=c++17 -g main.cpp testLexer.cpp testParser.cpp -I/usr/include/antlr4-runtime -lantlr4-runtime -o test

解决方法

在语法规则的入口点以外的语法规则中使用EOF时,如果没有其他选择(!),可能会导致行为异常。您可能就是这种情况。

尝试这样的事情:

parse
 : queryStmt (EOF | SEMICOLON)
 ;

queryStmt
 : query
 | insertStmt
 ;

这样自己测试:

TLexer lexer = new TLexer(CharStreams.fromString("SELECT cast (a AS b)"));
TParser parser = new TParser(new CommonTokenStream(lexer));
ParseTree root = parser.parse();
System.out.println(root.toStringTree(parser));

导致了此情况(我的stderr没有任何错误):

(parse (queryStmt (query (selectUnionStmt (selectStmtWithParens (selectStmt SELECT (columnExprList (columnExpr cast ( (columnExpr (columnIdentifier (nestedIdentifier (identifier a)))) AS (identifier b) )))))))) <EOF>)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。