2016-11-20 4 views
2

私は、リアルタイム言語OpenPEARL用のレクサー/パーサーを実装しています。私のtestsuiteのより良いstruturingのために私はC/C++に似てインクルードファイルの処理を実装したい。それ自体パーサは訪問者を使用します。これを実装する最良の方法は何でしょうか?ネストされたパーサーをインスタンス化する際に私が気になることの1つは、インクルードされたファイルに含まれる場所に応じて完全なプログラムを含む必要はありません。ANTLR4:インクルードファイル処理のようなCを実装するための最善のアプローチは何ですか?

乾杯

マルセル

答えて

3

私はANTLRのために話すが、一般的なものでレクサーでCのようなプリプロセッサを実装することはできません。

これは、スタックの入力ストリームであり、スタックのベースはソースファイルです。スタックの上にあるストリームから入力を読み込みます。

レクサーのインクルードがになると、新しいストリームがスタックの一番上にプッシュされ、読み込みが続けられます(新しいストリームから)。ストリームがEOFに遭遇すると、スタックをポップして続行します。スタックが空の場合、レクサーはEOFトークンを発行します。

これらのストリームを乱用してマクロを実装できます。マクロ呼び出しでは、単にマクロ本体を表す新しいストリームをプッシュします。マクロパラメータ名に遭遇したら、対応するマクロに渡された引数のストリームをプッシュします。

1

私は、(構文解析)文法でインクルード処理が行われている実装を見てきました。アイラのようなレクサーでそれをすることは確かに可能ですが、余分な作業が必要です。

しかし、完全なインクルード処理は、#if(def)コマンドのエバリュエーターとして、入力ストリーム、つまりマクロ処理、ラインスプライシング、トリグラフ処理、チャーティングおよび文字列化を切り替えるだけではありません。私がWindows Resource File Parserに実装しているのは、ANTLR 2.7のために書かれたもので、アップデートが必要ですが、確かにアイデアを得るのに良いものです。

このプロジェクトでは、通常のANTLR解析チェーンの外にあるインクルードファイルを扱います。これは、C/C++でよく見られるプリプロセッサのアプローチに続きます。

+0

どのようにCで動作しますか? #includeディレクティブはどこでも*発生する可能性があります。言語文法にインクルード・ディレクティブが明示的に含まれている場合は、「include_directive」ルールの縮小時にストリーム・スタッキングを行うことができます。 (私のPARLANSEコンパイラ[これを参照してください]バイオ)。私はレクサーベースのものよりもこのアプローチを好んでいます... –

+0

...しかし、プリプロセッサが言語に依存していないとき、私はパーサーでこれをどのように処理するかはわかりません。完全なCと完全なC++フロントエンドを構築します。 *レクサー*は、プリプロセッサー・トークンとストリーム切り替えの基本的な認識を行います。レキシコンとパーサーの間のプリプロセッサ・パスが、プリプロセッサ・ディレクティブの解析(コンプレックス式、文字列化などがある場合) –

+0

まあ、パーサー・アプローチの例は見つかりません。一般的なアプローチに関するディスカッションのみ:https://groups.google.com/forum/#!searchin/antlr-discussion/include|sort:relevance/antlr-discussion/FUQbEtonUlw/zFKdMU9ADAAJそれをレクサー(または私がやったように入力ストリーム)で扱うことはまったく問題ありません。 –

関連する問題