1
在用解析偵聽器玩了一下之後,我發現了一個我沒想到的行爲。 我的問題對你來說,我錯了我的期望,是這種行爲想要或是一個錯誤?如果行爲是想要的,請解釋它。錯誤或者功能?在標籤規則中輸入偵聽器的方法
這裏樣品語法:
grammar Labeled;
file: stmt;
stmt: stmt '+' stmt # Add
| stmt '*' stmt # Mult
| FLOAT # Value
| INTEGER # Value
;
FLOAT: '-'? DIGIT* '.' DIGIT+;
INTEGER: '-'? DIGIT+;
COMMENT: (COMMENT_LINE | COMMENT_BLOCK) -> skip;
WS: [ \t\r\n] -> skip;
fragment
DIGIT: [0-9];
COMMENT_LINE: '//' ~'\n'*;
COMMENT_BLOCK: '/*' .*? '*/';`
這裏樣品聽衆:
import org.antlr.v4.runtime.misc.NotNull;
import java.util.HashMap;
import java.util.Map;
public class TestListener extends LabeledBaseListener {
public static final String ALL_KEY = "All";
public static final String MULT_KEY = "Mult";
public static final String ADD_KEY = "Add";
public static final String VALUE_KEY = "Value";
public static final String FILE_KEY = "File";
public Map<String, Integer> enterValues = new HashMap<>();
public Map<String, Integer> exitValues = new HashMap<>();
@Override
public void enterMult(@NotNull LabeledParser.MultContext ctx) {
addEnter(ALL_KEY);
addEnter(MULT_KEY);
}
@Override
public void exitMult(@NotNull LabeledParser.MultContext ctx) {
addExit(ALL_KEY);
addExit(MULT_KEY);
}
@Override
public void enterValue(@NotNull LabeledParser.ValueContext ctx) {
addEnter(ALL_KEY);
addEnter(VALUE_KEY);
}
@Override
public void exitValue(@NotNull LabeledParser.ValueContext ctx) {
addExit(ALL_KEY);
addExit(VALUE_KEY);
}
@Override
public void enterFile(@NotNull LabeledParser.FileContext ctx) {
addEnter(ALL_KEY);
addEnter(FILE_KEY);
}
@Override
public void exitFile(@NotNull LabeledParser.FileContext ctx) {
addExit(ALL_KEY);
addExit(FILE_KEY);
}
@Override
public void enterAdd(@NotNull LabeledParser.AddContext ctx) {
addEnter(ALL_KEY);
addEnter(ADD_KEY);
}
@Override
public void exitAdd(@NotNull LabeledParser.AddContext ctx) {
addExit(ALL_KEY);
addExit(ADD_KEY);
}
// region map helper
private static void addValue(Map<String, Integer> valueMap, String name) {
if(valueMap.containsKey(name)) {
valueMap.put(name, valueMap.get(name) + 1);
} else {
valueMap.put(name, 1);
}
}
private void addEnter(String name) {
addValue(enterValues, name);
}
private void addExit(String name) {
addValue(exitValues, name);
}
// endregion
}
主類:
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class Main {
public static void main(String[] args) throws IOException {
String filePath = args[0];
ANTLRInputStream input = new ANTLRFileStream(filePath);
LabeledLexer lexer = new LabeledLexer(input);
CommonTokenStream token = new CommonTokenStream(lexer);
LabeledParser parser = new LabeledParser(token);
TestListener testListener = new TestListener();
parser.addParseListener(testListener);
parser.file();
System.out.println("Enter Values:");
System.out.println(getMapString(testListener.enterValues));
System.out.println("Exit Values:");
System.out.println(getMapString(testListener.exitValues));
System.out.println("End");
}
private static String getMapString(Map<?, ?> map) {
StringBuffer buffer = new StringBuffer();
for(Map.Entry<?, ?> curEntry: map.entrySet()) {
buffer.append("Key: " + curEntry.getKey() + "\tValue: " + curEntry.getValue() + "\n");
}
String result = buffer.toString();
return result;
}
}
現在,當我與內容的文件執行:
-4 + 8
輸出將是:
Enter Values:
Key: File Value: 1
Key: Add Value: 1
Key: All Value: 2
Exit Values:
Key: Value Value: 2
Key: File Value: 1
Key: Add Value: 1
Key: All Value: 4
End
但我希望這樣的輸出:
Enter Values:
Key: Value Value: 2
Key: File Value: 1
Key: Add Value: 1
Key: All Value: 4
Exit Values:
Key: Value Value: 2
Key: File Value: 1
Key: Add Value: 1
Key: All Value: 4
End
因此,大家可以看到enterValue()方法不會被調用。如果在規則的替代方案中只有一個令牌/規則,則不會調用方法。
在此先感謝!