2013-11-21 40 views
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()方法不會被調用。如果在規則的替代方案中只有一個令牌/規則,則不會調用方法。

在此先感謝!

回答

1

是的,這種行爲是預期的(或者至少是允許的)。行爲本身以及它的基本原理是包括了你所使用的addParseListener方法的文檔中:

Parser.addParseListener(ParseTreeListener)

相關問題