2

私の言語では、定義がメソッドの下に表示されるときに、メソッドでクラス変数を使用できます。また、自分のメソッドなどの下のメソッドを呼び出すこともできます。「ヘッダー」はありません。この C# の例を見てみましょう。

class A
{
    public void callMethods() { print(); B b; b.notYetSeen();
    public void print() { Console.Write("v = {0}", v); }
    int v=9;
}

class B
{
    public void notYetSeen() { Console.Write("notYetSeen()\n"); }
}

それをどのようにコンパイルすればよいですか?私が考えていたのは:

  • pass1: すべてを AST に変換します
  • pass2: すべてのクラスを調べて、define classes/variable/etc のリストを作成します。
  • pass3: コードを調べて、未定義の変数、間違った使用などのエラーがあるかどうかを確認し、出力を作成します

しかし、これが機能するように思えます.pass3を実行する前に、すべてのファイルに対してpass 1と2を実行する必要があります. また、構文エラーが見つかるまで、やるべきことがたくさんあるように感じます (ブレースを閉じるのを忘れたり、16 進値の代わりに 0xLETTERS を書き込んだりするなど、解析時に実行できる明らかなエラーを除きます)。私の腸は、他の方法があると言っています。

注: bison/flex を使用してコンパイラを生成しています。

4

4 に答える 4

3

前方参照を処理する言語についての私の理解では、通常、最初のパスを使用して有効な名前のリストを作成するだけです。テーブルにエントリを配置するだけの行に沿ったもの (定義を入力せずに) であるため、後で実際のパスを実行して定義を生成するときに何かを指すことができます。

実際に完全な定義を作成しようとすると、次のパスまで未定義のものへの参照を保存するたびに、再スキャンを繰り返す必要があります。循環参照があると、それでも失敗します。

于 2009-10-16T15:41:35.507 に答える
1

パス 1 を通過し、メソッド本体を無視して、すべてのクラス/メソッド/フィールド名と型を収集します。次に、パス 2 でメソッド本体のみをチェックします。

于 2009-10-16T15:37:34.907 に答える
0

ソース内のすべてのファイルをトラバースする以外に方法があるかどうかはわかりません。

2 つのパスに分けることができると思います。最初のパスで AST を構築し、変数名を見つけたら、そのブロックのシンボルを含むリストに追加します (そのリストをツリー内の対応するスコープ)。ステップ 2 は、ツリーを直線的にトラバースし、使用される各シンボルがそのスコープまたはその上のスコープ内のシンボルを参照していることを確認することです。

私の説明は単純化されすぎていますが、基本的な答えは -- 先読みには少なくとも 2 つのパスが必要です。

于 2009-10-16T15:47:47.953 に答える
0

通常のアプローチはB、「不明」として保存することです。おそらくある種のタイプです(遭遇した場所のため)。したがって、それが実際に何であるかわからない場合でも、メモリ (ポインター) を予約することができます。

メソッド呼び出しについては、多くのことはできません。動的言語では、メソッドの名前をどこかに保存し、実行時に存在するかどうかを確認するだけです。静的言語では、未知の型とともにコンパイラのどこかに「未知のメソッド」の下に保存できますB。メソッド呼び出しは最終的にメモリ アドレスに変換されるため、再度メモリを予約できます。

そして、その方法に出会ったとき、Bあなたの未知をクリアすることができます。それらについて少し知っているので、それらが本来のように動作するかどうか、または最初の使用が構文エラーであるかどうかを判断できます。

したがって、すべてのファイルを 2 回読み取る必要はありませんが、確実に作業が簡単になります。

または、ソースに遭遇したときにこれらのヘッダー ファイルを生成し、それらを再び見つけられる場所に保存することもできます。このようにして、コンパイルを高速化できます (次のコンパイル実行で変更されていないファイルを考慮する必要がないため)。

最後に、新しい言語を作成する場合は、もう bison と flex を使用しないでください。今ではもっと優れたツールがあります。たとえば、 ANTLRは、エラー後に回復できるパーサーを生成できるため、ファイル全体を引き続き解析できます。または、このウィキペディアの記事でその他のオプションを確認してください。

于 2009-10-16T15:51:48.777 に答える