java - 在 antlr 中,有没有办法在 AST 模式下获取 CommonTree 的解析文本?

标签 java antlr

一个简单的例子:

(grammar):

stat: ID '=' expr NEWLINE -> ^('=' ID expr)

expr: atom '+' atom -> ^(+ atom atom)

atom: INT | ID

...

(input text): a = 3 + 5

“3 + 5”对应的 CommonTree 包含一个“+”标记和两个 child (3, 5)。

此时,恢复解析为这棵树 ('3 + 5') 的原始输入文本的最佳方法是什么?

我在 CommonTree 对象中得到了文本、位置和各个标记的行号,因此理论上可以确保仅丢弃空白标记并使用此信息将它们拼凑在一起, 但它看起来容易出错。

有更好的方法吗?

最佳答案

Is there a better way to do this?

更好,我不知道。当然, 还有另一种方法。您决定什么更好。

另一种选择是创建自定义 AST 节点类(和相应的节点适配器)并在解析期间将匹配的文本添加到该 AST 节点。这里的技巧是不使用 skip(),它会从词法分析器中丢弃标记,而是将其放在 HIDDEN channel 中。这实际上是相同的,但是,这些(隐藏的)标记匹配的文本在解析器中仍然可用。

快速演示:将所有这 3 个文件放在名为 demo 的目录中:

演示/T.g

grammar T;

options {
  output=AST;
  ASTLabelType=XTree;
}

@parser::header {
  package demo;
  import demo.*;
}

@lexer::header {
  package demo;
  import demo.*;
}

parse
 : expr EOF -> expr
 ;

expr
@after{$expr.tree.matched = $expr.text;}
 : Int '+' Int ';' -> ^('+' Int Int)
 ;

Int
 : '0'..'9'+
 ;

Space
 : ' ' {$channel=HIDDEN;}
 ;

演示/XTree.java

package demo;

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;

public class XTree extends CommonTree {

  protected String matched;

  public XTree(Token t) {
    super(t);
    matched = null;
  }
}

演示/Main.java

package demo;

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;

public class Main {

  public static void main(String[] args) throws Exception {
    String source = "12    +  42 ;";
    TLexer lexer = new TLexer(new ANTLRStringStream(source));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.setTreeAdaptor(new CommonTreeAdaptor(){
      @Override
      public Object create(Token t) {
        return new XTree(t);
      }
    }); 
    XTree root = (XTree)parser.parse().getTree();
    System.out.println("tree    : " + root.toStringTree());
    System.out.println("matched : " + root.matched);    
  }
}

您可以通过打开 shell 并 cd-ing 到包含 demo 目录的目录并执行以下命令来运行此演示:

java -cp demo/antlr-3.3.jar org.antlr.Tool demo/T.g
javac -cp demo/antlr-3.3.jar demo/*.java
java -cp .:demo/antlr-3.3.jar demo.Main

这将产生以下输出:

tree    : (+ 12 42)
matched : 12    +  42 ;

关于java - 在 antlr 中,有没有办法在 AST 模式下获取 CommonTree 的解析文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12941718/

相关文章:

java - Log4J SQL 日志记录 TopLink

java - 为什么这个 `printf` 格式的表的第一行没有对齐?

Java - 从应用程序刷新打开的 html 页面

parsing - ANTLR 与预煮

Antlr 生成的文件

java - antlr4 - 如何实现递归

java - 使用字符串的二叉树,而不是插入所有字符串。有些失踪了

java - Android 正确清理/处置

antlr - Antlr 3.2重写规则

C# asp.net 支持一个dll的多个版本