static struct rx_node *_term(struct parse_sp *ps) { struct rx_node *n; switch (ps->type) { case 0: if (!(n = _node(ps->mem, CHARSET, NULL, NULL))) { stack; return NULL; } dm_bit_copy(n->charset, ps->charset); _rx_get_token(ps); /* match charset */ break; case '(': _rx_get_token(ps); /* match '(' */ n = _or_term(ps); if (ps->type != ')') { log_error("missing ')' in regular expression"); return 0; } _rx_get_token(ps); /* match ')' */ break; default: n = 0; } return n; }
struct rx_node *rx_parse_tok(struct dm_pool *mem, const char *begin, const char *end) { struct rx_node *r; struct parse_sp *ps = dm_pool_zalloc(mem, sizeof(*ps)); if (!ps) return_NULL; ps->mem = mem; if (!(ps->charset = dm_bitset_create(mem, 256))) { log_error("Regex charset allocation failed"); dm_pool_free(mem, ps); return NULL; } ps->cursor = begin; ps->rx_end = end; _rx_get_token(ps); /* load the first token */ if (!(r = _or_term(ps))) { log_error("Parse error in regex"); dm_pool_free(mem, ps); return NULL; } if (!(r = _optimise(mem, r))) { log_error("Regex optimisation error"); dm_pool_free(mem, ps); return NULL; } return r; }
static struct rx_node *_closure_term(struct parse_sp *ps) { struct rx_node *l, *n; if (!(l = _term(ps))) return NULL; for (;;) { switch (ps->type) { case '*': n = _node(ps->mem, STAR, l, NULL); break; case '+': n = _node(ps->mem, PLUS, l, NULL); break; case '?': n = _node(ps->mem, QUEST, l, NULL); break; default: return l; } if (!n) return_NULL; _rx_get_token(ps); l = n; } return n; }
static struct rx_node *_or_term(struct parse_sp *ps) { struct rx_node *l, *r, *n; if (!(l = _cat_term(ps))) return NULL; if (ps->type != '|') return l; _rx_get_token(ps); /* match '|' */ if (!(r = _or_term(ps))) { log_error("Badly formed 'or' expression"); return NULL; } if (!(n = _node(ps->mem, OR, l, r))) stack; return n; }