ANTLR重写查询文本以使用早期节点重复文本

时间:2010-11-19 10:45:29

标签: antlr antlr3 antlrworks

我是ANTLR的新手,正在尝试使用以下

解析查询
grammar SearchEngineQuery; 

options { language = CSharp2; output = AST; } 

tokens {
AndNode;
}

LPARENTHESIS : '('; 
RPARENTHESIS : ')'; 

AND    : 'and'; 
OR     : 'or'; 
ANDNOT : 'andnot'; 
NOT    : 'not'; 
NEAR    : 'near'; 


fragment CHARACTER : ('a'..'z'|'0'..'9'|'-'); 
fragment QUOTE     : ('"'); 
fragment WILDCARD  : ('*'|'?'); 
fragment SPACE     : (' '|'\n'|'\r'|'\t'|'\u000C'); 

WILD_STRING 
   : (CHARACTER)* 
     ( 
       ('?') 
       (CHARACTER)* 
     )+ 
   ; 
PREFIX_STRING 
   : (CHARACTER)+
     ( 
       ('*')  
     )+ 
   ; 
WS     : (SPACE) { $channel=HIDDEN; }; 
PHRASE : (QUOTE)(WORD)(WILDCARD)?((SPACE)+(WORD)(WILDCARD)?)*(QUOTE); 
WORD   : (CHARACTER)+; 

startExpression  : nearExpression; 
nearExpression     : andExpression (NEAR^ andExpression)*; 
andExpression 
  :  (andnotExpression        ->  andnotExpression) 
     (AND? a=andnotExpression -> ^(AndNode $andnotExpression $a))*  
  ; 

andnotExpression : orExpression (ANDNOT^ orExpression)*; 
orExpression     : notExpression (OR^ notExpression)* ; 
notExpression    : (NOT^)? (phraseExpression | wildExpression | prefixExpression | atomicExpression); 
phraseExpression : (PHRASE^);
wildExpression    : (WILD_STRING^); 
prefixExpression    : (PREFIX_STRING^); 
atomicExpression :  WORD | LPARENTHESIS! andExpression RPARENTHESIS!; 

这似乎适用于一般查询。但是,a near (b or c)的情况需要实际处理为:

alt text

a near (b or c and (d or e))需要处理为:

alt text

我无法确定如何执行此操作。非常感激任何的帮助。

由于

1 个答案:

答案 0 :(得分:0)

您可能可以通过使用多次传递树重写语法来实现此目的。 规则应该相当短。

对于OR案例,

类似于此:

orCaseRight: a=. NEAR ^(OR x=. y=.) -> ^(OR ^(NEAR $a $x) ^(NEAR $a $y));
orCaseLeft: ^(OR x=. y=.) NEAR a=. -> ^(OR ^(NEAR $a $x) ^(NEAR $a $y)); 
每当规则匹配时,topDown中的

添加一个设置rewrite标志的动作,因此只要设置了rewrite标志,就可以应用此语法。

我用它来优化/预先计算数学表达式,它就像一个魅力。