4

PPCompositeParser のいくつかのサブクラスで拡張したいプログラミング言語の文法があります (たとえば、あるクラスは命令を処理し、別のクラスは式を処理し、別のクラスはプログラム構造を処理します)。数十のインスタンス変数を持つ大きなクラスを取得しないようにするために、これを行いたいと考えています。

私の問題は、これらのサブ文法には循環的な依存関係があることです: 構造文法は、構造文法の「サブルーチン名」を参照する式文法の「式」規則を参照するステートメント文法の「ステートメント」規則を参照します (依存関係サイクルを閉じます)。たとえば、次のような式文法で #subroutineName メソッドを使用する簡単な方法を試しました。

MyExpressionGrammar>>subroutineName
  ^ N2TJStructureParser newStartingAt: #subroutineName

しかし、それは無限再帰のために初期化に失敗します (明らかに)。

この問題を解決するために、PPDeferedParser を作成しました。

PPParser subclass: #PPDeferedParser
    instanceVariableNames: 'creationBlock'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'PetitParser-Tools'

PPDeferedParser>>parseOn: aStream
    ^ creationBlock value parseOn: aStream

前の #subroutineName は次のようになります。

MyExpressionGrammar>>subroutineName
  ^ PPDederedParser creationBlock: [N2TJStructureParser newStartingAt: #subroutineName]

これはうまくいくようですが、他の解決策があるのではないかと思います。

4

1 に答える 1

3

現在、複合パーサーを複数のPPCompositeParserサブクラスに分割することは、PetitParserでは直接サポートされていません。

PetitParserブラウザーを使用する場合、インスタンス変数について気にする必要がないことを覚えておいてください。それらは自動的に管理されます。さらに、プロダクションごとにインスタンス変数は必ずしも必要ではありません。たとえば、端末は直接呼び出すメソッドに含めることができます。

あなたの解決策も確かに機能しますが、文法をどのように接続したいかに注意を払う必要があるため、それほど良いものではありません。また、実装では、結果を遅延キャッシュする必要があります。そうしないと、コードが解析中に新しい複合パーサーを作成します。これは非常に高価です。

PPCompositeParserこれはさておき、たとえば、コンストラクターが準備、初期化、最終的に解決する依存関係の他のパーサーを宣言することにより、複数のサブクラス間の依存関係をサポートするように改善することは確かに可能です。

于 2013-03-16T23:56:15.833 に答える