Skip to content
Snippets Groups Projects
ignoreseq.c 2.55 KiB
Newer Older
#include "parser_internal.h"


//
// general case: parse sequence, pick one result
//

typedef struct {
  const HParser **parsers;
  size_t which;         // whose result to return
} HIgnoreSeq;

static HParseResult* parse_ignoreseq(void* env, HParseState *state) {
  const HIgnoreSeq *seq = (HIgnoreSeq*)env;
  HParseResult *res = NULL;

    HParseResult *tmp = h_do_parse(seq->parsers[i], state);
    if (!tmp)
      return NULL;
    else if (i == seq->which)
      res = tmp;
  }

  return res;
}

static bool is_isValidRegular(void *env) {
  HIgnoreSeq *seq = (HIgnoreSeq*)env;
  for (size_t i=0; i<seq->len; ++i) {
    if (!seq->parsers[i]->vtable->isValidRegular(seq->parsers[i]->env))
      return false;
  }
  return true;
}

static bool is_isValidCF(void *env) {
  HIgnoreSeq *seq = (HIgnoreSeq*)env;
  for (size_t i=0; i<seq->len; ++i) {
    if (!seq->parsers[i]->vtable->isValidCF(seq->parsers[i]->env))
      return false;
  }
  return true;
}

static const HParserVtable ignoreseq_vt = {
  .parse = parse_ignoreseq,
  .isValidRegular = is_isValidRegular,
  .isValidCF = is_isValidCF,
static const HParser* h_leftright__m(HAllocator* mm__, const HParser* p, const HParser* q, size_t which) {
  HIgnoreSeq *seq = h_new(HIgnoreSeq, 1);
  seq->parsers = h_new(const HParser*, 2);
  seq->parsers[0] = p;
  seq->parsers[1] = q;
  seq->which = which;

  HParser *ret = h_new(HParser, 1);
  ret->vtable = &ignoreseq_vt;
  ret->env = (void*)seq;
  return ret;
}

const HParser* h_left(const HParser* p, const HParser* q) {
  return h_leftright__m(&system_allocator, p, q, 0);
}
const HParser* h_left__m(HAllocator* mm__, const HParser* p, const HParser* q) {
  return h_leftright__m(mm__, p, q, 0);
}

const HParser* h_right(const HParser* p, const HParser* q) {
  return h_leftright__m(&system_allocator, p, q, 1);
}
const HParser* h_right__m(HAllocator* mm__, const HParser* p, const HParser* q) {
  return h_leftright__m(mm__, p, q, 1);
const HParser* h_middle(const HParser* p, const HParser* x, const HParser* q) {
  return h_middle__m(&system_allocator, p, x, q);
}
const HParser* h_middle__m(HAllocator* mm__, const HParser* p, const HParser* x, const HParser* q) {
  HIgnoreSeq *seq = h_new(HIgnoreSeq, 1);
  seq->parsers = h_new(const HParser*, 3);
  seq->parsers[0] = p;
  seq->parsers[1] = x;
  seq->parsers[2] = q;
  HParser *ret = h_new(HParser, 1);
  ret->vtable = &ignoreseq_vt;
  ret->env = (void*)seq;
  return ret;
}