From 69e84bcbb047c0de92d2595742d3dfa337a940d3 Mon Sep 17 00:00:00 2001 From: Dan Hirsch <thequux@upstandinghackers.com> Date: Sat, 23 Nov 2013 13:01:55 -0600 Subject: [PATCH] Added a void* user_data pointer to HPredicate --- examples/dns.c | 4 ++-- examples/dns_common.c | 2 +- examples/rr.c | 2 +- src/backends/llk.c | 2 +- src/backends/lr.c | 2 +- src/glue.h | 12 +++++++----- src/hammer.h | 4 ++-- src/parsers/attr_bool.c | 17 ++++++++++------- src/t_parser.c | 5 +++-- 9 files changed, 28 insertions(+), 22 deletions(-) diff --git a/examples/dns.c b/examples/dns.c index 5effb895..63df3a44 100644 --- a/examples/dns.c +++ b/examples/dns.c @@ -15,7 +15,7 @@ // Validations /// -bool validate_hdzero(HParseResult *p) { +bool validate_hdzero(HParseResult *p, void* user_data) { if (TT_UINT != p->ast->token_type) return false; return (0 == p->ast->uint); @@ -25,7 +25,7 @@ bool validate_hdzero(HParseResult *p) { * Every DNS message should have QDCOUNT entries in the question * section, and ANCOUNT+NSCOUNT+ARCOUNT resource records. */ -bool validate_message(HParseResult *p) { +bool validate_message(HParseResult *p, void* user_data) { if (TT_SEQUENCE != p->ast->token_type) return false; diff --git a/examples/dns_common.c b/examples/dns_common.c index 3cdd04e0..bf934d61 100644 --- a/examples/dns_common.c +++ b/examples/dns_common.c @@ -10,7 +10,7 @@ H_ACT_APPLY(act_index0, h_act_index, 0) /** * A label can't be more than 63 characters. */ -bool validate_label(HParseResult *p) { +bool validate_label(HParseResult *p, void* user_data) { if (TT_SEQUENCE != p->ast->token_type) return false; return (64 > p->ast->seq->used); diff --git a/examples/rr.c b/examples/rr.c index 4a7c4be6..c179922d 100644 --- a/examples/rr.c +++ b/examples/rr.c @@ -11,7 +11,7 @@ // Validations and Semantic Actions /// -bool validate_null(HParseResult *p) { +bool validate_null(HParseResult *p, void* user_data) { if (TT_SEQUENCE != p->ast->token_type) return false; return (65536 > p->ast->seq->used); diff --git a/src/backends/llk.c b/src/backends/llk.c index 39ac07a6..2bc39daf 100644 --- a/src/backends/llk.c +++ b/src/backends/llk.c @@ -375,7 +375,7 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream* tok = (HParsedToken *)x->reshape(make_result(arena, tok), x->user_data); // call validation and semantic action, if present - if(x->pred && !x->pred(make_result(tarena, tok))) + if(x->pred && !x->pred(make_result(tarena, tok), x->user_data)) goto no_parse; // validation failed -> no parse if(x->action) tok = (HParsedToken *)x->action(make_result(arena, tok), x->user_data); diff --git a/src/backends/lr.c b/src/backends/lr.c index 3739ec9b..e7f23775 100644 --- a/src/backends/lr.c +++ b/src/backends/lr.c @@ -310,7 +310,7 @@ bool h_lrengine_step(HLREngine *engine, const HLRAction *action) value = (HParsedToken *)symbol->reshape(make_result(arena, value), symbol->user_data); // call validation and semantic action, if present - if(symbol->pred && !symbol->pred(make_result(tarena, value))) + if(symbol->pred && !symbol->pred(make_result(tarena, value), symbol->user_data)) return false; // validation failed -> no parse; terminate if(symbol->action) value = (HParsedToken *)symbol->action(make_result(arena, value), symbol->user_data); diff --git a/src/glue.h b/src/glue.h index 7486e46c..74963b06 100644 --- a/src/glue.h +++ b/src/glue.h @@ -58,17 +58,19 @@ #define H_RULE(rule, def) HParser *rule = def #define H_ARULE(rule, def) HParser *rule = h_action(def, act_ ## rule, NULL) #define H_VRULE(rule, def) HParser *rule = \ - h_attr_bool(def, validate_ ## rule) + h_attr_bool(def, validate_ ## rule, NULL) #define H_VARULE(rule, def) HParser *rule = \ - h_attr_bool(h_action(def, act_ ## rule, NULL), validate_ ## rule) + h_attr_bool(h_action(def, act_ ## rule, NULL), validate_ ## rule, NULL) #define H_AVRULE(rule, def) HParser *rule = \ - h_action(h_attr_bool(def, validate_ ## rule), act_ ## rule, NULL) + h_action(h_attr_bool(def, validate_ ## rule, NULL), act_ ## rule, NULL) #define H_ADRULE(rule, def, data) HParser *rule = \ h_action(def, act_ ## rule, data) +#define H_VDRULE(rule, def, data) HParser *rule = \ + h_attr_bool(def, validate_ ## rule, data) #define H_VADRULE(rule, def, data) HParser *rule = \ - h_attr_bool(h_action(def, act_ ## rule, data), validate_ ## rule) + h_attr_bool(h_action(def, act_ ## rule, data), validate_ ## rule, data) #define H_AVDRULE(rule, def, data) HParser *rule = \ - h_action(h_attr_bool(def, validate_ ## rule), act_ ## rule, data) + h_action(h_attr_bool(def, validate_ ## rule, data), act_ ## rule, data) // diff --git a/src/hammer.h b/src/hammer.h index bd3ae022..541e38df 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -120,7 +120,7 @@ typedef HParsedToken* (*HAction)(const HParseResult *p, void* user_data); * attr_bool() parser. It can be any (user-defined) function that takes * a HParseResult* and returns true or false. */ -typedef bool (*HPredicate)(HParseResult *p); +typedef bool (*HPredicate)(HParseResult *p, void* user_data); typedef struct HCFChoice_ HCFChoice; typedef struct HRVMProg_ HRVMProg; @@ -515,7 +515,7 @@ HAMMER_FN_DECL(HParser*, h_length_value, const HParser* length, const HParser* v * * Result token type: p's result type if pred succeeded, NULL otherwise. */ -HAMMER_FN_DECL(HParser*, h_attr_bool, const HParser* p, HPredicate pred); +HAMMER_FN_DECL(HParser*, h_attr_bool, const HParser* p, HPredicate pred, void* user_data); /** * The 'and' parser asserts that a conditional syntax is satisfied, diff --git a/src/parsers/attr_bool.c b/src/parsers/attr_bool.c index fc980b24..e8359ab0 100644 --- a/src/parsers/attr_bool.c +++ b/src/parsers/attr_bool.c @@ -4,13 +4,14 @@ typedef struct { const HParser *p; HPredicate pred; + void* user_data; } HAttrBool; static HParseResult* parse_attr_bool(void *env, HParseState *state) { HAttrBool *a = (HAttrBool*)env; HParseResult *res = h_do_parse(a->p, state); if (res && res->ast) { - if (a->pred(res)) + if (a->pred(res, a->user_data)) return res; else return NULL; @@ -42,12 +43,13 @@ static void desugar_ab(HAllocator *mm__, HCFStack *stk__, void *env) { } HCFS_END_SEQ(); HCFS_THIS_CHOICE->pred = a->pred; HCFS_THIS_CHOICE->reshape = h_act_first; + HCFS_THIS_CHOICE->user_data = a->user_data; } HCFS_END_CHOICE(); } static bool h_svm_action_attr_bool(HArena *arena, HSVMContext *ctx, void* arg) { HParseResult res; - HPredicate pred = arg; + HAttrBool *ab = arg; assert(ctx->stack_count >= 1); if (ctx->stack[ctx->stack_count-1]->token_type != TT_MARK) { assert(ctx->stack_count >= 2 && ctx->stack[ctx->stack_count-2]->token_type == TT_MARK); @@ -59,7 +61,7 @@ static bool h_svm_action_attr_bool(HArena *arena, HSVMContext *ctx, void* arg) { res.ast = NULL; } res.arena = arena; - return pred(&res); + return ab->pred(&res, ab->user_data); } static bool ab_ctrvm(HRVMProg *prog, void *env) { @@ -67,7 +69,7 @@ static bool ab_ctrvm(HRVMProg *prog, void *env) { h_rvm_insert_insn(prog, RVM_PUSH, 0); if (!h_compile_regex(prog, ab->p)) return false; - h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_attr_bool, ab->pred)); + h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_attr_bool, ab)); return true; } @@ -80,12 +82,13 @@ static const HParserVtable attr_bool_vt = { }; -HParser* h_attr_bool(const HParser* p, HPredicate pred) { - return h_attr_bool__m(&system_allocator, p, pred); +HParser* h_attr_bool(const HParser* p, HPredicate pred, void* user_data) { + return h_attr_bool__m(&system_allocator, p, pred, user_data); } -HParser* h_attr_bool__m(HAllocator* mm__, const HParser* p, HPredicate pred) { +HParser* h_attr_bool__m(HAllocator* mm__, const HParser* p, HPredicate pred, void* user_data) { HAttrBool *env = h_new(HAttrBool, 1); env->p = p; env->pred = pred; + env->user_data = user_data; return h_new_parser(mm__, &attr_bool_vt, env); } diff --git a/src/t_parser.c b/src/t_parser.c index 292d1c45..12edba93 100644 --- a/src/t_parser.c +++ b/src/t_parser.c @@ -365,7 +365,7 @@ static void test_epsilon_p(gconstpointer backend) { g_check_parse_match(epsilon_p_3, (HParserBackend)GPOINTER_TO_INT(backend), "a", 1, "(u0x61)"); } -bool validate_test_ab(HParseResult *p) { +bool validate_test_ab(HParseResult *p, void* user_data) { if (TT_SEQUENCE != p->ast->token_type) return false; if (TT_UINT != p->ast->seq->elements[0]->token_type) @@ -377,7 +377,8 @@ bool validate_test_ab(HParseResult *p) { static void test_attr_bool(gconstpointer backend) { const HParser *ab_ = h_attr_bool(h_many1(h_choice(h_ch('a'), h_ch('b'), NULL)), - validate_test_ab); + validate_test_ab, + NULL); g_check_parse_match(ab_, (HParserBackend)GPOINTER_TO_INT(backend), "aa", 2, "(u0x61 u0x61)"); g_check_parse_match(ab_, (HParserBackend)GPOINTER_TO_INT(backend), "bb", 2, "(u0x62 u0x62)"); -- GitLab