#ifndef PARSER_H #define PARSER_H #include #include struct parser_event { /** tipo de evento */ unsigned type; /** caracteres asociados al evento */ uint8_t data[3]; /** cantidad de datos en el buffer 'data' */ uint8_t n; /** lista de eventos: si es diferente de null ocurrieron varios eventos */ struct parser_event *next; }; /* CDT del parser */ typedef struct parser { /** tipificación para cada caracter */ const unsigned *classes; /** definición de estados */ struct parser_definition *def; /* estado actual */ unsigned state; /* evento que se retorna */ struct parser_event e1; /* evento que se retorna */ struct parser_event e2; } parser; /** describe una transición entre estados */ struct parser_state_transition { /* condición: un caracter o una clase de caracter. Por ej: '\r' */ int when; /** descriptor del estado destino cuando se cumple la condición */ unsigned dest; /** acción 1 que se ejecuta cuando la condición es verdadera. requerida. */ void (*act1)(struct parser_event *ret, const uint8_t c); /** otra acción opcional */ void (*act2)(struct parser_event *ret, const uint8_t c); }; /** predicado para utilizar en `when' que retorna siempre true */ static const unsigned ANY = 1 << 9; /** declaración completa de una máquina de estados */ struct parser_definition { /** cantidad de estados */ unsigned states_count; /** por cada estado, sus transiciones */ struct parser_state_transition **states; /** cantidad de estados por transición */ size_t *states_n; /** estado inicial */ unsigned start_state; }; /** * inicializa el parser. * * `classes`: caracterización de cada caracter (256 elementos) */ struct parser * parser_init(const unsigned *classes, struct parser_definition *def); /** destruye el parser */ void parser_destroy(struct parser *p); /** permite resetear el parser al estado inicial */ void parser_reset(struct parser *p); /** * el usuario alimenta el parser con un caracter, y el parser retorna un evento * de parsing. Los eventos son reusado entre llamadas por lo que si se desea * capturar los datos se debe clonar. */ struct parser_event * parser_feed(struct parser *p, const uint8_t c); /** * En caso de la aplicacion no necesite clases caracteres, se * provee dicho arreglo para ser usando en `parser_init' */ const unsigned * parser_no_classes(void); #endif