C でのパーサーの作成

始める前に

以下のトピックを読み、理解していることを確認してください。

ロード可能インプリメンテーション・ライブラリー、または LIL、 は C パーサー (またはノード) のインプリメンテーション・モジュールです。 LIL は、ファイル拡張子が .dll ではなく .lil である、Linux または UNIX 共有オブジェクトまたは Windows ダイナミック・リンク・ライブラリー (DLL) です。

開発者が作成する必要のあるインプリメンテーション関数は、C パーサー・インプリメンテーション関数でリストしています。このプロセスに役立てるために WebSphere Message Broker によって提供されるユーティリティー関数は、C パーサー・ユーティリティー関数でリストしています。

WebSphere Message Broker には、 BipSampPluginParser.c というサンプル・ユーザー定義パーサーのソースが備えられています。これは、単純な擬似 XML パーサーで、現状のまま使用することもできますし、変更を加えることもできます。

パーサーを作成するタスクは、 構文解析されるビット・ストリームの複雑さによってかなり異なります。ここでは、基本ステップのみを説明します。 これらについて、以下のセクションで説明します。
  1. パーサーの宣言および定義
  2. パーサーのインスタンスの作成
  3. パーサーのインスタンスの削除

パーサーの宣言および定義

ブローカーに対してユーザー定義パーサーを宣言して定義するには、初期化関数 bipGetParserFactory を LIL に含める必要があります。 以下のステップは、ブローカーが初期化関数をどのようにして呼び出し、初期化関数がユーザー定義パーサーをどのようにして宣言および定義するかについての概要です。

以下の手順は、パーサーをブローカーへ宣言および定義する方法を表しています。

  1. LIL がロードされ、オペレーティング・システムによって初期化されると、 ブローカーによって初期化関数 bipGetParserFactory が呼び出されます。 ブローカーは、 LIL が実行できる事柄と、ブローカーが LIL を呼び出す方法を理解するために、この関数を呼び出します。 以下に例を示します。
    CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix
    bipGetParserFactory()
  2. bipGetParserFactory 関数は次にユーティリティー関数 cpiCreateParserFactory を呼び出します。 この関数は、LIL がサポートするすべてのパーサーに固有のファクトリー名 (またはグループ名) を戻します。 戻されるファクトリー名 (またはグループ名) はいずれも、そのブローカー内のすべての LIL で固有でなければなりません。
  3. LIL は次にユーティリティー関数 cpiDefineParserClass を呼び出して、 各パーサーの固有の名前と、インプリメンテーション関数のアドレスの仮想関数表を渡します。
    例えば、 以下のコードは InputxParser という単一パーサーの宣言と定義を行います。
    {
    CciFactory* factoryObject;
    int                rc = 0;
    CciChar factoryName[] = L"MyParserFactory";
    CCI_EXCEPTION_ST exception_st;
    
    /* Create the Parser Factory for this parser */
    factoryObject = cpiCreateParserFactory(0, factoryName);
    if (factoryObject == CCI_NULL_ADDR) {
    		
    /* Any local error handling can go here */
    	}
    	else {
    /* Define the parsers supported by this factory */
    static CNI_VFT vftable = {CNI_VFT_DEFAULT};
    
    /* Setup function table with pointers to parser implementation functions */
    vftable.iFpCreateContext = cpiCreateContext;
    vftable.iFpParseBufferEncoded = cpiParseBufferEncoded;
    vftable.iFpParseFirstChild = cpiParseFirstChild;
    vftable.iFpParseLastChild = cpiParseLastChild;
    vftable.iFpParsePreviousSibling = cpiParsePreviousSibling;
    vftable.iFpParseNextSibling = cpiParseNextSibling;
    vftable.iFpWriteBufferEncoded = cpiWriteBufferEncoded;
    vftable.iFpDeleteContext = cpiDeleteContext;
    vftable.iFpSetElementValue = cpiSetElementValue;
    vftable.iFpElementValue = cpiElementValue;
    vftable.iFpNextParserClassName = cpiNextParserClassName;
    vftable.iFpSetNextParserClassName = cpiSetNextParserClassName;
    vftable.iFpNextParserEncoding = cpiNextParserEncoding;
    vftable.iFpNextParserCodedCharSetId = cpiNextParserCodedCharSetId;
    
    cpiDefineParserClass(0, factoryObject, L"InputxParser", &vftable);
    	}
    
    /* Return address of this factory object to the broker */
    return(factoryObject);
    }

    初期化関数は、cpiCreateParserFactory を呼び出すことによってパーサー・ファクトリーを作成する必要があります。 ファクトリーがサポートするパーサー・クラスは、cpiDefineParserClass を呼び出すことによって定義されます。ファクトリー・オブジェクトのアドレス (cpiCreateParserFactory によって戻される) は、 初期化関数からの戻り値としてブローカーに戻される必要があります。

    以下に例を示します。
    1. cpiCreateParserFactory 関数を使用してパーサー・ファクトリーを作成します。
        factoryObject = cpiCreateParserFactory(&rc, constParserFactory);
        
    2. cpiDefineParserClass 関数を使用して、 ファクトリーがサポートするメッセージのクラスを定義します。
      if (factoryObject) {
         cpiDefineParserClass(&rc, factoryObject, constPXML, &vftable);
        }
      else {
          /* Error: Unable to create parser factory */
        }
    3. このファクトリー・オブジェクトのアドレスをブローカーに戻します。
        return(factoryObject);
      }

パーサーのインスタンスの作成

以下の手順は、パーサーをインスタンス化する方法を表しています。

ブローカーは、関数ポインターの表を受信すると、ユーザー定義パーサーの各インスタンス化ごとに関数 cpiCreateContext を呼び出します。 ユーザー定義パーサーを使用する 3 つのメッセージ・フローがある場合は、 3 つのそれぞれに対して cpiCreateContext 関数が呼び出されます。 この関数は、そのユーザー定義パーサーのインスタンス化用に、 構成された属性の値を保持するためのメモリーを割り振ります。 以下に例を示します。
  1. cpiCreateContext 関数を呼び出します。
    CciContext* _createContext(
      CciFactory* factoryObject,
      CciChar* parserName,
      CciNode* parserObject
    ){
      static char* functionName = (char *)"_createContext()";
      PARSER_CONTEXT_ST* p;
      CciChar buffer[256];
  2. ローカル・コンテキストにポインターを割り振り、コンテキスト・エリアを消去します。
      p = (PARSER_CONTEXT_ST *)malloc(sizeof(PARSER_CONTEXT_ST));
    
      if (p) {
         memset(p, 0, sizeof(PARSER_CONTEXT_ST));
  3. コンテキストの中のパーサー・オブジェクト・ポインターを保存します。
       p->parserObject = parserObject;
  4. パーサー名を保存します。
     CciCharNCpy((CciChar*)&p->parserName, parserName, MAX_NODE_NAME_LEN);
  5. パーサー・コンテキストを戻します。
    return (CciContext*) p;

パーサーのインスタンスの削除

メッセージ・フローが削除や再デプロイされたり、実行グループの処理が (mqsistop コマンドを使用して) 停止されたりすると、パーサーは破棄されます。 パーサーが破棄されるとき、 使用されていたメモリーおよび保持されていたリソースがあれば、 それらは開放される必要があります。 これは、cpiDeleteContext 関数を使用して行います。 以下に例を示します。

void cpiDeleteContext(
  CciParser*  parser,
  CciContext* context
){
  PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
  int                rc = 0;

  return;
}
特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック
Copyright IBM Corporation 1999, 2006 最終更新: 08/21/2006
as10010_