我不确定这是缺陷、限制还是我做错了什么……如果这是讨论这个问题的错误地方,我提前道歉。
我正在尝试更改解析“oil 0w prod or e12b/cpc”时使用的语法的优先级,以便将其处理为等效于“(oil 0w prod)或e12b / cpc”而不是“oil 0w(prod或e12b/cpc)"。
我有以下语法:
parse : statement EOF ;
statement : statement proximityOp statement # ProximityExpression
| statement booleanOperator statement # BooleanExpression
| statement IN delimited # InExpression
| delimited # NoSynonyms
;
delimited : operand
| operand delimiters+=DELIMITER values+=WORD
;
operand : value # SingleValue
;
value : WORD # Term
;
booleanOperator : AND|OR|NOT|LOW_RELATION|SAME_RELATION|HIGH_RELATION;
proximityOp : W_PROX_OP|D_PROX_OP|S_PROX_OP|P_PROX_OP;
LBRACE : '{';
RBRACE : '}';
WS : (' '|'\t'|'\r'|'\n') -> skip;
AND : 'and' | 'AND' | '.' ;
OR : 'or' | 'OR' | ',' ;
NOT : 'not' | 'NOT' ;
DIGIT : ('0'..'9');
W_PROX_OP : DIGIT 'w' | DIGIT 'W' ;
S_PROX_OP : DIGIT 's' | DIGIT 'S' ;
P_PROX_OP : DIGIT 'p' | DIGIT 'P' ;
D_PROX_OP : DIGIT 'd' | DIGIT 'D' ;
DELIMITER : '/' | ':';
SYN_DELIM : '|' ;
USE_SYN : '~' ;
USE_QUERYLET : '$' ;
LPAREN : '(';
RPAREN : ')';
EXCLUSION : '!' ;
EQUALS : '=';
GREATER : '>';
LOWER : '<';
MT_EQUALS : GREATER EQUALS ;
LT_EQUALS : LOWER EQUALS ;
DOUBLE_EQUALS : EQUALS EQUALS ;
SAME_RELATION : '=/same' | '=/SAME';
HIGH_RELATION : '=/high' | '=/HIGH';
LOW_RELATION : '=/low' | '=/LOW';
IN : WS 'in' WS;
COMMENTED : LBRACE .*? RBRACE -> skip ;
WORD : OTHER+ ;
OTHER : ~[\{\}()!,/:|\[\] "=<>\~$];
我已经更改了 ProximityExpression 和 BooleanExpression 的顺序,但它对优先级没有影响 - 尽管我可以看到它会影响转换后的语法:
statement[int _p]
: ( {} delimited
)
( options{preventepsilon=true;}:
{4 >= $_p}? booleanOperator statement
| {3 >= $_p}? proximityOp statement
| {2 >= $_p}? IN delimited
)*
;
记录 ParserRuleContext 时,无论语法中 ProximityExpression 和 BooleanExpression 的顺序如何,我总是得到以下信息:
parsing... oil 0w prod or e12b/cpc
IN.... ParseContext, depth=1: oil0wprodore12b/cpc<EOF>
IN.... ProximityExpressionContext, depth=2: oil0wprodore12b/cpc
IN.... NoSynonymsContext, depth=3: oil
IN.... DelimitedContext, depth=4: oil
IN.... SingleValueContext, depth=5: oil
IN.... TermContext, depth=6: oil
OUT... TermContext
OUT... SingleValueContext
OUT... DelimitedContext
OUT... NoSynonymsContext
IN.... ProximityOpContext, depth=3: 0w
OUT... ProximityOpContext
IN.... BooleanExpressionContext, depth=3: prodore12b/cpc
IN.... NoSynonymsContext, depth=4: prod
IN.... DelimitedContext, depth=5: prod
IN.... SingleValueContext, depth=6: prod
IN.... TermContext, depth=7: prod
OUT... TermContext
OUT... SingleValueContext
OUT... DelimitedContext
OUT... NoSynonymsContext
IN.... BooleanOperatorContext, depth=4: or
OUT... BooleanOperatorContext
IN.... NoSynonymsContext, depth=4: e12b/cpc
IN.... DelimitedContext, depth=5: e12b/cpc
IN.... SingleValueContext, depth=6: e12b
IN.... TermContext, depth=7: e12b
OUT... TermContext
OUT... SingleValueContext
OUT... DelimitedContext
OUT... NoSynonymsContext
OUT... BooleanExpressionContext
OUT... ProximityExpressionContext
我已经在 ANTlr 4 版本和来自 github 的今天的 master 中尝试过这个。
戴夫