我是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)
的情况需要实际处理为:
和a near (b or c and (d or e))
需要处理为:
我无法确定如何执行此操作。非常感激任何的帮助。
由于
答案 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
标志,就可以应用此语法。
我用它来优化/预先计算数学表达式,它就像一个魅力。