Estendendo o Recurso de um Analisador C Definido pelo Usuário

Quando você tiver criado um analisador C, você poderá estender a sua capacidade.

Antes de começar
Certifique-se de que tenha lido e entendido o seguinte tópico:

Implementando a Funcionalidade do Analisador

Um analisador precisa implementar os seguintes tipos de funções de implementação:
  1. Funções de Entrada
  2. Funções de Análise
  3. Funções de Saída

Implementando Funções de Entrada

Seu analisador deve implementar uma, e apenas uma, das seguintes funções de entrada:

O intermediário chama a função input quando o analisador definido pelo usuário for necessário para analisar uma mensagem de entrada. O analisador deve instruir ao intermediário de quanto do buffer do fluxo de bits de entrada ele reclama para si. No caso de um cabeçalho de comprimento fixo, o analisador reclama o tamanho do cabeçalho. Caso o analisador deva manipular a mensagem inteira, ele reclamará o restante do buffer.

Exemplo:
  1. O intermediário chama a função de entrada cpiParseBufferEncoded:
    int cpiParseBufferEncoded(
        CciParser*  parser,
      CciContext*    context,
        int            encoding,
        int         ccsid
    ){
        PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
        int                rc;
  2. Obter um ponteiro para o buffer de mensagem e definir o deslocamento utilizando a função de utilitário cpiBufferPointer:
      pc->iBuffer = (void *)cpiBufferPointer(&rc, parser);
      pc->iIndex = 0;
  3. Salvar o formato do buffer:
      pc->iEncoding = encoding;
      pc->iCcsid = ccsid;
  4. Salvar o tamanho do buffer utilizando a função de utilitário cpiBufferSize:
      pc->iSize = cpiBufferSize(&rc, parser);
  5. Obter o primeiro byte no fluxo utilizando a função de utilitário cpiBufferByte:
      pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
  6. Configurar o elemento atual para o elemento raiz utilizando a função de utilitário cpiRootElement:
      pc->iCurrentElement = cpiRootElement(&rc, parser);
  7. Reconfigurar o sinalizador para assegurar-se de que a análise seja redefinida corretamente:
      pc->iInTag = 0;
  8. Reclamar a propriedade do restante do buffer:
      return(pc->iSize);
    }

Implementando Funções de Análise

As funções de análise geral (por exemplo, cpiParseFirstChild) são aquelas chamadas pelo intermediário quando a árvore de elementos da sintaxe precisar ser criada para avaliar uma expressão ESQL ou Java. Por exemplo, um nó Filter utiliza uma referência de campo ESQL em uma expressão ESQL. Essa referência de campo precisa ser resolvida para avaliar a expressão. A função geral de análise do analisador é chamada, talvez repetidamente, até que o elemento pedido seja criado ou seja reconhecido pelo analisador como não existente.

Exemplo:
void cpiParseFirstChild(
    CciParser*  parser,
  CciContext*    context,
    CciElement* element
){
    PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
    int                rc;

  if ((!cpiElementCompleteNext(&rc, element)) &&
            (cpiElementType(&rc, element) == CCI_ELEMENT_TYPE_NAME)) {

    while ((!cpiElementCompleteNext(&rc, element))     &&
                      (!cpiFirstChild(&rc, element)) &&
           (pc->iCurrentElement))
    {
      pc->iCurrentElement = parseNextItem(parser, context, pc->iCurrentElement);
    }
  }
           return;
}

Implementando Funções de Saída

Seu analisador deve implementar uma, e apenas uma, das seguintes funções de saída:

O intermediário chama a função output quando o analisador definido pelo usuário for necessário para serializar uma árvore de elementos de sintaxe para um fluxo de bits de saída. Por exemplo, um nó Compute pode ter criado uma árvore no domínio do analisador definido pelo usuário. Quando um nó, como um nó MQOutput, precisar serializar essa árvore, o analisador é responsável poe anexar o buffer de fluxo de bits de saída com dados que representam a árvore que foi construída.

Exemplo:
int cpiWriteBufferEncoded(
    CciParser*  parser,
  CciContext*    context,
    int            encoding,
    int         ccsid
){
    PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
    int                initialSize = 0;
    int                rc = 0;
    const void* a;
    CciByte b;

    initialSize = cpiBufferSize(&rc, parser);
    a = cpiBufferPointer(&rc, parser);
    b = cpiBufferByte(&rc, parser, 0);

    cpiAppendToBuffer(&rc, parser, (char *)"Some test data", 14);

    return cpiBufferSize(0, parser) - initialSize;
}

Implementando um Analisador de Cabeçalho da Mensagem

Geralmente, os dados da mensagem de entrada são de um único formato da mensagem; portanto, um analisador é responsável por analisar todo o conteúdo da mensagem. O nome da classe do analisador que é necessário é definido no campo Format no cabeçalho MQMD ou MQRFH2 da mensagem de entrada.

Entretanto, a mensagem pode consistir em vários formatos, por exemplo, onde exista um cabeçalho em um formato seguido por dados em outro formato. Nesse caso, o primeiro analisador tem que identificar o nome da classe do analisador que é responsável pelo próximo formato na cadeia, e assim por diante. Em um analisador definido pelo usuário, a função de implementação cpiNextParserClassName é chamada pelo intermediário quando navega por uma cadeia de classes de analisador para uma mensagem composta por vários formatos da mensagem.

Se o analisador definido pelo usuário suportar a análise de um formato de mensagem que faz parte de um formato de várias mensagens, o analisador definido pelo usuário deve implementar a função cpiNextParserClassName.

Exemplo:
  1. Chamar a função cpiNextParserClassName:
    void cpiNextParserClassName(
        CciParser*  parser,
      CciContext*    context,
        CciChar*    buffer,
        int         size
    ){
        PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
        int                rc = 0;
  2. Copiar o nome da próxima classe de analisador para o intermediário:
      CciCharNCpy(buffer, pc->iNextParserClassName, size);
    
               return;
    }
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback

Copyright IBM Corporation 1999, 2009Copyright IBM Corporation 1999, 2009.
Última atualização : 2009-02-13 16:13:13

as24980_