Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Antlr4 bug还是特性?在标记的规则上输入侦听器的方法_Antlr4 - Fatal编程技术网

Antlr4 bug还是特性?在标记的规则上输入侦听器的方法

Antlr4 bug还是特性?在标记的规则上输入侦听器的方法,antlr4,Antlr4,在与解析侦听器玩了一会儿之后,我发现了一种出乎意料的行为。 我的问题是,我的期望是错误的,这种行为是需要的还是一种缺陷?如果需要这种行为,请解释 下面是示例语法: grammar Labeled; file: stmt; stmt: stmt '+' stmt # Add | stmt '*' stmt # Mult | FLOAT # Value | INTEGER # Value ; FLOAT: '-'? DIGIT* '.

在与解析侦听器玩了一会儿之后,我发现了一种出乎意料的行为。 我的问题是,我的期望是错误的,这种行为是需要的还是一种缺陷?如果需要这种行为,请解释

下面是示例语法:

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
}
输出将是:

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()方法。经过一些测试后,发现如果规则的替代项中只有一个令牌/规则,则不会调用enterXXX()方法


提前谢谢

是的,这种行为是预期的(或至少是允许的)。您使用的
addParseListener
方法的文档中包含了行为本身及其基本原理:


是的,这种行为是预期的(或至少是允许的)。您使用的
addParseListener
方法的文档中包含了行为本身及其基本原理:

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