#ifndef LIBLEX_PATTERN_H #define LIBLEX_PATTERN_H #include "liblex.h" /** * Enum that represents the type * of a NFA node / state. */ enum pattern_node_type_e { /** * Represents a clear, un-configured node. */ PNODE_CLEAR, /** * Represents a single value to be matched. */ PNODE_VALUE, /** * Represents a range of values, inclusive. */ PNODE_RANGE, /** * Represents any character other than the NULL terminator. */ PNODE_ANY, /** * Represents a "connection" between nodes, does not * match any value. * */ PNODE_CONNECT, /** * Represents a fork / divide in possible "next" states. */ PNODE_FORK, /** * Represents a succesfully matched pattern. */ PNODE_END }; /** * Struct representing a single NFA node / state. */ struct pattern_node_s { /** * The type of this node. */ enum pattern_node_type_e type; /** * The id of this node. * The id is unique within the pattern. */ int id; /** * The id of the pattern that this node belongs to. */ int pattern_id; /** * Whether to "invert" this node - inverted * nodes indicate "match anything but this". */ int invert; /** * The node's data that varies based on type. */ union { /** * Data for a "value" node. */ struct { /** * The value this node matches. */ char value; /** * The next state in the pattern. */ struct pattern_node_s* next; } value_s; /** * Data for a "range" node. */ struct { /** * The beginning of the range, inclusive, of matched values. */ char from; /** * The end of the range, inclusive, of matched values. */ char to; /** * The next state in the pattern. */ struct pattern_node_s* next; } range_s; /** * Data for an "any" node. */ struct { /** * The next state in the pattern. */ struct pattern_node_s* next; } any_s; /** * Data for a "connect" node. */ struct { /** * The next node in the pattern. */ struct pattern_node_s* next; } connect_s; /** * Data for a "fork" node. */ struct { /** * The left node in the fork. */ struct pattern_node_s* left; /** * The right node in the fork. */ struct pattern_node_s* right; } fork_s; } data_u; }; /** * A chain of pattern nodes. */ struct pattern_chain_s { /** * The beginning of the chain, its first state. */ struct pattern_node_s* head; /** * The end of the chain, its last state. */ struct pattern_node_s* tail; }; /** * Represents a single compiled pattern. */ struct pattern_s { /** * The first NFA state of the pattern. */ struct pattern_node_s* head; /** * The number of NFA nodes in this pattern. */ int size; }; typedef enum pattern_node_type_e pattern_node_type; typedef struct pattern_node_s pattern_node; typedef struct pattern_chain_s pattern_chain; typedef struct pattern_s pattern; /** * Compiles a string representation of a pattern into a pattern NFA, * and stores the first node of the new NFA in root. * @param root the node to store the resulting pattern into. * @param expression the pattern represented as a string. * @param id the id of the pattern. * @return LIBLEX_SUCCESS if all goes well, otherwise some other liblex_result. */ liblex_result pattern_compile(pattern* ptrn, const char* expression, int id); /** * Frees a pattern NFA allocated by pattern_compile. * @param root the root node to start freeing from. * @return LIBLEX_SUCCESS if all goes well, otherwise some other liblex_result. */ liblex_result pattern_free(pattern* ptrn); #endif