0

完全な YACC 文法がすでにあるとします。たとえば、C の文法を考えてみましょう。ここで、完全な C 型宣言を解析する必要があることを除いて、単純な文法でドメイン固有言語用の別のパーサーを作成したいと考えています。関連する処理コードを使用して元の文法から長いルールを複製したくはありませんが、代わりに元のパーサーを呼び出して、1 つのルールだけを処理したいと考えています (「宣言子」と呼びましょう)。

もしそれが再帰的降下パーサーであるなら、簡単に呼び出すことができる各ルールのための関数があるでしょう。

4

1 に答える 1

4

基本的に、いいえ。LR 文法を作成するのは簡単ではなく、bison はあまり役に立ちません。

しかし、すべてが失われるわけではありません。文法全体 (%start宣言を除く) を含め、その一部を使用することを妨げるものは何もありません。

それがあなたにとってショーストッパーである場合は、トリックを使用して、複数の開始規則を持つ文法を作成できるようにすることができます。実際、パーサーを呼び出すたびに開始記号を指定できる文法を作成できます。焼き込む必要さえありません。その後、それをライブラリに押し込んで、必要なパーサーを使用できます。

もちろん、これには代償も伴います。その代償は、パーサーが必要以上に大きくなることです。ただし、速度が遅くなったり、少なくともそれほど遅くなったりすることはありません。キャッシュの影響がある可能性があります。余分なサイズは、コンパイラの残りの部分と比較しておそらく重要ではありません。

ハックについてはbison FAQにかなり詳細に説明されているので、ここで概要を説明します: サポートしたい開始プロダクションごとに、疑似トークン (つまり、レクサーによって生成されることのない字句コード)。たとえば、次のようにします。

%start meta_start
%token START_C START_DSL

meta_start: START_C c_start | START_DSL dsl_start;

あとは、最初の起動時にレクサーが適切な START トークンを生成するように調整するだけです。それにはさまざまな方法があります。FAQ ではグローバル変数の使用が提案されていますが、再入可能なフレックス スキャナーを使用する場合は、目的の開始トークンをスキャナー状態にするだけです (開始トークンが送信されたときに設定されるフラグと共に)。

于 2013-05-09T06:24:41.987 に答える