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
现在以这种方式解析:
我在这里开发了这个小语法我有一个问题:
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
现在以这种方式解析: