Ampliación de las posibilidades de un analizador en C

Antes de comenzar

Asegúrese de haber leído y comprendido el tema siguiente:

Implementación de la funcionalidad de analizador

Un analizador necesita implementar los siguientes tipos de función de implementación:
  1. funciones de entrada
  2. funciones de análisis
  3. funciones de salida

Más abajo se describe cada tipo de función.

Implementación de funciones de entrada

Inicio del cambioExisten tres funciones de entrada: El analizador puede implementar una y sólo una de estas funciones de entrada.Fin del cambio

Inicio del cambioEl intermediario invocará la función de entrada cuando el analizador definido por el usuario sea requerido para analizar un mensaje de entrada.Fin del cambio El analizador debe indicar al intermediario qué cantidad de almacenamiento intermedio de corriente de bits de entrada reclama como propietario. En el caso de una cabecera de tamaño fijo, el analizador reclama el tamaño de la cabecera. Si el analizador está destinado a manejar el mensaje completo, reclama el resto del almacenamiento intermedio.

Por ejemplo:
  1. El intermediario invoca la función de entrada cpiParseBufferEncoded:
    int cpiParseBufferEncoded(
    CciParser*  parser,
    CciContext* context,
    int         encoding,
    int         ccsid
    ){
    PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
    int                rc;
  2. Obtenga un puntero al almacenamiento intermedio de mensajes y a continuación establezca el desplazamiento utilizando la función de utilidad cpiBufferPointer:
    pc->iBuffer = (void *)cpiBufferPointer(&rc, parser);
    pc->iIndex = 0;
  3. Guarde el formato del almacenamiento intermedio:
    pc->iEncoding = encoding;
    pc->iCcsid = ccsid;
  4. Guarde el tamaño del almacenamiento intermedio utilizando la función de utilidad cpiBufferSize:
    pc->iSize = cpiBufferSize(&rc, parser);
  5. Cargue el primer byte de la corriente de datos utilizando la función de utilidad cpiBufferByte:
    pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
  6. Establezca el elemento actual en el elemento raíz utilizando la función de utilidad cpiRootElement:
    pc->iCurrentElement = cpiRootElement(&rc, parser);
  7. Restablezca el distintivo para asegurar que el análisis se restablece correctamente:
    pc->iInTag = 0;
  8. Reclame la propiedad del resto del almacenamiento intermedio:
    return(pc->iSize);
    }

Implementación de funciones de análisis

Las funciones de análisis generales (por ejemplo cpiParseFirstChild) son las invocadas por el intermediario cuando se necesita crear el árbol de elementos de sintaxis para evaluar una expresión ESQL o Java. Por ejemplo, un nodo de filtro utiliza una referencia de campo ESQL en una expresión ESQL. Esta referencia de campo se debe resolver a fin de evaluar la expresión. Se invoca la función de análisis general del analizador, quizá repetidamente, hasta que el elemento solicitado se crea o hasta que el analizador reconoce que dicho elemento no existe.

Por ejemplo:
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;
}

Implementación de funciones de salida

Inicio del cambioExisten tres funciones de salida: El analizador puede implementar una y sólo una de estas funciones de salida.Fin del cambio

Inicio del cambioEl intermediario invocará la función de salida cuando se solicite al analizador definido por el usuario que serialice un árbol de elementos en una corriente de bits de salida.Fin del cambio Por ejemplo, es posible que un nodo Compute haya creado un árbol en el dominio del analizador definido por el usuario. Cuando este árbol necesite que, por ejemplo, un nodo MQOutput lo produzca como salida, el analizador será responsable de añadir el almacenamiento intermedio de corriente de bits de salida con los datos que representan el árbol que se ha creado.

Por ejemplo:
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 *)"Algunos datos de prueba", 14);
return cpiBufferSize(0, parser) - initialSize;
}

Implementación de un analizador de cabecera de mensajes

Normalmente, dado que los datos de mensaje de entrada tienen un solo formato de mensaje, un analizador es responsable de analizar el contenido entero del mensaje. El nombre de clase del analizador que se necesita se define en el campo Formato del MQMD o de la cabecera MQRFH2 del mensaje de entrada.

Sin embargo, es posible que el mensaje conste de varios formatos, donde, por ejemplo, hay una cabecera en un formato seguida de datos en otro formato. En este caso, el primer analizador tiene que identificar el nombre de clase del analizador que es responsable del siguiente formato de la cadena, y así sucesivamente. En un analizador definido por el usuario, el intermediario invoca la función de implementación cpiNextParserClassName cuando necesita navegar hacia abajo en una cadena de clases de analizador para un mensaje que contiene varios formatos de mensaje.

Si el analizador definido por el usuario soporta el análisis de un formato de mensaje que forma parte de un formato de mensaje múltiple, el analizador definido por el usuario debe implementar la función cpiNextParserClassName.

Por ejemplo:
  1. Invoque la función cpiNextParserClassName:
    void cpiNextParserClassName(
    CciParser*  parser,
    CciContext* context,
    CciChar*    buffer,
    int         size
    ){
    PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
    int rc = 0;
  2. Copie el nombre de la siguiente clase de analizador en el intermediario:
    CciCharNCpy(buffer, pc->iNextParserClassName, size);
    return;
    }
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2006 Última actualización: 04/05/2006
as24980_