【问题标题】:ANTLR tree parser grammar rewrite rule for *ANTLR 树解析器语法重写规则 *
【发布时间】:2012-10-24 20:27:27
【问题描述】:

我有一个树语法,部分语法如下所示

transitions
    :'transitions' '=' INT ('(' INT ',' INT ')') + ';' -> ^(TRANSITIONS INT INT INT*)
    ;

这里是树解析器语法的相应部分,

transitions
    :^(TRANSITIONS INT INT INT*)
    {System.out.println("");}
    ;

我使用了 + rewrite 规则,这基本上是 repitition。在上面的语法中,用户输入最少 3 个整数值,比如说 一种可能的输入,

  transitions 1 (5,0)

第二个可能的输入

transitions 2 (5,0) (5,1)

第三种可能的输入

transitions 3 (5,0) (5,1) (5,2)

等等。
第一个整数决定了有多少对整数。问题是如何在解析器语法中访问这些整数输入,以及如何在上面的 println 语句中打印它们?

我写的完整语法请参考我的问题ANTLR java test file can't create object of tree grammar

【问题讨论】:

    标签: java antlr dsl parser-generator


    【解决方案1】:

    我建议您将数字“对”保留在单独的规则中:

    解析器语法

    transitions
     : 'transitions' '=' INT pair+ ';' -> ^(TRANSITIONS INT pair+)
     ;
    
    pair
     : '(' INT ',' INT ')' -> ^(PAIR INT INT)
     ;
    

    树语法

    transitions
     : ^(TRANSITIONS INT pair+) {System.out.println("transitions.INT=" + $INT.text);}
     ;
    
    pair
     : ^(PAIR a=INT b=INT) {System.out.println("pair=" + $a.text + ", " + $b.text);}
     ;
    

    编辑

    快速演示:

    grammar T;
    
    options {
      output=AST;
      ASTLabelType=CommonTree;
    }
    
    tokens {
      TRANSITIONS;
      PAIR;
    }
    
    parse
     : transitions EOF!
       {
         CommonTree root = $transitions.tree;
    
         int count = root.getChildCount();
    
         Tree child1 = root.getChild(0);
         Tree child2 = root.getChild(1);
         Tree child3 = root.getChild(2);
         Tree child4 = root.getChild(3);
    
         System.out.println("root=" + root.getToken().getText() + " has " + count + " child nodes:");
         System.out.println(" - child1=" + child1.toStringTree());
         System.out.println(" - child2=" + child2.toStringTree());
         System.out.println(" - child3=" + child3.toStringTree());
         System.out.println(" - child4=" + child3.toStringTree());
    
         String secondValueFromLastPair = child4.getChild(1).getText();
         System.out.println("\nsecondValueFromLastPair=" + secondValueFromLastPair);
       }
     ;
    
    transitions
     : 'transitions' '=' INT pair+ ';' -> ^(TRANSITIONS INT pair+)
     ;
    
    pair
     : '(' INT ',' INT ')' -> ^(PAIR INT INT)
     ;
    
    INT   : '0'..'9'+;
    SPACE : ' ' {skip();};
    

    如果您现在解析输入 "transitions = 3(5,0) (5,1) (5,2);",您会看到控制台打印出以下内容:

    root=TRANSITIONS 有 4 个子节点:
     - 孩子1=3
     - child2=(对 5 0)
     - child3=(对 5 1)
     - child4=(对 5 1)
    
    secondValueFromLastPair=2

    【讨论】:

    • 一件事,我想问一下,^(PAIR a=INT b=INT) a 和 b 是标签吗?是的,它工作正常,但如果我给出以下输入,比如说。转换 = 3(5,0) (5,1) (5,2);我将如何存储它以便我的 AST 包含 PAIR0 = (5,0) PAIR1 = (5,1) PAIR2 = (5,2)
    • @RizwanAbbasi,它已经这样存储了。 transitions 规则产生一个 CommonTree 类型的 AST,其根为 TRANSITIONS 并将有 4 个子节点(也是 CommonTree 的):一个 INT 和 3 个 PAIR 节点。
    • 如果我打印 AST,我得到,(PROT test) (INITIALP 5) (PROC 4) (TRANSITIONS 3 (PAIR 5 0) (PAIR 5 1) (PAIR 5 2)) 你可以看到我无法区分成对。在上面的java代码中(你打印的地方),我将如何以以下方式访问整数(不知何故)PAIR0(g0,a0)PAIR1(g1,a1)PAIR2(g2,a2)谢谢
    • @RizwanAbbasi,当然你可以:树是(TRANSITIONS 3 (PAIR 5 0) (PAIR 5 1) (PAIR 5 2)),所以根TRANSITIONS的AST有4个子节点:3(PAIR 5 0)(PAIR 5 1)和@987654336 @。现在您需要做的就是查看 API 以了解如何获取节点的子节点(提示:我在之前的评论中发布了指向 CommonTree API 的链接)。祝你好运。
    • 非常感谢您的支持。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    相关资源
    最近更新 更多