简体   繁体   English

ANTLR4语法中的优先级问题

[英]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. 您可以复制此语法,并根据需要使用antlr对其进行测试,它将起作用。 Now for my question: Let's consider an expression like this: ab -> cd -> forall n:nat, c . 现在是我的问题:让我们考虑这样的表达式: ab-> cd-> forall n:nat,c Now according to my grammar the ("->") rule (right after forall rule) has the highest precedence. 现在,根据我的语法, (“->”)规则(紧随forall规则之后)具有最高优先级。 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 )规则中的term更改为below_term,我们可以解决问题arg : below_term| '(' IDENT ':=' term ')'; arg : below_term| '(' IDENT ':=' term ')'; .

Lets take this expression as an example: abc . 让我们以以下表达式为例: 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. 一旦解析器看到了,则模式ab匹配以下规则: below_term arg (arg)*他将a用作below_term,并尝试将b与arg规则匹配。 However since arg points to the below_term rule now, no above_term is alowed except when it is braced. 但是,由于arg现在指向了below_term规则,因此除非将大括号括起来,否则不会禁止upper_term。 This solved my problem. 这解决了我的问题。

The term ab -> abc -> forall n:nat, n now gets parsed this way: 术语ab -> abc -> forall n:nat, n现在以这种方式解析ab -> abc -> forall n:nat, n

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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