如何解决为什么在此ANTLR语法中删除一些随机替代项会影响C ++中的自适应预测?
我的语法here有所减少(调试问题时,我会尝试进一步减少语法)。我已经尽力缩小了。可以在输入中重现该问题:
SELECT强制转换(a AS b)
后跟EOF
的 Ctrl + D 。
第1:19行的输入')'不匹配,期望AS
使用更多详细的自定义错误侦听器表明,解析器尝试匹配columnExpr AS? identifier
替代项而不是columnIdentifier
,以便可以将AS
关键字解析为CAST
外部的一部分替代。
如果我删除了一些语法行,即| showStmt
(query
的替代项),错误就消失了。我试图跟踪执行情况,结果发现区别在于:
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 举报,一经查实,本站将立刻删除。