ANTLR4 语法中的优先级问题

Problems with precedence in ANTLR4 Grammar

我在这里开发了这个小语法我有一个问题:

grammar test;

    term : above_term | below_term;

    above_term :
        <assoc=right> 'forall' binders ',' forall_term
        | <assoc=right> above_term '->' above_term
        | <assoc=right> above_term '->' below_term
        | <assoc=right> below_term '->' above_term
        | <assoc=right> below_term '->' below_term
        ;

    below_term :
         <assoc = right> below_term arg (arg)*
        | '@' qualid (term)*
        | below_term '%' IDENT
        | qualid
        | sort
        | '(' term ')'
        ;

    forall_term : term;


    arg : term| '(' IDENT ':=' term ')';
    binders : binder (binder)*;
    binder : name |<assoc=right>name (name)* ':' term | '(' name (name)* ':' term ')' |<assoc=right> name (':' term)? ':=' term;
    name : IDENT | '_';
    qualid : IDENT | qualid ACCESS_IDENT;
    sort : 'Prop' | 'Set' | 'Type' ;

    /**************************************
    * LEXER RULES
    **************************************/

    /*
    * STRINGS
    */

    STRING : '"' (~["])* '"';
    /*
    * IDENTIFIER AND ACCESS IDENTIFIER
    */
    ACCESS_IDENT : '.' IDENT;
    IDENT : FIRST_LETTER (SUBSEQUENT_LETTER)*;
    fragment FIRST_LETTER :  [a-z] | [A-Z] | '_' | UNICODE_LETTER;
    fragment SUBSEQUENT_LETTER : [a-z] | [A-Z] | DIGIT | '_' | '"' | UNICODE_LETTER | UNICODE_ID_PART;
    fragment UNICODE_LETTER : '\' 'u' HEX HEX HEX HEX;
    fragment UNICODE_ID_PART : '\' 'u' HEX HEX HEX HEX;
    fragment HEX : [0-9a-fA-F];

    /*
    * NATURAL NUMBERS AND INTEGERS
    */

    NUM : DIGIT (DIGIT)*;
    INTEGER : ('-')? NUM;
    fragment DIGIT : [0-9];

    WS : [ \n\t\r] -> skip;

如果你愿意,你可以复制这个语法并用antlr测试它,它会工作的。现在回答我的问题: 让我们考虑这样一个表达式:a b -> c d -> forall n:nat, c。 现在根据我的语法 ("->") 规则(紧跟在 forall 规则之后)具有最高的优先级。 至于这个,我希望这个术语被解析,以便 ("->") 规则都在解析树的顶部。像这样:(请注意,这是一个抽象视图,我知道叶子之间有很多上下术语)

然而遗憾的是它没有被这样解析而是这样:

解析器怎么看不到解析树顶部的 (->) 规则?这是优先级问题吗?

通过将 (arg) 规则中的术语更改为 below_term 我们可以解决问题 arg : below_term| '(' IDENT ':=' term ')'; .

让我们以这个表达式为例:a b c。 一旦解析器发现模式 a b 匹配此规则:below_term arg (arg)* 他将 a 作为 below_term 并尝试将 b 与 arg 规则匹配。但是,由于 arg 现在指向 below_term 规则,因此除了在大括号中外,不允许使用 above_term。这解决了我的问题。

术语 a b -> a b c -> forall n:nat, n 现在以这种方式解析: