10

ペットプロジェクトのために、私はANTLRをいじり始めました。いくつかのチュートリアルに従った後、私は今、自分の言語の文法を作成し、ASTを生成しようとしています。

今のところ、私はほとんどANTLRWorksをいじっていますが、解析ツリーが正常であるように見えることを検証したので、(繰り返しますが、まだ学習中であり、最終的な構造に関していくつかの決定を行う必要があるためです)ツリーの)ASTを作成します。antlrworksはそれを視覚化しないようです(または少なくとも「インタープリター」機能を使用していない、デバッグは私のどのマシンでも機能していません)。

結論:ASTを手動で視覚化する唯一の方法は、ASTをトラバース/表示するか、ツリーを文字列表現でコンソールに印刷することですか?

私が探しているのは、入力、文法->ANTLRWorksの「インタープリター」機能による視覚的なAST表現から簡単に移動する方法です。何か案は?

4

2 に答える 2

17

正解です。インタープリターは、解析プロセスで使用されるルールのみを表示し、AST 書き換えルールは無視します。

あなたができることは、 Graphviz DOT-fileStringTemplateを作成するために使用することです。このようなDOT ファイルを作成した後、サードパーティ製のビューアを使用してこのツリー (グラフ) を表示します。

これは Java の簡単なデモです (私は C# をほとんど知りません。申し訳ありません)。

AST を生成する次の (過度に単純化された) 式の文法を取り上げます。

grammar ASTDemo;

options { 
  output=AST; 
}

tokens {
  ROOT;
  EXPRESSION;
}

parse
  :  (expression ';')+ -> ^(ROOT expression+) // omit the semi-colon
  ;

expression
  :  addExp -> ^(EXPRESSION addExp)
  ;

addExp
  :  multExp
     ( '+'^ multExp
     | '-'^ multExp
     )*
  ;

multExp
  :  powerExp
     ( '*'^ powerExp
     | '/'^ powerExp
     )*
  ;

powerExp
  :  atom ('^'^ atom)*
  ;

atom
  :  Number
  |  '(' expression ')' -> expression // omit the parenthesis
  ;

Number
  :  Digit+ ('.' Digit+)?
  ;

fragment
Digit
  :  '0'..'9'
  ;

Space
  :  (' ' | '\t' | '\r' | '\n') {skip();}
  ;

まず、ANTLR にレクサー ファイルとパーサー ファイルを生成させます。

java -cp antlr-3.2.jar org.antlr.Tool ASTDemo.g 

次に、式を解析してDOT ファイル"12 * (5 - 6); 2^3^(4 + 1);"を出力する小さなテスト ハーネスを作成します。

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

public class MainASTDemo {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream("12 * (5 - 6); 2^3^(4 + 1);");
        ASTDemoLexer lexer = new ASTDemoLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ASTDemoParser parser = new ASTDemoParser(tokens);
        ASTDemoParser.parse_return returnValue = parser.parse();
        CommonTree tree = (CommonTree)returnValue.getTree();
        DOTTreeGenerator gen = new DOTTreeGenerator();
        StringTemplate st = gen.toDOT(tree);
        System.out.println(st);
    }
}

.javaすべてのファイルをコンパイルします。

// *nix & MacOS
javac -cp .:antlr-3.2.jar *.java

// Windows
javac -cp .;antlr-3.2.jar *.java

次に、メイン クラスを実行し、その出力を次の名前のファイルにパイプしますast-tree.dot

// *nix & MacOS
java -cp .:antlr-3.2.jar MainASTDemo > ast-tree.dot

// Windows
java -cp .;antlr-3.2.jar MainASTDemo > ast-tree.dot

ファイルには次のast-tree.dotものが含まれています。

digraph {

    ordering=out;
    ranksep=.4;
    bgcolor="lightgrey"; node [shape=box, fixedsize=false, fontsize=12, fontname="Helvetica-bold", fontcolor="blue"
        width=.25, height=.25, color="black", fillcolor="white", style="filled, solid, bold"];
    edge [arrowsize=.5, color="black", style="bold"]

  n0 [label="ROOT"];
  n1 [label="EXPRESSION"];
  n1 [label="EXPRESSION"];
  n2 [label="*"];
  n2 [label="*"];
  n3 [label="12"];
  n4 [label="EXPRESSION"];
  n4 [label="EXPRESSION"];
  n5 [label="-"];
  n5 [label="-"];
  n6 [label="5"];
  n7 [label="6"];
  n8 [label="EXPRESSION"];
  n8 [label="EXPRESSION"];
  n9 [label="^"];
  n9 [label="^"];
  n10 [label="^"];
  n10 [label="^"];
  n11 [label="2"];
  n12 [label="3"];
  n13 [label="EXPRESSION"];
  n13 [label="EXPRESSION"];
  n14 [label="+"];
  n14 [label="+"];
  n15 [label="4"];
  n16 [label="1"];

  n0 -> n1 // "ROOT" -> "EXPRESSION"
  n1 -> n2 // "EXPRESSION" -> "*"
  n2 -> n3 // "*" -> "12"
  n2 -> n4 // "*" -> "EXPRESSION"
  n4 -> n5 // "EXPRESSION" -> "-"
  n5 -> n6 // "-" -> "5"
  n5 -> n7 // "-" -> "6"
  n0 -> n8 // "ROOT" -> "EXPRESSION"
  n8 -> n9 // "EXPRESSION" -> "^"
  n9 -> n10 // "^" -> "^"
  n10 -> n11 // "^" -> "2"
  n10 -> n12 // "^" -> "3"
  n9 -> n13 // "^" -> "EXPRESSION"
  n13 -> n14 // "EXPRESSION" -> "+"
  n14 -> n15 // "+" -> "4"
  n14 -> n16 // "+" -> "1"

}

ここのビューアの 1 つで見ることができます。オンライン視聴者もいます。これを例に取ります: https://dreampuf.github.io/GraphvizOnline/

のコンテンツをフィードするとast-tree.dot、次の画像が生成されます。

アストツリー

于 2010-05-18T13:11:28.780 に答える
-1

ANTLRWorks インタープリターが機能するには、ターゲット言語を Java に変更する必要があります。少なくとも、それは私が観察したことです。

于 2010-05-18T12:21:12.330 に答える