2012-07-01 19 views
5

オペレーターがMenhirパーサー(Ocamlyaccに似ています)を使用して動的属性(優先順位と優先順位)を持つ言語を解析しようとしています。レキシングフェーズでは、すべての演算子がOP:stringトークンを埋めます(したがって、 "+"は(OP "+")などになります)。Menhir/Ocamlyaccの演算子の動的優先順位と優先順位の指定

演算子の属性は、解析時に決定され、演算子とその属性を関連付けるテーブルを埋めます。このテーブルが与えられると、このテーブルのデータに基づいて演算子を解析するルールの優先順位を動的に変更するようにMenhirに指示するにはどうすればよいですか?

ありがとう、 CharlieP。

答えて

10

「あなたは間違っている」という意見には申し訳ありません。私は願っています3人の異議が関連性の順に、建設されているがあります。

  1. 立石は、動的文法の更新のためのものではありません。解析時に文法を変更することを主張する場合は、GLRパーサーDypgenなどのこの機能を提供するツールを使用する必要があります。 Dypgenのマニュアルでは、オペレータの優先順位を動的に更新する可能性について言及しています(新しいオペレータと対応する優先順位を追加できますが、既存の優先順位を変更することはできません)。 Dypgen manual (PDF)の6.6節、ページ42 ...

  2. 動的にCFG文法を更新するのは、ユーザー定義の演算子の優先順位を処理する最良の方法ではないと私は考えています。 Agdaには非常に一般的なユーザ定義のmixfix演算子があり、その解決方法は大まかに以下の通りです:CFGパーサを使って静的に知られている文法構造を解析しますが、おそらくファンシーな優先順位と関連性を使用する式の場合、トークン。たとえば、let x = if foo then x + y * z else barは、Let(x, If(foo, Expr(x, +, y, *, z), bar)のようなものに解析されます。後で特殊化されたパスは、それらの特殊な構造にノードを後で解析するために必要な情報を集めることができます。パーサージェネレータを使用して(静的に知られている豊富なCFG)、複雑で不明瞭な動的な処理のための後処理パスを使用します。 Parsing Mixfix Operators、DanielssonとNorell、2009年。

    デザインの観点から、私はあなたのレキシングとパースをいくつかの異なるパスで分けることを強くお勧めします。独自の振る舞いを動的に変更しようとするのではなく、以前の構造で収集された情報のみを使用します。はるかに簡単で、はるかに堅牢なものがあります。

  3. 動的またはユーザー定義の優先順位と優先順位は、私の意見では少し悪です。 OCamlは、オペレータの優先順位の優先順位が最初の数文字(たとえば、@,@@および@+)がすべて右結合である別のシステムを持っています。中断演算子を選択する人には少し制限がありますが、コードリーダーは、新しいコードに目を動的に適応させるのではなく、学習する一連の文法ルールしか持たないため、はるかに快適です。 。まったく異なる構文を持つ野生の異種コードを挿入したい場合は、引用符の仕組み(例:camlp4 <:foo<...>>)は、演算子レベルの関連性や優先順位で操作するよりはるかに堅牢であり、解析するのがはるかに簡単です。

    しかし、プロジェクトにはさまざまなニーズがあります。わからないアプリケーションでは、演算子の優先順位や関連性を動的に変更することを主張しているかどうかは完全に理解できます。周囲の唯一の方法ではなく、時には一貫性とシンプルさが絶対的な柔軟性より優れていることに留意してください。