ANTLR重写查询文本以与早期节点重复文本
我是ANTLR新手,正在尝试使用以下方法解析查询ANTLR重写查询文本以与早期节点重复文本,antlr,antlr3,antlrworks,Antlr,Antlr3,Antlrworks,我是ANTLR新手,正在尝试使用以下方法解析查询 grammar SearchEngineQuery; options { language = CSharp2; output = AST; } tokens { AndNode; } LPARENTHESIS : '('; RPARENTHESIS : ')'; AND : 'and'; OR : 'or'; ANDNOT : 'andnot'; NOT : 'not'; NEAR : 'nea
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靠近b或c的情况需要实际处理为:
a靠近b或c和d或e需要处理为:
我无法确定如何做到这一点。任何帮助都将不胜感激
谢谢您可能可以通过使用多重传递树重写语法来实现这一点。 规则应该相当简短 与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));
在自上而下中,每当规则匹配时,添加设置重写标志的操作,以便只要设置了重写标志,就可以应用此语法
我使用它来优化/预计算数学表达式,它的工作方式很有魅力。您可能可以通过使用多重传递树重写语法来实现这一点。 规则应该相当简短 与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));
在自上而下中,每当规则匹配时,添加设置重写标志的操作,以便只要设置了重写标志,就可以应用此语法
我用它来优化/预计算数学表达式,它就像一个魔咒。a和b或c呢?这也应该转化为a和b还是a和c?a靠近b或c和d或e?a和b或c可以按原样处理。这是需要通过分解查询来处理的near选项。对于接近b或c和d或e的a,理想情况下也应该分解。很抱歉延迟回复。我是stackexchange新手,只是一直在我的个人资料中查看这个问题的答案值。现在我知道了。还有一件事,你的语法允许a接近x接近b或c,对吗?如果是这样,那应该产生什么样的AST?@Bart,靠近b或c的近x应该被解析为靠近b或c的近x=>靠近c的近x或接近c的近x。我知道事情会变得很复杂。我想我需要检查查询的复杂性,然后决定是否允许处理该查询,或者停止代码的执行,并要求修改查询input@Puneet嗯,我明白了。有相当多的AST重新订购正在进行。我不认为这可以在语法本身,无论是在组合语法还是从树语法,但我可能是错误的,当然。。。我会仔细考虑一下,但是现在,我要说的是,在创建AST之后,您必须自己手动重新排序AST。请参阅CommonTree的API,以了解如何获得子类以及所述类的其他属性。祝你好运。a和b或c呢?这也应该转化为a和b还是a和c?a靠近b或c和d或e?a和b或c可以按原样处理。这是需要通过分解查询来处理的near选项。对于接近b或c和d或e的a,理想情况下也应该分解。很抱歉延迟回复。我是stackexchange新手,只是一直在我的个人资料中查看这个问题的答案值。现在我知道了。还有一件事,你的语法允许a接近x接近b或c,对吗?如果是这样,那应该产生什么样的AST?@Bart,靠近b或c的近x应该被解析为靠近b或c的近x=>靠近c的近x或接近c的近x。我知道事情会变得很复杂。我想我需要检查查询的复杂性,然后决定是否允许处理该查询,或者停止代码的执行,并要求修改查询input@Puneet嗯,我明白了。有相当多的AST重新订购正在进行。我不认为这可以在语法本身,无论是在组合语法还是从树语法,但我可能是错误的,当然。。。我会仔细考虑一下,但是现在,我要说的是,在创建AST之后,您必须自己手动重新排序AST。请参阅CommonTree的API,以了解如何获得子类以及所述类的其他属性。祝你好运。对不起,我怎么循环语法呢?您能进一步解释一下吗?这将在解析器调用代码中执行。在我看来,它看起来像这样:简化表达式,而不是真的{CommonTreeNodeDestream节点=新建CommonTreeNodeDestreamDownUp;表达式简化表达式简化=新建表达式简化节点;downup=树表达式简化。downupdownup,false;if!表达式简化。重写是否中断;}很抱歉,代码混乱,注释中不支持return。基本上,只要重写器仍在重写某些内容,我就用上一步的结果调用TreeRewriter。很抱歉,但我将如何循环语法?你能进一步解释吗?这将在解析器调用代码中执行。在我的示例中,它类似于这://简化表达式,而true{commonTreeNodesTeam nodes=new CommonTreeNodesStreamDownup;表达式简化表达式简化=
新表达式简化节点;downup=树表达式Simplifying.downup,false;如果expressionSimplifying.u重写中断;}很抱歉代码混乱,注释中不支持return。基本上,只要重写器仍然重写某些内容,我就用上一遍的结果调用TreeRewriter。