简体   繁体   中英

Problems with precedence in ANTLR4 Grammar

I developed this small grammar here i have an issue with:

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;

You can copy this grammar and test it with antlr if you want, it will work. Now for my question: Let's consider an expression like this: ab -> cd -> forall n:nat, c . Now according to my grammar the ("->") rule (right after forall rule) has the highest precedence. As for this I want this term to be parsed so that both ("->") rules are on top of the parse tree. like this: 说明我想要的解析树 (Please note, that this is an abstract view, i know that there are many above and below terms between the leafs)

However sadly it doesn't get parsed this way but this way: 可悲的真相

Howcome the parser doesn't see the (->) rules both on top of the parse tree? Is this a precedence issue?

By changing term to below_term in the ( arg ) rule we can fix the problem arg : below_term| '(' IDENT ':=' term ')'; arg : below_term| '(' IDENT ':=' term ')'; .

Lets take this expression as an example: abc . Once the parser sees, that the pattern ab matches this rule: below_term arg (arg)* he puts a as a below_term and trys to match b with the arg rule. However since arg points to the below_term rule now, no above_term is alowed except when it is braced. This solved my problem.

The term ab -> abc -> forall n:nat, n now gets parsed this way:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM