2012-03-06 3 views
1

私はLex/Bisonを使用して、C言語に変換する簡単なスクリプト言語を作成しています。トランスコンパイラ。Bisonはスコープと構文を検証できますか?

私はBisonが構文を検証できることは知っていますが、スコープはどうですか?以前に使用されていた識別子が宣言されていることを確認できますか?手動で行う必要がありますか?もしそうなら、どのステップ?

など。これは構文上正しいものです。 メッセージが間違った範囲にあるので、をコンパイルしないでください。さらに、message2は決して宣言されませんでした。

String s1 
if (s1=='knock on door') 
    String message1='Hello'; 

print message1; 
print message2; 

答えて

1

一般に、パーサー(ただし生成される)はスコープ規則をチェックすることはできません。

一般的にスコープチェックを行うには、AST全体を構築して、識別子のスコープが有効であることを確認する必要があります。 の範囲でスタティックスコープを使用する言語の場合、変数を使用する前に、ルールでフライのみを実行できます。名前空間を持つ言語の場合、名前空間宣言はどこにでも発生する可能性があり、その名前空間、つまりプログラム全体を収集することなく実行することはできません。 (ネームスペース宣言は、使用するファイルと同じファイルではないかもしれません;今ではまったく別のファイルを解析しています)。

結果的に、スコープチェックが行われる通常の方法は、プログラムツリー上の解析後です。通常、構文解析以外のことをする場合は、ツリーと完全なシンボルテーブルが必要です。したがって、これはあまり煩わしいことではありません。

一部の初期のコンパイラでは、ツリー全体をメモリに保持するという贅沢さはありませんでした。使用前にスコープ宣言を持つ言語を持っていたか、複数のパスで実装されていましたか。

+0

一部の言語では、パーサーがその情報を参照することなく動作できないため、ASTを使用するまでスコープを延期することはできません。これは何ですか: X(Y);/* CまたはC++ */ これは関数呼び出しですか? YはXに渡されますか?または、YがX型であるという宣言ですか? Xが宣言されていることを確認して、それがどのような種類の文法記号であるかを簡単に判断する必要があります。タイプ名、または主要な式(関数または変数)です。 – Kaz

+2

@ Kaz:これはあいまいさを扱うパーサーをうまく設計できない人々が押し付けた民俗定理です。 *構文*のポイントは、解析中に決める必要がないということです。それがいくつかの異なるものであるかもしれないならば、おそらくいくつかの異なるものとしてそれを解析します。後でシンボルテーブルを作成して、受け入れ可能なサブパラメータを選択することができます。当社のCおよびC++フロントエンド(http://www.semanticdesigns.com/Products/FrontEnds/CppFrontEnd)。html)は正確にこのように動作し、うまく動作します。彼らは何百万行ものCおよびC++コードを処理するために使用されてきました。 –

+0

ええ、あなたが簡単に(パーズツリーの前の部分に基づいて)あなたが簡単に知ることができる言語では、魔法のtype_or_variableシンボルを生成しなければならないのではなく、ASTをビルドしている間、 AST全体が構築されたときにどちらのものであるかを判断する必要があります。これは "解析"の定義方法と実装が簡単な方法になります。私の視点からは、部分的に構築されたASTにスキャナを縛るのを避けるために、パーサーの仕事の一部をどこか別の場所に移動しています。 – Edmund

0

Bisonは識別子スコープとルックアップを処理しません。その機能は、ルール操作で提供することができます。

1

答えを見つけました。実際にはセマンティック分析と呼ばれる第3段階があります。手順:

  1. レックス(トークンを取得)
  2. 解析(正しい文脈で使用されることを確認トークンを作る)
  3. 意味解析(型チェック/スコープ)

意味解析は、解析木を解析し、