From 0813b6995d344af14f8f2e7ed5042f30f99cdfd6 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" <pesco@khjk.org> Date: Sun, 9 Feb 2020 18:09:20 +0100 Subject: [PATCH] differantiate error codes from h_compile() and update documentation the regex backend already returned 2 for an internal failure, contrary to documentation, so this mainly brings the latter in line with existing behavior. at the same time, fix a bug: h_compile would previously return "false" (0) on exceptions (longjmp). make use of our new freedom to signal different error conditions from the context-free backends, notably "incompatible combinator" vs. "unresolvable conflict". --- src/backends/glr.c | 2 +- src/backends/lalr.c | 10 +++++----- src/backends/llk.c | 2 +- src/backends/regex.c | 3 ++- src/benchmark.c | 2 +- src/hammer.h | 8 +++++++- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/backends/glr.c b/src/backends/glr.c index 535dc286..44b0c50c 100644 --- a/src/backends/glr.c +++ b/src/backends/glr.c @@ -14,7 +14,7 @@ int h_glr_compile(HAllocator* mm__, HParser* parser, const void* params) } int result = h_lalr_compile(mm__, parser, params); - if(result == -1 && parser->backend_data) { + if(result == -2 && parser->backend_data) { // table is there, just has conflicts? nevermind, that's okay. result = 0; } diff --git a/src/backends/lalr.c b/src/backends/lalr.c index b82ef71c..db9b88ae 100644 --- a/src/backends/lalr.c +++ b/src/backends/lalr.c @@ -279,18 +279,18 @@ int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params) } HCFGrammar *g = h_cfgrammar_(mm__, h_desugar_augmented(mm__, parser)); if(g == NULL) // backend not suitable (language not context-free) - return -1; + return 2; HLRDFA *dfa = h_lr0_dfa(g); if (dfa == NULL) { // this should normally not happen h_cfgrammar_free(g); - return -1; + return 3; } HLRTable *table = h_lr0_table(g, dfa); if (table == NULL) { // this should normally not happen h_cfgrammar_free(g); - return -1; + return 4; } if(has_conflicts(table)) { @@ -300,7 +300,7 @@ int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params) if(eg == NULL) { // this should normally not happen h_cfgrammar_free(g); h_lrtable_free(table); - return -1; + return 5; } // go through the inadequate states; replace inadeq with a new list @@ -349,7 +349,7 @@ int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params) h_cfgrammar_free(g); parser->backend_data = table; - return has_conflicts(table)? -1 : 0; + return has_conflicts(table)? -2 : 0; } void h_lalr_free(HParser *parser) diff --git a/src/backends/llk.c b/src/backends/llk.c index 4e8209b3..19944a20 100644 --- a/src/backends/llk.c +++ b/src/backends/llk.c @@ -238,7 +238,7 @@ int h_llk_compile(HAllocator* mm__, HParser* parser, const void* params) // the table was ambiguous h_cfgrammar_free(grammar); h_llktable_free(table); - return -1; + return -2; } parser->backend_data = table; diff --git a/src/backends/regex.c b/src/backends/regex.c index f26abfda..0337949f 100644 --- a/src/backends/regex.c +++ b/src/backends/regex.c @@ -430,9 +430,10 @@ static int h_regex_compile(HAllocator *mm__, HParser* parser, const void* params prog->actions = NULL; prog->allocator = mm__; if (setjmp(prog->except)) { - return false; + return 3; } if (!h_compile_regex(prog, parser)) { + // this shouldn't normally fail when isValidRegular() returned true h_free(prog->insns); h_free(prog->actions); h_free(prog); diff --git a/src/benchmark.c b/src/benchmark.c index b6a2876f..7d56c32e 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -46,7 +46,7 @@ HBenchmarkResults *h_benchmark__m(HAllocator* mm__, HParser* parser, HParserTest for (backend = PB_MIN; backend <= PB_MAX; backend++) { ret->results[backend].backend = backend; // Step 1: Compile grammar for given parser... - if (h_compile(parser, backend, NULL) == -1) { + if (h_compile(parser, backend, NULL)) { // backend inappropriate for grammar... fprintf(stderr, "Compiling for %s failed\n", HParserBackendNames[backend]); ret->results[backend].compile_success = false; diff --git a/src/hammer.h b/src/hammer.h index c8a1074c..6cd2660d 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -785,7 +785,13 @@ void h_pprintln(FILE* stream, const HParsedToken* tok); * documentation for the parser backend in question for information * about the [params] parameter, or just pass in NULL for the defaults. * - * Returns -1 if grammar cannot be compiled with the specified options; 0 otherwise. + * Returns a nonzero value on error; 0 otherwise. Common return codes include: + * + * -1: parser uses a combinator that is incompatible with the chosen backend. + * -2: parser could not be compiled with the chosen parameters. + * >0: unexpected internal errors. + * + * Consult each backend for details. */ HAMMER_FN_DECL(int, h_compile, HParser* parser, HParserBackend backend, const void* params); -- GitLab