使用antlr3将堆叠的比较表达式解析为逻辑连接树

时间:2014-01-05 20:10:50

标签: parsing tree antlr3

当我试图解析堆叠的算术比较表达式时,我遇到了一个问题:

"1<2<3<4<5" 

进入逻辑连词树:

CONJUNCTION(COMPARISON(1,2,<) COMPARISON(2,3,<) COMPARISON(3,4,<) COMPARISON(4,5,<))

在Antlr3 Tree Rewrite规则中是否有一种方法可以迭代匹配的令牌并使用目标语言从它们创建结果树(我正在使用java)?所以我可以从匹配的“加法”标记的元素x,x-1制作COMPARISON节点。我知道我可以引用规则的最后结果,但这样我只会得到嵌套的COMPARISON规则,这不是我想要的。

/This is how i approached the problem, sadly it doesn't do what i would like to do yet of course.

fragment COMPARISON:;

operator
:
('<'|'>'|'<='|'>='|'=='|'!=')
;

comparison
@init{boolean secondpart = false;}
:
e=addition (operator {secondpart=true;} k=addition)* 
-> {secondpart}? ^(COMPARISON ^(VALUES addition*) ^(OPERATORS operator*))
-> $e
;

//Right now what this does is:
tree=(COMPARISON (VALUES (INTEGERVALUE (VALUE 1)) (INTEGERVALUE (VALUE 2)) (INTEGERVALUE (VALUE 3)) (INTEGERVALUE (VALUE 4)) (INTEGERVALUE (VALUE 5))) (OPERATORS < < < <))



//The label for the CONJUNCTION TreeNode that i would like to use:
fragment CONJUNCTION:;  

1 个答案:

答案 0 :(得分:0)

通过编写实际的树构建java代码,我想出了一个讨厌的解决方案:

grammar testgrammarforcomparison;

options {
  language = Java;
  output = AST;
}

tokens
{
 CONJUNCTION;
 COMPARISON;
 OPERATOR;
 ADDITION;
}


WS
:
    ('\t' | '\f' | ' ' | '\r' | '\n' )+
    {$channel = HIDDEN;}
;

comparison
@init 
{ 
  List<Object> additions = new ArrayList<Object>();
  List<Object> operators = new ArrayList<Object>();
  boolean secondpart = false;
}
:
(( e=addition {additions.add(e.getTree());} ) ( op=operator k=addition {additions.add(k.getTree()); operators.add(op.getTree()); secondpart = true;} )*) 
{
  if(secondpart)
  {
      root_0 = (Object)adaptor.nil();

            Object root_1 = (Object)adaptor.nil();
            root_1 = (Object)adaptor.becomeRoot(
            (Object)adaptor.create(CONJUNCTION, "CONJUNCTION")
            , root_1); 

      Object lastaddition = additions.get(0);

            for(int i=1;i<additions.size();i++)
      {
        Object root_2 = (Object)adaptor.nil();
        root_2 = (Object)adaptor.becomeRoot(
        (Object)adaptor.create(COMPARISON, "COMPARISON")
        , root_2); 

        adaptor.addChild(root_2, additions.get(i-1)); 
        adaptor.addChild(root_2, operators.get(i-1));
        adaptor.addChild(root_2, additions.get(i)); 

        adaptor.addChild(root_1, root_2);
      }
  adaptor.addChild(root_0, root_1);
  }
  else
  {
   root_0 = (Object)adaptor.nil();
   adaptor.addChild(root_0, e.getTree());
  }
}
;
/** lowercase letters */
fragment LOWCHAR
:   'a'..'z';
/** uppercase letters */
fragment HIGHCHAR
:   'A'..'Z';
/** numbers */
fragment DIGIT
:   '0'..'9';

fragment LETTER
: LOWCHAR
| HIGHCHAR
;

IDENTIFIER
:
 LETTER (LETTER|DIGIT)*
;

addition
:
 IDENTIFIER ->^(ADDITION IDENTIFIER)
;

operator 
:
 ('<'|'>') ->^(OPERATOR '<'* '>'*)
;

parse
:
 comparison EOF
;

输入

"DATA1 < DATA2 > DATA3" 

输出树,例如:

enter image description here

如果你们知道更好的解决方案,请告诉我有关它们的信息