/* Parser combinators for binary formats. * Copyright (C) 2012 Meredith L. Patterson, Dan "TQ" Hirsch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include "hammer.h" #include "internal.h" #include "allocator.h" #include "parsers/parser_internal.h" static HParserBackendVTable *backends[PB_MAX + 1] = { &h__packrat_backend_vtable, &h__regex_backend_vtable, &h__llk_backend_vtable, &h__lalr_backend_vtable, &h__glr_backend_vtable, }; /* Helper function, since these lines appear in every parser */ typedef struct { const HParser *p1; const HParser *p2; } HTwoParsers; HParseResult* h_parse(const HParser* parser, const uint8_t* input, size_t length) { return h_parse__m(&system_allocator, parser, input, length); } HParseResult* h_parse__m(HAllocator* mm__, const HParser* parser, const uint8_t* input, size_t length) { // Set up a parse state... HInputStream input_stream = { .index = 0, .bit_offset = 8, .overrun = 0, .endianness = BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN, .length = length, .input = input }; return backends[parser->backend]->parse(mm__, parser, &input_stream); } void h_parse_result_free__m(HAllocator *alloc, HParseResult *result) { h_parse_result_free(result); } void h_parse_result_free(HParseResult *result) { if(result == NULL) return; h_delete_arena(result->arena); } bool h_false(void* env) { (void)env; return false; } bool h_true(void* env) { (void)env; return true; } bool h_not_regular(HRVMProg *prog, void *env) { (void)env; return false; } int h_compile(HParser* parser, HParserBackend backend, const void* params) { return h_compile__m(&system_allocator, parser, backend, params); } int h_compile__m(HAllocator* mm__, HParser* parser, HParserBackend backend, const void* params) { backends[parser->backend]->free(parser); int ret = backends[backend]->compile(mm__, parser, params); if (!ret) parser->backend = backend; return ret; }