9
// Create a scanner that reads from the input stream passed to us
 CSLexer lexer = new CSLexer(new ANTLRFileStream(f));
tokens.TokenSource = lexer;

// Create a parser that reads from the scanner
CSParser parser = new CSParser(tokens);

// start parsing at the compilationUnit rule
CSParser.compilation_unit_return x = parser.compilation_unit();
object ast = x.Tree;

ルート、クラス、メソッドなどを抽出するために、compile_unit_return タイプの x を使用して何ができますか? そのアダプタを抽出する必要がありますか? それ、どうやったら出来るの?Compilation_unit_return は私の CSParser でそのように定義されていることに注意してください (これは ANTLR によって自動的に生成されます):

public class compilation_unit_return : ParserRuleReturnScope
    {
        private object tree;
        override public object Tree
        {
            get { return tree; }
            set { tree = (object) value; }
        }
    };

ただし、取得しているツリーはオブジェクト型です。デバッガーを使用して実行したところ、BaseTree タイプであることがわかりました。しかし、BaseTree はインターフェースです。それが BaseTree とどのように関係しているかはわかりませんし、このツリーから詳細を抽出する方法もわかりません。

クラス、メソッド、変数などにアクセスするビジターを作成する必要があります。ParserRuleReturn クラスは RuleReturnScope から拡張され、開始オブジェクトと停止オブジェクトを持ちますが、それが何であるかはわかりません。

さらに、ANTLR が提供するこの TreeVisitor クラスがありますが、これは紛らわしく見えます。コンストラクターにパラメーターとしてアダプターを渡す必要があります (そうでない場合は、デフォルトの CommonTreeAdaptor を使用します)。これが、以前にアダプターを取得する方法について尋ねた理由です。そして他の問題も。API については、 http://www.antlr.org/api/CSharp/annotated.htmlを参照できます。

4

3 に答える 3

6

次のように、ファイルの先頭にある文法オプションで AST ツリー タイプを設定できます。

tree grammar CSharpTree;
options { 
    ASTLabelType = CommonTree
}

3 番目の文法を構築するか、それを既存のパーサー文法に組み込み、ツリーを作成したクラスに変換します。たとえば、プラス演算子に一致するルールがあり、それが 2 つの引数であるとします。作成したクラスを作成するツリーに一致するルールを定義できます。これを次のように PlusExpression と呼びましょう。

plusExpr returns [PlusExpression value]
   : ^(PLUS left=expr right=expr) { $value = new PlusExpression($left.value, $right.value); }

expr は、文法一致式の別のルールになります。left と right は、ツリーの値に与えられた単なるエイリアスです。{ } の間の部分は、変数参照を置き換えることを除いて、ほぼそのまま C# コードに変換されています。$left と $right の .value プロパティは、それらが作成されたルールから指定された戻り値から取得されます。

于 2009-08-30T02:35:20.803 に答える
3

私はC#からANTLRを使用したことはありませんが、APIへのリンクをたどると、BaseTree明らかにインターフェースではありません-それはクラスであり、パブリックプロパティがあります:Typeノードのタイプを取得し、Text対応するソーステキストを取得します(私は仮定します)それに、Children子ノードを取得します。それを歩くために他に何が必要ですか?

于 2009-08-18T00:32:45.413 に答える
-2

今日C#コンパイラを作成する場合は、次のようにします。行う最初の試みとして試してください:

  1. ANTLR C#3ターゲットから始めます(もちろん、ここでは偏見があります。真剣に、CSharp2またはCSharp3ターゲットのいずれかを使用できます)。
  2. .NET Framework4を使用してVisualStudio2010を入手します。ここで重要なのは.NET4であり、これは新しい式ツリーです。
  3. 基本的な複合パーサーを作成します。パーサーにロジックをできるだけ少なくします。アクションは(あるとしても)ほとんどなく、出力はLL(1)ウォーカーで歩くことができる装飾されていないASTである必要があります。
  4. ツリーを歩き、宣言されたすべてのタイプを識別するためのツリー文法を作成します。またmember_declaration、後で使用するためにサブツリーを保持する必要があります。
  5. シングルを歩きmember_declaration、メンバーをに追加するツリーウォーカーを作成しTypeBuilderます。メソッド本体を追跡しますが、まだ深く歩かないでください。
  6. メソッドの本体を歩くツリーウォーカーを作成します。Expression<TDelegate>一致するメソッドを生成し、CompileToMethodメソッド_ILコードを生成するための独自のAPI(Pavelと私のコメントを参照)。

この順序で処理を行うと、最終的に式(メソッド本体、フィールド初期化子)を解析するときに、クラスでこのようなstringパラメーター化されたメソッドを使用して、作業解決メンバーを保存できます。Expression

于 2009-08-18T00:41:16.417 に答える