我正在開發給定語言的語法。 我相信我所提出的語法應該可行 - 但Antlr4有不同的意見。鑑於這些錯誤,它看起來像缺少回溯。但Antlr4應該解析沒有...Antlr4解析器失敗 - 需要回溯?
每個例子應該只有一個解決方案。解析過程中有些含糊不清,但除了一個選項外,其他所有選項都應該是死衚衕。所以我期待解析器回去嘗試下一種可能的方法。但它只是報告一個語法錯誤。
語法快速彙總: 有些元素被'#'分隔。在一個元素之後,可以有一個可選的跳轉,這個跳轉由一個'='表示。如果元素本身包含'#'或'=',則通過複製它們來轉義它們。 爲避免歧義,元素不允許以'#'結尾。所以'###'總是第一個分隔符,然後是下一個元素的轉義第一個字符。 '####'不是分隔符,只有兩個名字裏面的'#'。
的語法:
grammar ConfigPath;
configpath: toplevelement subprojectelement* EOF;
subprojectelement: '#' path jump?;
toplevelement: '#' path jump?;
jump: jumpcommand '=' jumpdestination;
jumpcommand: '#d' | '#devpath';
jumpdestination: NONHASHCHAR+;
path: pathelement ('/' pathelement)*;
pathelement: escapedCharacterHash* escapedCharacter ;
escapedCharacterHash: escapedCharacter | '##';
escapedCharacter: NONHASHCHAR | '==';
NONHASHCHAR: ~('#' | '/' | '=');
HASH: '#';
EQ: '=';
測試,以分析器錯誤的評論
@Test
public void testTripleHash() throws Exception {
ConfigpathContext c = parse("#BU/ConfigPath###sub");
// line 1:16 extraneous input '#' expecting {'##', '==', NONHASHCHAR}
Assert.assertEquals("#BU/ConfigPath", c.toplevelement().getText());
Assert.assertEquals("###sub", c.subprojectelement().get(0).path().getText());
}
由於pathelement不能以哈希結束,第一三重散列應該關閉toplevelelement和啓動subprojectelement,以a開頭##
@Test
public void testDoubleHash() throws Exception {
ConfigpathContext c = parse("#BU/proj##bla#d==u##bla");
// line 1:15 mismatched input '==' expecting '='
Assert.assertEquals("#BU/proj##bla", c.toplevelement().getText());
Assert.assertEquals("#d==u##bla", c.subprojectelement().get(0).getText());
}
@Test
public void testJumps() throws Exception {
ConfigpathContext c = parse("#BU/pro##dla#du##d==la#d=dest");
// line 1:14 missing '=' at 'u'
Assert.assertEquals("#BU/pro##dla", c.toplevelement().getText());
Assert.assertEquals(1, c.subprojectelement().size());
Assert.assertEquals("#du##d==la", c.subprojectelement().get(0).path().getText());
Assert.assertEquals("dest", c.subprojectelement().get(0).jump().jumpdestination().getText());
}
private ConfigpathContext parse(String src) {
ConfigPathParser parser = new ConfigPathParser(new CommonTokenStream(new ConfigPathLexer(new ANTLRInputStream(src))));
parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException("line " + line + ":" + charPositionInLine + " " + msg);
}
});
return parser.configpath();
}
有什麼方法可以改變接受測試的語法? 還是Antlr4只是無法解析這樣的語法?帶回溯的Antlr3會找到解決方案嗎?
你的語法是錯誤的 - 假設分析器應該接受你的例子。只有一些提示 - 解析器和詞法分析器檢測到第一條規則,因此您需要確保沒有歧義。如果你要使用antlrworks這樣的東西,你會看到什麼規則被識別等等 – cantSleepNow