如何构建ANTLR Works样式的解析树?

如何构建ANTLR Works样式的解析树?,antlr,antlr3,Antlr,Antlr3,我读到你需要使用“^”和“!”运算符,以构建类似于ANTLR Works中显示的解析树(即使您不需要使用它们在ANTLR Works中获得一个漂亮的树)。那么我的问题是,我怎样才能建造这样一棵树呢?我看过几页关于使用两个运算符和重写的树构造的文章,但我说我有一个输入字符串abc abc123和一个语法: grammar test; program : idList; idList : id* ; id : ID ; ID : LETTER (LETTER | NUMBER)* ; LETTE

我读到你需要使用“^”和“!”运算符,以构建类似于ANTLR Works中显示的解析树(即使您不需要使用它们在ANTLR Works中获得一个漂亮的树)。那么我的问题是,我怎样才能建造这样一棵树呢?我看过几页关于使用两个运算符和重写的树构造的文章,但我说我有一个输入字符串
abc abc123
和一个语法:

grammar test;

program : idList;
idList : id* ;
id : ID ;

ID : LETTER (LETTER | NUMBER)* ;
LETTER : 'a' .. 'z' | 'A' .. 'Z' ;
NUMBER : '0' .. '9' ;
ANTLR工程将输出:


我不明白的是,如何在这棵树的顶部找到“idList”节点(事实上也是语法节点)。如何使用重写和那些运算符来复制此树

我不明白的是,如何在这棵树的顶部找到“idList”节点(事实上也是语法节点)。如何使用重写和那些运算符来复制此树

您不能使用
^
单独。这些操作符仅对现有令牌进行操作,而您希望创建额外的令牌(并使它们成为子树的根)。你可以用电脑来做

快速演示:

grammar test;

options {
  output=AST;
  ASTLabelType=CommonTree;
}

tokens {
  IdList;
  Id;
}

@parser::members {

  private static void walk(CommonTree tree, int indent) {
    if(tree == null) return;
    for(int i = 0; i < indent; i++, System.out.print("    "));
    System.out.println(tree.getText());
    for(int i = 0; i < tree.getChildCount(); i++) {
      walk((CommonTree)tree.getChild(i), indent + 1);
    }
  }

  public static void main(String[] args) throws Exception {
    testLexer lexer = new testLexer(new ANTLRStringStream("abc abc123"));
    testParser parser = new testParser(new CommonTokenStream(lexer));
    walk((CommonTree)parser.program().getTree(), 0);
  }
}

program : idList EOF -> idList;
idList  : id*        -> ^(IdList id*);
id      : ID         -> ^(Id ID);

ID    : LETTER (LETTER | DIGIT)*;
SPACE : ' ' {skip();};

fragment LETTER : 'a' .. 'z' | 'A' .. 'Z';
fragment DIGIT  : '0' .. '9';
正如您所看到的,虚构的标记也必须以大写字母开头,就像lexer规则一样。如果您想赋予假想标记与其表示的解析器规则相同的
text
,请执行以下操作:

idList  : id*        -> ^(IdList["idList"] id*);
id      : ID         -> ^(Id["id"] ID);
将打印:

idList
    id
        abc
    id
        abc123

谢谢你如此深入的回答。无论出于什么原因,我都无法从文档中获得这些信息。
idList
    id
        abc
    id
        abc123