Merge branch 'master' of git://github.com/abiggerhammer/hammer
This commit is contained in:
commit
ca8751bcfe
25 changed files with 200 additions and 4 deletions
|
|
@ -112,6 +112,8 @@ typedef bool (*HPredicate)(HParseResult *p);
|
|||
|
||||
typedef struct HParserVtable_ {
|
||||
HParseResult* (*parse)(void *env, HParseState *state);
|
||||
bool (*isValidRegular)(void *env);
|
||||
bool (*isValidCF)(void *env);
|
||||
} HParserVtable;
|
||||
|
||||
typedef struct HParser_ {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,20 @@ static HParseResult* parse_action(void *env, HParseState *state) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool action_isValidRegular(void *env) {
|
||||
HParseAction *a = (HParseAction*)env;
|
||||
return a->p->vtable->isValidRegular(a->p->env);
|
||||
}
|
||||
|
||||
static bool action_isValidCF(void *env) {
|
||||
HParseAction *a = (HParseAction*)env;
|
||||
return a->p->vtable->isValidCF(a->p->env);
|
||||
}
|
||||
|
||||
static const HParserVtable action_vt = {
|
||||
.parse = parse_action,
|
||||
.isValidRegular = action_isValidRegular,
|
||||
.isValidCF = action_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_action(const HParser* p, const HAction a) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ static HParseResult *parse_and(void* env, HParseState* state) {
|
|||
|
||||
static const HParserVtable and_vt = {
|
||||
.parse = parse_and,
|
||||
.isValidRegular = h_false, /* TODO: strictly speaking this should be regular,
|
||||
but it will be a huge amount of work and difficult
|
||||
to get right, so we're leaving it for a future
|
||||
revision. --mlp, 18/12/12 */
|
||||
.isValidCF = h_false, /* despite TODO above, this remains false. */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,20 @@ static HParseResult* parse_attr_bool(void *env, HParseState *state) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool ab_isValidRegular(void *env) {
|
||||
HAttrBool *ab = (HAttrBool*)env;
|
||||
return ab->p->vtable->isValidRegular(ab->p->env);
|
||||
}
|
||||
|
||||
static bool ab_isValidCF(void *env) {
|
||||
HAttrBool *ab = (HAttrBool*)env;
|
||||
return ab->p->vtable->isValidCF(ab->p->env);
|
||||
}
|
||||
|
||||
static const HParserVtable attr_bool_vt = {
|
||||
.parse = parse_attr_bool,
|
||||
.isValidRegular = ab_isValidRegular,
|
||||
.isValidCF = ab_isValidCF,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ static HParseResult* parse_bits(void* env, HParseState *state) {
|
|||
|
||||
static const HParserVtable bits_vt = {
|
||||
.parse = parse_bits,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
const HParser* h_bits(size_t len, bool sign) {
|
||||
return h_bits__m(&system_allocator, len, sign);
|
||||
|
|
|
|||
|
|
@ -35,8 +35,16 @@ static HParseResult* parse_butnot(void *env, HParseState *state) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool bn_isValidCF(void *env) {
|
||||
HTwoParsers *tp = (HTwoParsers*)env;
|
||||
return (tp->p1->vtable->isValidCF(tp->p1->env) &&
|
||||
tp->p2->vtable->isValidCF(tp->p2->env));
|
||||
}
|
||||
|
||||
static const HParserVtable butnot_vt = {
|
||||
.parse = parse_butnot,
|
||||
.isValidRegular = h_false,
|
||||
.isValidCF = bn_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_butnot(const HParser* p1, const HParser* p2) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ static HParseResult* parse_ch(void* env, HParseState *state) {
|
|||
|
||||
static const HParserVtable ch_vt = {
|
||||
.parse = parse_ch,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
|
||||
const HParser* h_ch(const uint8_t c) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ static HParseResult* parse_charset(void *env, HParseState *state) {
|
|||
|
||||
static const HParserVtable charset_vt = {
|
||||
.parse = parse_charset,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
|
||||
const HParser* h_ch_range(const uint8_t lower, const uint8_t upper) {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,28 @@ static HParseResult* parse_choice(void *env, HParseState *state) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool choice_isValidRegular(void *env) {
|
||||
HSequence *s = (HSequence*)env;
|
||||
for (size_t i=0; i<s->len; ++i) {
|
||||
if (!s->p_array[i]->vtable->isValidRegular(s->p_array[i]->env))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool choice_isValidCF(void *env) {
|
||||
HSequence *s = (HSequence*)env;
|
||||
for (size_t i=0; i<s->len; ++i) {
|
||||
if (!s->p_array[i]->vtable->isValidCF(s->p_array[i]->env))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const HParserVtable choice_vt = {
|
||||
.parse = parse_choice,
|
||||
.isValidRegular = choice_isValidRegular,
|
||||
.isValidCF = choice_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_choice(const HParser* p, ...) {
|
||||
|
|
|
|||
|
|
@ -34,8 +34,16 @@ static HParseResult* parse_difference(void *env, HParseState *state) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool diff_isValidCF(void *env) {
|
||||
HTwoParsers *tp = (HTwoParsers*)env;
|
||||
return (tp->p1->vtable->isValidCF(tp->p1->env) &&
|
||||
tp->p2->vtable->isValidCF(tp->p2->env));
|
||||
}
|
||||
|
||||
static HParserVtable difference_vt = {
|
||||
.parse = parse_difference,
|
||||
.isValidRegular = h_false,
|
||||
.isValidCF = diff_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_difference(const HParser* p1, const HParser* p2) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ static HParseResult* parse_end(void *env, HParseState *state) {
|
|||
|
||||
static const HParserVtable end_vt = {
|
||||
.parse = parse_end,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
|
||||
const HParser* h_end_p() {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ static HParseResult* parse_epsilon(void* env, HParseState* state) {
|
|||
|
||||
static const HParserVtable epsilon_vt = {
|
||||
.parse = parse_epsilon,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
|
||||
static const HParser epsilon_p = {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,20 @@ static HParseResult* parse_ignore(void* env, HParseState* state) {
|
|||
return res;
|
||||
}
|
||||
|
||||
static bool ignore_isValidRegular(void *env) {
|
||||
HParser *p = (HParser*)env;
|
||||
return (p->vtable->isValidRegular(p->env));
|
||||
}
|
||||
|
||||
static bool ignore_isValidCF(void *env) {
|
||||
HParser *p = (HParser*)env;
|
||||
return (p->vtable->isValidCF(p->env));
|
||||
}
|
||||
|
||||
static const HParserVtable ignore_vt = {
|
||||
.parse = parse_ignore,
|
||||
.isValidRegular = ignore_isValidRegular,
|
||||
.isValidCF = ignore_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_ignore(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
typedef struct {
|
||||
const HParser **parsers;
|
||||
size_t count; // how many parsers in 'ps'
|
||||
size_t len; // how many parsers in 'ps'
|
||||
size_t which; // whose result to return
|
||||
} HIgnoreSeq;
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ static HParseResult* parse_ignoreseq(void* env, HParseState *state) {
|
|||
const HIgnoreSeq *seq = (HIgnoreSeq*)env;
|
||||
HParseResult *res = NULL;
|
||||
|
||||
for (size_t i=0; i < seq->count; ++i) {
|
||||
for (size_t i=0; i < seq->len; ++i) {
|
||||
HParseResult *tmp = h_do_parse(seq->parsers[i], state);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
|
@ -26,8 +26,28 @@ static HParseResult* parse_ignoreseq(void* env, HParseState *state) {
|
|||
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,
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -40,7 +60,7 @@ static const HParser* h_leftright__m(HAllocator* mm__, const HParser* p, const H
|
|||
seq->parsers = h_new(const HParser*, 2);
|
||||
seq->parsers[0] = p;
|
||||
seq->parsers[1] = q;
|
||||
seq->count = 2;
|
||||
seq->len = 2;
|
||||
seq->which = which;
|
||||
|
||||
HParser *ret = h_new(HParser, 1);
|
||||
|
|
@ -73,7 +93,7 @@ const HParser* h_middle__m(HAllocator* mm__, const HParser* p, const HParser* x,
|
|||
seq->parsers[0] = p;
|
||||
seq->parsers[1] = x;
|
||||
seq->parsers[2] = q;
|
||||
seq->count = 3;
|
||||
seq->len = 3;
|
||||
seq->which = 1;
|
||||
|
||||
HParser *ret = h_new(HParser, 1);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,17 @@
|
|||
static HParseResult* parse_indirect(void* env, HParseState* state) {
|
||||
return h_do_parse(env, state);
|
||||
}
|
||||
|
||||
static bool indirect_isValidCF(void *env) {
|
||||
HParser *p = (HParser*)env;
|
||||
HParser *inner = (HParser*)p->env;
|
||||
return inner->vtable->isValidCF(inner->env);
|
||||
}
|
||||
|
||||
static const HParserVtable indirect_vt = {
|
||||
.parse = parse_indirect,
|
||||
.isValidRegular = h_false,
|
||||
.isValidCF = indirect_isValidCF,
|
||||
};
|
||||
|
||||
void h_bind_indirect(HParser* indirect, const HParser* inner) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ static HParseResult* parse_int_range(void *env, HParseState *state) {
|
|||
|
||||
static const HParserVtable int_range_vt = {
|
||||
.parse = parse_int_range,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
|
||||
const HParser* h_int_range(const HParser *p, const int64_t lower, const int64_t upper) {
|
||||
|
|
|
|||
|
|
@ -44,8 +44,22 @@ static HParseResult *parse_many(void* env, HParseState *state) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool many_isValidRegular(void *env) {
|
||||
HRepeat *repeat = (HRepeat*)env;
|
||||
return (repeat->p->vtable->isValidRegular(repeat->p->env) &&
|
||||
repeat->sep->vtable->isValidRegular(repeat->sep->env));
|
||||
}
|
||||
|
||||
static bool many_isValidCF(void *env) {
|
||||
HRepeat *repeat = (HRepeat*)env;
|
||||
return (repeat->p->vtable->isValidCF(repeat->p->env) &&
|
||||
repeat->sep->vtable->isValidCF(repeat->sep->env));
|
||||
}
|
||||
|
||||
static const HParserVtable many_vt = {
|
||||
.parse = parse_many,
|
||||
.isValidRegular = many_isValidRegular,
|
||||
.isValidCF = many_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_many(const HParser* p) {
|
||||
|
|
@ -147,6 +161,8 @@ static HParseResult* parse_length_value(void *env, HParseState *state) {
|
|||
|
||||
static const HParserVtable length_value_vt = {
|
||||
.parse = parse_length_value,
|
||||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false,
|
||||
};
|
||||
|
||||
const HParser* h_length_value(const HParser* length, const HParser* value) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ static HParseResult* parse_not(void* env, HParseState* state) {
|
|||
|
||||
static const HParserVtable not_vt = {
|
||||
.parse = parse_not,
|
||||
.isValidRegular = h_false, /* see and.c for why */
|
||||
.isValidCF = h_false, /* also see and.c for why */
|
||||
};
|
||||
|
||||
const HParser* h_not(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ static HParseResult* parse_nothing() {
|
|||
|
||||
static const HParserVtable nothing_vt = {
|
||||
.parse = parse_nothing,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
|
||||
const HParser* h_nothing_p() {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,20 @@ static HParseResult* parse_optional(void* env, HParseState* state) {
|
|||
return make_result(state, ast);
|
||||
}
|
||||
|
||||
static bool opt_isValidRegular(void *env) {
|
||||
HParser *p = (HParser*) env;
|
||||
return p->vtable->isValidRegular(p->env);
|
||||
}
|
||||
|
||||
static bool opt_isValidCF(void *env) {
|
||||
HParser *p = (HParser*) env;
|
||||
return p->vtable->isValidCF(p->env);
|
||||
}
|
||||
|
||||
static const HParserVtable optional_vt = {
|
||||
.parse = parse_optional,
|
||||
.isValidRegular = opt_isValidRegular,
|
||||
.isValidCF = opt_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_optional(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,28 @@ static HParseResult* parse_sequence(void *env, HParseState *state) {
|
|||
return make_result(state, tok);
|
||||
}
|
||||
|
||||
static bool sequence_isValidRegular(void *env) {
|
||||
HSequence *s = (HSequence*)env;
|
||||
for (size_t i=0; i<s->len; ++i) {
|
||||
if (!s->p_array[i]->vtable->isValidRegular(s->p_array[i]->env))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sequence_isValidCF(void *env) {
|
||||
HSequence *s = (HSequence*)env;
|
||||
for (size_t i=0; i<s->len; ++i) {
|
||||
if (!s->p_array[i]->vtable->isValidCF(s->p_array[i]->env))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const HParserVtable sequence_vt = {
|
||||
.parse = parse_sequence,
|
||||
.isValidRegular = sequence_isValidRegular,
|
||||
.isValidCF = sequence_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_sequence(const HParser* p, ...) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ static HParseResult* parse_token(void *env, HParseState *state) {
|
|||
|
||||
const HParserVtable token_vt = {
|
||||
.parse = parse_token,
|
||||
.isValidRegular = h_true,
|
||||
.isValidCF = h_true,
|
||||
};
|
||||
|
||||
const HParser* h_token(const uint8_t *str, const size_t len) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ static HParseResult* parse_unimplemented(void* env, HParseState *state) {
|
|||
|
||||
static const HParserVtable unimplemented_vt = {
|
||||
.parse = parse_unimplemented,
|
||||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false,
|
||||
};
|
||||
|
||||
static HParser unimplemented = {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,20 @@ static HParseResult* parse_whitespace(void* env, HParseState *state) {
|
|||
return h_do_parse((HParser*)env, state);
|
||||
}
|
||||
|
||||
static bool ws_isValidRegular(void *env) {
|
||||
HParser *p = (HParser*)env;
|
||||
return p->vtable->isValidRegular(p->env);
|
||||
}
|
||||
|
||||
static bool ws_isValidCF(void *env) {
|
||||
HParser *p = (HParser*)env;
|
||||
return p->vtable->isValidCF(p->env);
|
||||
}
|
||||
|
||||
static const HParserVtable whitespace_vt = {
|
||||
.parse = parse_whitespace,
|
||||
.isValidRegular = ws_isValidRegular,
|
||||
.isValidCF = ws_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_whitespace(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -31,8 +31,16 @@ static HParseResult* parse_xor(void *env, HParseState *state) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool xor_isValidCF(void *env) {
|
||||
HTwoParsers *tp = (HTwoParsers*)env;
|
||||
return (tp->p1->vtable->isValidCF(tp->p1->env) &&
|
||||
tp->p2->vtable->isValidCF(tp->p2->env));
|
||||
}
|
||||
|
||||
static const HParserVtable xor_vt = {
|
||||
.parse = parse_xor,
|
||||
.isValidRegular = h_false,
|
||||
.isValidCF = xor_isValidCF,
|
||||
};
|
||||
|
||||
const HParser* h_xor(const HParser* p1, const HParser* p2) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue