9

この質問をした後、以前は手動で記述していたパーサー ジェネレーターを使用することに自信が持てるようになりました。

しかし、C++ コードを生成するパーサーも、Unicode を正しく処理するパーサーも見つけることができないようです。(私の入力は UCS-2 にあることに注意してください -- パーサーの構築がより困難になる場合、基本多言語面の外側のビットをサポートすることは気にしません)

C を生成できるパーサーがいくつかありますが、そのようなパーサーはすべて、窓の外に例外安全性をスローしているように見えます。これにより、セマンティック アクション内で C++ を使用できなくなります。

これら 2 つの原則を満たすパーサー ジェネレーターは存在しますか?

編集:ああ、私のプロジェクトはBSLライセンスなので、パーサージェネレーター自体の出力の使用に多くの制限はありません。

4

8 に答える 8

5

C++ には 2 つの方法があります。プログラムを使用して、自由形式またはテンプレートを使用して記述された文法から C++ ファイルを生成します。

テンプレート型で文法を書く場合、2 つの選択肢があります。boost::proto を使用します。すべての演算子は、boost::fusion で構文ツリーを構築するために再定義されます (boost::spirit、boost::msm、boost::xpressive で使用されます)。(基本的なアイデアはここにあります: Expression Templates ) または、独自のテンプレートを使用して手動で記述された式ツリーを構築し、直接 boost::mpl コンテナーに格納します。このテニークはビスケットで使用されます。

あなたが持っているビスケットで

or_<>, seq_<>, char_<>, ..

テンプレート。Biscuit は Yard に基づいていますが、拡張された boost::range によって拡張され、より優れたサブマッチ機能が得られます。

Biscuit パーサー ライブラリ 1

Biscuit パーサー ライブラリ 2

C++ 用の Yet Another Recursive Descent (YARD) 解析フレームワーク

于 2010-12-09T19:27:59.670 に答える
4

さて、これはロングショットかもしれませんが、Qt のサイド プロジェクトとしてパーサー ジェネレーター (LALR) があります。これはQLALRと呼ばれ、非常に薄いレイヤーであり、字句解析はまだあなた次第ですが、すべての作業は QStrings を介して実行できます。ユニコードをサポートします。多くの機能はありません。各トークンに対して作業を行うコードを使用して文法を記述し、パーサーを生成します。しかし、私はそれを使用して、解析された言語の AST を作成し、〜 100 のルールを持つパーサーを正常に生成しました。

于 2010-12-04T15:52:14.680 に答える
1

ANTLRは Unicode をサポートしています。C++ (および C、Java、その他のいくつかの言語) をサポートしていますが、私は C++ サポートを使用したことがないので、それがどれほどよく開発されているかはわかりません。

于 2010-11-30T19:44:24.650 に答える
1

パーサーはトークンを処理するため、文字を気にしません。

Lexing Unicode は非常に高価です。これは、分類のために膨大な関数呼び出しオーバーヘッドを支払うか、大規模なテーブルでメモリを消費するためです。通常、Unicode のみをサポートするのは、文字列リテラルや、手作りの関数が効率的にジョブを実行できる識別子など、PL 内の特定の場所です。

私は以前、ISO C++ 標準 (さまざまな言語で「文字」と見なされる Unicode コード ポイントの範囲のセットを含む) で義務付けられている識別子を受け入れるレクサーを Ocamllex でコーディングしました。コードポイント範囲の数は非常に少ないですが (約 20 程度の範囲)、このための UTF-8 DFA には 64K を超える状態があり、lexer ジェネレーターを爆破しました :)

ここでの私のアドバイスは、レクサーを手作りする必要があるということです。実際、これを非効率的に行うのは非常に簡単です。これを効率的に行うのは非常に困難です。Judy 配列のサポートを検討しています (これは地球上最速のデータ構造です)。

于 2010-12-04T20:48:16.873 に答える
1

実験したい気分なら、これはワイド文字をサポートしていますが、あいまいです: http://wiki.winprog.org/wiki/LibCC_Parse

于 2010-11-30T20:18:43.897 に答える
1

Unicode の予備的なサポートがあるようですboost::spirit

于 2010-11-30T20:13:30.690 に答える
0

私はパーサーに関する理論をあまり知らないので、これが当てはまらない場合はご容赦ください。ただし、Ragel はあります。

Ragelはステート マシンを生成します。Ruby が HTTP リクエストを解析するために Mongrel HTTP サーバーで (おそらく最も有名な?) 使用されます。

Ragel はプレーンな C (とりわけ) をターゲットにしていますが、すべてのステート マシン データは static const またはスタックに割り当てられているため、C++ の例外に関するいくつかの重要な問題が軽減されるはずです。特別な例外処理が必要な場合、Ragel はその内部を公開することを躊躇しません。(聞こえるほど複雑ではありません。)

char入力は任意の基本型の配列であり、通常は、しかしおそらくshortまたはintあなたの場合は、Unicodeが可能であるはずです。そうでない場合は、次の入力項目/トークン/イベントを取得するための独自のメカニズムで配列の繰り返しを置き換えることもできます。

于 2010-12-09T19:44:39.700 に答える
0

Boost.Spiritを試してください。問題のユニコード部分を処理する独自の「ストリームデコーダー」をプラグインできます。Spritを動作させるwchar_tことは可能であるはずですが、私自身は試していません。

于 2010-12-09T15:50:38.860 に答える