2

'^'と'!'を使用する必要があることを読みました ANTLR Worksに表示されるものと同様の解析ツリーを構築するための演算子(ANTLR Worksで適切なツリーを取得するために演算子を使用する必要はありませんが)。それでは、私の質問は、どうすればそのようなツリーを構築できるかということです。abc abc1232つの演算子と書き直しを使用したツリー構築に関するページをいくつか見てきましたが、入力文字列と文法があると言っています。

grammar test;

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

ID : LETTER (LETTER | NUMBER)* ;
LETTER : 'a' .. 'z' | 'A' .. 'Z' ;
NUMBER : '0' .. '9' ;

ANTLRWorksは以下を出力します:

ANTLRWorksインタープリター出力

私が理解していないのは、このツリーの上に「idList」ノードを取得する方法です(実際のところ、文法ノードも同様です)。リライトとそれらの演算子を使用してこのツリーを再現するにはどうすればよいですか?

4

1 に答える 1

2

私が理解していないのは、このツリーの上に「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';

上記のデモを実行すると、コンソールに次のように出力されます。

IdList
    Id
        abc
    Id
        abc123

ご覧のとおり、レクサールールと同様に、架空のトークンも大文字で始める必要があります。text架空のトークンに、それらが表すパーサールールと同じものを与えたい場合は、代わりに次のようにします。

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

印刷されます:

idList
    id
        abc
    id
        abc123
于 2012-04-12T06:23:22.700 に答える