удалить узел в базе AST при условии

Я новичок в использовании ANTLR. У меня есть грамматика ANTLR, которая создает AST. Я хочу проверить, что если ComparisonExpr содержит FuzzyExpr, то я хочу удалить этот узел ComparisonExpr и союз («и», «или») перед этим ComparisonExpr (если он есть) из AST. Пожалуйста, предложите мне, как это сделать. Я не знаю, что я могу сделать по обычному правилу перезаписи ANTLR или нет?

Например

Given the input: where $GPA = #high and age = 25
I want the output like this: where age = 25
(delete the conjunction "and" and ComparisonExpr=>"$GPA = #high") because it has the FuzzyExpr=>"#hight")

Это часть моей грамматики.

grammar Test;
options{
output=AST;
ASTLabelType=CommonTree;
}

WhereClause      :="where" ExprSingle;
ExprSingle       :OrExpr;
OrExpr           :AndExpr ("or" AndExpr)*;
AndExpr          :ComparisonExpr ("and" ComparisonExpr)*;
ComparisonExpr   :ValueExpr((ValueComp)ValueExpr)?;
ValueExpr        :ValidateExpr
                 |PathExpr 
                 |ExtensionExpr 
                 |FuzzyExpr;
FuzzyExpr        :"#" Literal;

Спасибо. Паннипа


person pannipa saeung    schedule 15.05.2013    source источник
comment
Какую версию ANTLR вы используете? Это будет иметь значение для ответа.   -  person monty0    schedule 15.05.2013
comment
@ monty0, появление output=AST в параметрах предполагает, что OP использует v3.   -  person Bart Kiers    schedule 15.05.2013
comment
@Bart Kiers, я считаю, что это также может быть ANTLR 2 с этими параметрами.   -  person monty0    schedule 15.05.2013
comment
@ monty0, нет, в старые времена v2 был другой синтаксис: antlr2.org/ doc/options.html   -  person Bart Kiers    schedule 15.05.2013


Ответы (1)


Вы можете сделать это, переписав правила. Вот набросок, предполагающий, что вы укореняете свои деревья с помощью оператора:

^(OR e1=expr e2=expr) 
 -> {isFuzzy($e1) && isFuzzy($e2)}? /* empty */
 -> {isFuzzy($e1)}?                 $e2
 -> {isFuzzy($e2)}?                 $e1
 ->                                 ^(OR $e1 $e2)
;

Вы ставите семантические предикаты перед операторами построения дерева. Первый совпадающий предикат выберет, какое дерево будет записано. Если ничего не совпадает, будет использован последний.

person monty0    schedule 16.05.2013
comment
Нет, -> ^() является незаконным. Чтобы создать пустой AST, просто выполните ->, опционально с комментарием, чтобы было понятно, что создается пустой AST. Кроме того, вам не нужны двойные стрелки, ->, в качестве альтернативы. И, наконец, -> ^(X) равно -> X. Я взял на себя смелость отредактировать ваш ответ. - person Bart Kiers; 16.05.2013
comment
Спасибо за помощь, теперь пример намного понятнее (и правильнее)! - person monty0; 16.05.2013
comment
Спасибо большое за помощь. Это полезно для меня. Я использую ANTLR v.3. - person pannipa saeung; 20.05.2013
comment
Если это работает для вас, пожалуйста, примите это как ответ, чтобы люди увидели, что на ваш вопрос дан ответ. - person monty0; 20.05.2013