From 54bd5a4a3832a2f4c85cc34799022f61d0ddcf86 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" <pesco@khjk.org> Date: Thu, 10 Jan 2013 23:44:28 +0100 Subject: [PATCH] add semantic actions for base64_3, base64_2, base64_1 --- examples/base64_sem1.c | 84 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/examples/base64_sem1.c b/examples/base64_sem1.c index 83efc644..7839435a 100644 --- a/examples/base64_sem1.c +++ b/examples/base64_sem1.c @@ -1,4 +1,5 @@ #include "../src/hammer.h" +#include "../src/internal.h" // for h_carray functions (XXX ?!) #include <assert.h> @@ -77,6 +78,81 @@ const HParsedToken *act_bsfdig(const HParseResult *p) #define act_document act_index0 +// helper +void carray_append_uint(HCountedArray *array, uint8_t value) +{ + HParsedToken *item = h_arena_malloc(array->arena, sizeof(HParsedToken)); + item->token_type = TT_UINT; + item->uint = value; + h_carray_append(array, item); +} + +const HParsedToken *act_base64_3(const HParseResult *p) +{ + assert(p->ast->token_type == TT_SEQUENCE); + + HParsedToken *res = h_arena_malloc(p->arena, sizeof(HParsedToken)); + res->token_type = TT_SEQUENCE; + res->seq = h_carray_new_sized(p->arena, 4); + + HParsedToken **digits = p->ast->seq->elements; + uint32_t x = digits[0]->uint; + x <<= 6; x |= digits[1]->uint; + x <<= 6; x |= digits[2]->uint; + x <<= 6; x |= digits[3]->uint; + + carray_append_uint(res->seq, (x >> 16) & 0xFF); + carray_append_uint(res->seq, (x >> 8) & 0xFF); + carray_append_uint(res->seq, x & 0xFF); + + return res; +} + +const HParsedToken *act_base64_2(const HParseResult *p) +{ + assert(p->ast->token_type == TT_SEQUENCE); + + HParsedToken *res = h_arena_malloc(p->arena, sizeof(HParsedToken)); + res->token_type = TT_SEQUENCE; + res->seq = h_carray_new_sized(p->arena, 4); + + HParsedToken **digits = p->ast->seq->elements; + uint32_t x = digits[0]->uint; + x <<= 6; x |= digits[1]->uint; + x <<= 6; x |= digits[2]->uint; + + carray_append_uint(res->seq, (x >> 10) & 0xFF); + carray_append_uint(res->seq, (x >> 2) & 0xFF); + + return res; +} + +const HParsedToken *act_base64_1(const HParseResult *p) +{ + assert(p->ast->token_type == TT_SEQUENCE); + + HParsedToken *res = h_arena_malloc(p->arena, sizeof(HParsedToken)); + res->token_type = TT_SEQUENCE; + res->seq = h_carray_new_sized(p->arena, 4); + + HParsedToken **digits = p->ast->seq->elements; + uint32_t x = digits[0]->uint; + x <<= 6; x |= digits[1]->uint; + + carray_append_uint(res->seq, (x >> 4) & 0xFF); + + return res; +} + +#if 0 +const HParsedToken *act_base64(const HParseResult *p) +{ + // XXX + // concatenate base64_3 blocks + // append trailing base64_2 or _1 block +} +#endif + /// // Set up the parser with the grammar to be recognized. @@ -97,10 +173,10 @@ const HParser *init_parser(void) H_ARULE(bsfdig, h_choice(alpha, digit, plus, slash, NULL)); H_ARULE(bsfdig_4bit, h_in((uint8_t *)"AEIMQUYcgkosw048", 16)); H_ARULE(bsfdig_2bit, h_in((uint8_t *)"AQgw", 4)); - H_RULE (base64_3, h_repeat_n(bsfdig, 4)); - H_RULE (base64_2, h_sequence(bsfdig, bsfdig, bsfdig_4bit, equals, NULL)); - H_RULE (base64_1, h_sequence(bsfdig, bsfdig_2bit, equals, equals, NULL)); - H_RULE (base64, h_sequence(h_many(base64_3), + H_ARULE(base64_3, h_repeat_n(bsfdig, 4)); + H_ARULE(base64_2, h_sequence(bsfdig, bsfdig, bsfdig_4bit, equals, NULL)); + H_ARULE(base64_1, h_sequence(bsfdig, bsfdig_2bit, equals, equals, NULL)); + H_RULE(base64, h_sequence(h_many(base64_3), h_optional(h_choice(base64_2, base64_1, NULL)), NULL)); -- GitLab