【问题标题】:Parse stacked comparison expression into logical Conjunction Tree with antlr3使用 antlr3 将堆叠比较表达式解析为逻辑合取树
【发布时间】:2014-01-05 20:10:49
【问题描述】:

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

"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:;  

【问题讨论】:

  • 不清楚你在问什么。

标签: parsing tree antlr3


【解决方案1】:

我通过编写实际的树构建 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" 

这个输出树如:

如果你们知道更好的解决方案,请告诉我

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多