本文介绍了ANTLR未报告的语法歧义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
谁能帮我理解ANTLR为什么不报告此语法中的歧义问题?
https://github.com/NASA-SW-VnV/fret/blob/master/fret-electron/support/NuSMVParser/NuSMV.g4#L61-L78
simpleExpr
和ltlExpr
中的规则以这样一种方式重复,即始终有两个替代路径来构建任何内容,并对其应用and
、or
、xor
、implies
、equiv
、not
运算符或一些带括号的表达式。
当我对它运行ANTLR时,我预计会看到一条警告,但我什么也得不到(这意味着生成了一个解析器和一个词法分析器)。
推荐答案
由于ANTLR以先到先得的方式匹配解析器规则,因此第一个匹配的规则获胜(解析器不关心是否可以以多种方式解析某些输入)。
若要显示模糊性,您可以附加一个自定义错误侦听器并覆盖其reportAmbiguity
方法,并将预测模式设置为PredictionMode.LL_EXACT_AMBIG_DETECTION
。
如果statement
中的print_statement_1
和print_statement_2
替换项不明确,请使用以下语法:
grammar T;
parse
: statement* EOF
;
statement
: print_statement_1
| print_statement_2
;
print_statement_1
: 'print' expr
;
print_statement_2
: 'print' expr
;
expr
: INT
;
INT
: [0-9]+
;
SPACE
: [
] -> skip
;
ANY
: .
;
如果您运行以下代码:
public static void main(String[] args) {
String source= "print 42";
TLexer lexer = new TLexer(CharStreams.fromString(source));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);
parser.addErrorListener(new BaseErrorListener() {
// The code below is from org.antlr.v4.runtime.DiagnosticErrorListener
@Override
public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact, BitSet ambigAlts, ATNConfigSet configs) {
if (exact) {
String format = "reportAmbiguity d=%s: ambigAlts=%s, input='%s'";
String decision = this.getDecisionDescription(recognizer, dfa);
BitSet conflictingAlts = this.getConflictingAlts(ambigAlts, configs);
String text = recognizer.getTokenStream().getText(Interval.of(startIndex, stopIndex));
String message = String.format(format, decision, conflictingAlts, text);
recognizer.notifyErrorListeners(message);
}
}
protected String getDecisionDescription(Parser recognizer, DFA dfa) {
int decision = dfa.decision;
int ruleIndex = dfa.atnStartState.ruleIndex;
String[] ruleNames = recognizer.getRuleNames();
if (ruleIndex >= 0 && ruleIndex < ruleNames.length) {
String ruleName = ruleNames[ruleIndex];
return ruleName != null && !ruleName.isEmpty() ? String.format("%d (%s)", decision, ruleName) : String.valueOf(decision);
} else {
return String.valueOf(decision);
}
}
protected BitSet getConflictingAlts(BitSet reportedAlts, ATNConfigSet configs) {
if (reportedAlts != null) {
return reportedAlts;
} else {
BitSet result = new BitSet();
Iterator i$ = configs.iterator();
while(i$.hasNext()) {
ATNConfig config = (ATNConfig)i$.next();
result.set(config.alt);
}
return result;
}
}
});
ParseTree root = parser.parse();
}
将打印以下内容:
line 1:8 reportAmbiguity d=1 (statement): ambigAlts={1, 2}, input='print42'
这篇关于ANTLR未报告的语法歧义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!