当前位置: 首页 > 知识库问答 >
问题:

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

仲孙飞文
2023-03-14
"1<2<3<4<5" 
CONJUNCTION(COMPARISON(1,2,<) COMPARISON(2,3,<) COMPARISON(3,4,<) COMPARISON(4,5,<))

在Antlr3树重写规则中有没有一种方法来迭代匹配的令牌,并用目标语言(我使用的是java)从它们创建结果树?所以我可以从匹配的“addition”标记的元素x,x-1中生成比较节点。我知道我可以引用一个规则的最后一个结果,但那样我只能得到嵌套的比较规则,这不是我想要的。

/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个答案

曾丰茂
2023-03-14

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

此输出树,例如:

 类似资料:
  • 我的讲师给了我一个任务,让我创建一个程序,使用堆栈将表达式和中缀转换为后缀。我制作了堆栈类和一些函数来读取中缀表达式。 但是这个函数,叫做,它负责使用堆栈将数组inFix中的inFix表达式转换为数组postFix中的postfix表达式,并没有做它应该做的事情...你们能帮帮我告诉我哪里做错了吗? 下面是从中缀转换为后缀的函数的代码,是我需要帮助修复的代码: 注意:convertToPostfi

  • 问题内容: 在《 OCP学习指南 》一书中,有一个关于比较器的示例,可以通过两种方式对其进行初始化。首先是通过这样的匿名类: 这我能理解。根据这本书,可以将其替换为以下lambda表达式: 现在,我不明白。lambda表达式不会返回Comparator对象,因为Comparator是一个接口,所以我现在想到了它。 那么,第一个示例中的运算符是否引用正在创建的称为Comparator的匿名类,因为该

  • 我正在为我的一堂计算机科学课开发一个计算后缀表达式结果的程序。该程序使用堆栈ADT来实现这一点。 我已经编写了程序,但相信可能会有错误,因为一些表达式的结果不正确。我不确定我的错误在哪里。 此外,当输入文件为空时,程序将生成一个值32767。那是从哪里来的? 表达式:34+3*值=21。 主程序:

  • 我正在寻找一个JAVA库来解析 我的要求: 支持所有的值类型(例如int,双,布尔,String等) 支持所有已知的数学 有什么建议吗?

  • 任务是实现一个通用堆栈(不能使用java中的库),使用true和false为布尔b1和b2输入表达式,逻辑运算符(and,or,not,iff,implies)识别其布尔or运算符并发送到2个堆栈,然后弹出堆栈以评估其是否为有效表达式,即:输入:(b1和b2)意味着b3是一个有效的表达式,但b3和(b2 or)不是,我对堆栈部分有问题,因为peek没有返回任何元素,这是我到目前为止的代码,注意:字

  • 我对thymeleaf是新手,不明白这个错误。