Make sure ocamlyacc can handle 255 entry points (#9210)

The previous promised limit of ocamlyacc was 256 entry points, but
on some platforms (x86 at least) the actual limit was 127 due to representation of 
bucket->entry as char.  Switching to unsigned char extends the limit to 255.

I introduced a constant MAX_ENTRY_POINT as a synonym of MAXCHAR to
handle checks against the limit consistently over the different modules
of ocamlyacc.

Extensions beyond 255 entry points would require a bit more work (which
looks unrewarding) since entry points are currently identified by a single byte
at the beginning of the input stream.

Fixes: #9207
master
Andreas Abel 2019-12-26 11:02:13 +01:00 committed by Xavier Leroy
parent dc458a0436
commit 0d97917cd2
4 changed files with 16 additions and 6 deletions

View File

@ -73,6 +73,10 @@ Working version
to the toplevel.
(Gabriel Scherer, review by Armaël Guéneau)
* #9207: fix ocamlyacc to work correctly with up to 255 entry points
to the grammar.
(Andreas Abel, review by Xavier Leroy)
### Manual and documentation:
- #9141: beginning of the ocamltest reference manual

View File

@ -145,10 +145,16 @@ struct bucket
short prec;
char class;
char assoc;
char entry;
unsigned char entry; /* 1..MAX_ENTRY_POINT (0 for unassigned) */
char true_token;
};
/* MAX_ENTRY_POINT is the maximal number of entry points into the grammar. */
/* Entry points are identified by a non-zero byte in the input stream, */
/* so there are at most 255 entry points. */
#define MAX_ENTRY_POINT MAXCHAR
/* TABLE_SIZE is the number of entries in the symbol table. */
/* TABLE_SIZE must be a power of two. */

View File

@ -177,8 +177,8 @@ token\n", virtual_input_file_name, lineno, s);
void too_many_entries(void)
{
fprintf(stderr, "File \"%s\", line %d: more than 256 entry points\n",
virtual_input_file_name, lineno);
fprintf(stderr, "File \"%s\", line %d: more than %u entry points\n",
virtual_input_file_name, lineno, MAX_ENTRY_POINT);
done(1);
}

View File

@ -978,9 +978,9 @@ void declare_start(void)
if (bp->class == TERM)
terminal_start(bp->name);
bp->entry = ++entry_counter;
if (entry_counter == 256)
if (entry_counter >= MAX_ENTRY_POINT)
too_many_entries();
bp->entry = ++entry_counter;
}
}
@ -1699,7 +1699,7 @@ void make_goal(void)
if (is_polymorphic(bp->tag))
polymorphic_entry_point(bp->name);
fprintf(entry_file,
"let %s (lexfun : Lexing.lexbuf -> token) (lexbuf : Lexing.lexbuf) =\n (Parsing.yyparse yytables %d lexfun lexbuf : %s)\n",
"let %s (lexfun : Lexing.lexbuf -> token) (lexbuf : Lexing.lexbuf) =\n (Parsing.yyparse yytables %u lexfun lexbuf : %s)\n",
bp->name, bp->entry, bp->tag);
fprintf(interface_file,
"val %s :\n (Lexing.lexbuf -> token) -> Lexing.lexbuf -> %s\n",