From 737acae240f8de8b21c9ed3a9db71709c64c1013 Mon Sep 17 00:00:00 2001 From: Alexander Klauer Date: Sun, 11 Nov 2018 18:05:42 +0100 Subject: [PATCH] Provide grammar to read_terminal() and read_rule() Hack for #12 while using the current API. --- src/yaep.c | 26 ++++++++++++++------------ src/yaep.h | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/yaep.c b/src/yaep.c index a77a382..cd1f2b0 100644 --- a/src/yaep.c +++ b/src/yaep.c @@ -3359,34 +3359,36 @@ yaep_read_grammar (struct grammar *g, int strict_p, const char *name, *lhs, **rhs, *anode; struct symb *symb, *start; struct rule *rule; - int anode_cost; int *transl; - int i, el, code; + int i, el; + struct _yaep_reentrant_hack anode_cost, code; assert (g != NULL); + anode_cost.grammar = g; + code.grammar = g; grammar = g; symbs_ptr = g->symbs_ptr; term_sets_ptr = g->term_sets_ptr; rules_ptr = g->rules_ptr; - if ((code = setjmp (error_longjump_buff)) != 0) + if ((code.value = setjmp (error_longjump_buff)) != 0) { - return code; + return code.value; } if (!grammar->undefined_p) yaep_empty_grammar (); - while ((name = (*read_terminal) (&code)) != NULL) + while ((name = (*read_terminal) (&code.value)) != NULL) { - if (code < 0) + if (code.value < 0) yaep_error (YAEP_NEGATIVE_TERM_CODE, "term `%s' has negative code", name); symb = symb_find_by_repr (name); if (symb != NULL) yaep_error (YAEP_REPEATED_TERM_DECL, "repeated declaration of term `%s'", name); - if (symb_find_by_code (code) != NULL) + if (symb_find_by_code (code.value) != NULL) yaep_error (YAEP_REPEATED_TERM_CODE, - "repeated code %d in term `%s'", code, name); - symb_add_term (name, code); + "repeated code %d in term `%s'", code.value, name); + symb_add_term (name, code.value); } /* Adding error symbol. */ @@ -3398,7 +3400,7 @@ yaep_read_grammar (struct grammar *g, int strict_p, grammar->term_error = symb_add_term (TERM_ERROR_NAME, TERM_ERROR_CODE); grammar->term_error_num = grammar->term_error->u.term.term_num; grammar->axiom = grammar->end_marker = NULL; - while ((lhs = (*read_rule) (&rhs, &anode, &anode_cost, &transl)) != NULL) + while ((lhs = (*read_rule) (&rhs, &anode, &anode_cost.value, &transl)) != NULL) { symb = symb_find_by_repr (lhs); if (symb == NULL) @@ -3409,7 +3411,7 @@ yaep_read_grammar (struct grammar *g, int strict_p, if (anode == NULL && transl != NULL && *transl >= 0 && transl[1] >= 0) yaep_error (YAEP_INCORRECT_TRANSLATION, "rule for `%s' has incorrect translation", lhs); - if (anode != NULL && anode_cost < 0) + if (anode != NULL && anode_cost.value < 0) yaep_error (YAEP_NEGATIVE_COST, "translation for `%s' has negative cost", lhs); if (grammar->axiom == NULL) @@ -3439,7 +3441,7 @@ yaep_read_grammar (struct grammar *g, int strict_p, rule->order[0] = 0; rule->trans_len = 1; } - rule = rule_new_start (symb, anode, (anode != NULL ? anode_cost : 0)); + rule = rule_new_start (symb, anode, (anode != NULL ? anode_cost.value : 0)); while (*rhs != NULL) { symb = symb_find_by_repr (*rhs); diff --git a/src/yaep.h b/src/yaep.h index 6c89c9a..3bb9a64 100644 --- a/src/yaep.h +++ b/src/yaep.h @@ -33,6 +33,7 @@ #define __YAEP__ #include +#include /* The following is a forward declaration of grammar formed by function yaep_read_grammar. */ @@ -148,6 +149,30 @@ struct yaep_tree_node } val; }; +/* The following structure is used to work around a limitation of + yaep_read_grammar(). The read_terminal() and read_rule() functions + passed to yaep_read_grammar() cannot take a user-defined argument, + but this is required for reentrant operation. + The long-term solution would be to expand the API of yaep (FIXME). + When sticking to the old API, however, we hijack the pointer-to-int + parameters to slip through the grammar as additional information. + This structure is for internal use only. + Use the yaep_reentrant_hack_grammar() macro to retrieve the grammar. */ +struct _yaep_reentrant_hack +{ + int value; + struct grammar *grammar; +}; + +/* The following macro retrieves the grammar from a pointer-to-int argument. + It can only be applied to arguments to the code parameter of the + read_terminal() parameter, and to the anode_cost parameter of the + read_rule() parameter of yaep_read_grammar(). */ +#define yaep_reentrant_hack_grammar(x) \ + (((struct _yaep_reentrant_hack *) \ + (((char *) (x)) - offsetof (struct _yaep_reentrant_hack, value))) \ + ->grammar) + #ifndef __cplusplus /* The following function creates undefined grammar. The function