Skip to content

Commit

Permalink
Extend reentrancy hack to read_token()
Browse files Browse the repository at this point in the history
Extend hack introduced in a57380f for vnmakarov#12.
  • Loading branch information
TheCount committed Nov 19, 2018
1 parent 697c850 commit dfa54c0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 19 deletions.
29 changes: 16 additions & 13 deletions src/yaep.c
Original file line number Diff line number Diff line change
Expand Up @@ -3370,25 +3370,25 @@ yaep_read_grammar (struct grammar *g, int strict_p,
symbs_ptr = g->symbs_ptr;
term_sets_ptr = g->term_sets_ptr;
rules_ptr = g->rules_ptr;
if ((code.value = setjmp (error_longjump_buff)) != 0)
if ((code.value.code = setjmp (error_longjump_buff)) != 0)
{
return code.value;
return code.value.code;
}
if (!grammar->undefined_p)
yaep_empty_grammar ();
while ((name = (*read_terminal) (&code.value)) != NULL)
while ((name = (*read_terminal) (&code.value.code)) != NULL)
{
if (code.value < 0)
if (code.value.code < 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.value) != NULL)
if (symb_find_by_code (code.value.code) != NULL)
yaep_error (YAEP_REPEATED_TERM_CODE,
"repeated code %d in term `%s'", code.value, name);
symb_add_term (name, code.value);
"repeated code %d in term `%s'", code.value.code, name);
symb_add_term (name, code.value.code);
}

/* Adding error symbol. */
Expand All @@ -3400,7 +3400,8 @@ 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.value, &transl)) != NULL)
while ((lhs = (*read_rule) (&rhs, &anode, &anode_cost.value.anode_cost,
&transl)) != NULL)
{
symb = symb_find_by_repr (lhs);
if (symb == NULL)
Expand All @@ -3411,7 +3412,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.value < 0)
if (anode != NULL && anode_cost.value.anode_cost < 0)
yaep_error (YAEP_NEGATIVE_COST,
"translation for `%s' has negative cost", lhs);
if (grammar->axiom == NULL)
Expand Down Expand Up @@ -3441,7 +3442,8 @@ 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.value : 0));
rule = rule_new_start (symb, anode,
(anode != NULL ? anode_cost.value.anode_cost : 0));
while (*rhs != NULL)
{
symb = symb_find_by_repr (*rhs);
Expand Down Expand Up @@ -3656,10 +3658,11 @@ static void
read_toks (void)
{
int code;
void *attr;
struct _yaep_reentrant_hack attr;

while ((code = read_token (&attr)) >= 0)
tok_add (code, attr);
attr.grammar = grammar;
while ((code = read_token (&attr.value.attr)) >= 0)
tok_add (code, attr.value.attr);
tok_add (END_MARKER_CODE, NULL);
}

Expand Down
24 changes: 18 additions & 6 deletions src/yaep.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,24 +150,36 @@ struct yaep_tree_node
};

/* 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,
yaep_read_grammar() and yaep_parse(). The read_terminal() and read_rule()
functions passed to yaep_read_grammar(), as well as the read_token(),
syntax_error(), parse_alloc(), and parse_free() functions passed to
yaep_parse() 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
When sticking to the old API, however, we hijack some pointer
parameters to slip through the grammar as additional information.
Unfortunately, it does not work for syntax_error(), parse_alloc(),
and parse_free(), because these functions do not have
pointer-for-return type parameters.
This structure is for internal use only.
Use the yaep_reentrant_hack_grammar() macro to retrieve the grammar. */
struct _yaep_reentrant_hack
{
int value;
union
{
int code;
int anode_cost;
void *attr;
} 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(). */
read_terminal() parameter, to the anode_cost parameter of the
read_rule() parameter of yaep_read_grammar(),
as well as to the attr paramnerer of the read_token() parameter of
yaep_parse(). */
#define yaep_reentrant_hack_grammar(x) \
(((struct _yaep_reentrant_hack *) \
(((char *) (x)) - offsetof (struct _yaep_reentrant_hack, value))) \
Expand Down

0 comments on commit dfa54c0

Please sign in to comment.