* src/muscle_tab.h (MUSCLE_INSERT_LONG_INT): New.

* src/output.c (output_table_data): Return the longest number.
(prepare_tokens): Output `token_number_max').
* data/bison.simple, data/bison.c++ (b4_sint_type, b4_uint_type):
New.
Use them to define yy_token_number_type/TokenNumberType.
Use this type for yytranslate.
* tests/torture.at (Big triangle): Push the limit from 124 to
253.
* tests/regression.at (Web2c Actions): Adjust.
This commit is contained in:
Akim Demaille
2002-04-07 17:44:59 +00:00
parent 817e9f41d1
commit 680e8701b5
11 changed files with 95 additions and 26 deletions

View File

@@ -1,3 +1,16 @@
2002-04-07 Akim Demaille <akim@epita.fr>
* src/muscle_tab.h (MUSCLE_INSERT_LONG_INT): New.
* src/output.c (output_table_data): Return the longest number.
(prepare_tokens): Output `token_number_max').
* data/bison.simple, data/bison.c++ (b4_sint_type, b4_uint_type):
New.
Use them to define yy_token_number_type/TokenNumberType.
Use this type for yytranslate.
* tests/torture.at (Big triangle): Push the limit from 124 to
253.
* tests/regression.at (Web2c Actions): Adjust.
2002-04-07 Akim Demaille <akim@epita.fr> 2002-04-07 Akim Demaille <akim@epita.fr>
* tests/torture.at (Big triangle): New. * tests/torture.at (Big triangle): New.

5
TODO
View File

@@ -16,9 +16,8 @@ grammars.
* Huge Grammars * Huge Grammars
Currently, not only is Bison unable to handle huge grammars because of Currently, not only is Bison unable to handle huge grammars because of
internal limitations, but the test `big triangle' also demonstrates internal limitations (see test `big triangle'). Push the limit beyond
that it can produce SEGVing executables! Push the limit beyond 124, 253. Be my guest: fix this!
and have a core dump. Be my guest: fix this!
* read_pipe.c * read_pipe.c
This is not portable to DOS for instance. Implement a more portable This is not portable to DOS for instance. Implement a more portable

View File

@@ -1,5 +1,25 @@
m4_divert(-1) m4_divert(-1)
# b4_sint_type(MAX)
# -----------------
# Return the smallest signed int type able to handle the number MAX.
m4_define([b4_sint_type],
[m4_if(m4_eval([$1 <= 127]), [1], [signed char],
m4_eval([$1 <= 32767]), [1], [signed short],
m4_eval([$1 <= 2147483647]), [1], [signed int],
[m4_fatal([no signed int type for $1])])])
# b4_uint_type(MAX)
# -----------------
# Return the smallest unsigned int type able to handle the number MAX.
m4_define([b4_uint_type],
[m4_if(m4_eval([$1 <= 255]), [1], [unsigned char],
m4_eval([$1 <= 65535]), [1], [unsigned short],
m4_eval([$1 <= 4294967295]), [1], [unsigned int],
[m4_fatal([no unsigned int type for $1])])])
# b4_token_defines(TOKEN-NAME, TOKEN-NUMBER) # b4_token_defines(TOKEN-NAME, TOKEN-NUMBER)
# ------------------------------------------ # ------------------------------------------
# Output the definition of this token as #define. # Output the definition of this token as #define.
@@ -147,6 +167,7 @@ namespace yy
template < > template < >
struct Traits< b4_name > struct Traits< b4_name >
{ {
typedef typedef b4_uint_type(b4_token_number_max) TokenNumberType;
typedef int StateType; typedef int StateType;
typedef yystype SemanticType; typedef yystype SemanticType;
typedef b4_ltype LocationType; typedef b4_ltype LocationType;
@@ -159,9 +180,10 @@ namespace yy
{ {
public: public:
typedef Traits< b4_name >::StateType StateType; typedef Traits< b4_name >::TokenNumberType TokenNumberType;
typedef Traits< b4_name >::SemanticType SemanticType; typedef Traits< b4_name >::StateType StateType;
typedef Traits< b4_name >::LocationType LocationType; typedef Traits< b4_name >::SemanticType SemanticType;
typedef Traits< b4_name >::LocationType LocationType;
typedef Stack< StateType > StateStack; typedef Stack< StateType > StateStack;
typedef Stack< SemanticType > SemanticStack; typedef Stack< SemanticType > SemanticStack;
@@ -218,7 +240,7 @@ namespace yy
#endif #endif
/* Even more tables. */ /* Even more tables. */
static inline char translate_ (int token); static inline TokenNumberType translate_ (int token);
/* Constants. */ /* Constants. */
static const int eof_; static const int eof_;
@@ -685,16 +707,16 @@ yy::b4_name::rline_[[]] =
#endif #endif
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
char TokenNumberType
yy::b4_name::translate_ (int token) yy::b4_name::translate_ (int token)
{ {
static static
const char const TokenNumberType
translate_[[]] = translate_[[]] =
{ {
b4_translate b4_translate
}; };
return ((unsigned)(token) <= maxtok_ ? translate_[[token]] : nsym_); return (unsigned)(token) <= maxtok_ ? translate_[[token]] : nsym_;
} }
const int yy::b4_name::eof_ = 0; const int yy::b4_name::eof_ = 0;

View File

@@ -1,5 +1,25 @@
m4_divert(-1) m4_divert(-1)
# b4_sint_type(MAX)
# -----------------
# Return the smallest signed int type able to handle the number MAX.
m4_define([b4_sint_type],
[m4_if(m4_eval([$1 <= 127]), [1], [signed char],
m4_eval([$1 <= 32767]), [1], [signed short],
m4_eval([$1 <= 2147483647]), [1], [signed int],
[m4_fatal([no signed int type for $1])])])
# b4_uint_type(MAX)
# -----------------
# Return the smallest unsigned int type able to handle the number MAX.
m4_define([b4_uint_type],
[m4_if(m4_eval([$1 <= 255]), [1], [unsigned char],
m4_eval([$1 <= 65535]), [1], [unsigned short],
m4_eval([$1 <= 4294967295]), [1], [unsigned int],
[m4_fatal([no unsigned int type for $1])])])
m4_define_default([b4_input_suffix], [.y]) m4_define_default([b4_input_suffix], [.y])
m4_define_default([b4_output_parser_suffix], m4_define_default([b4_output_parser_suffix],
@@ -248,10 +268,11 @@ b4_token_defines(b4_tokens)
#define YYMAXUTOK b4_maxtok #define YYMAXUTOK b4_maxtok
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
typedef b4_uint_type(b4_token_number_max) yy_token_number_type;
#define YYTRANSLATE(x) ((unsigned)(x) <= b4_maxtok ? yytranslate[[x]] : b4_nsym) #define YYTRANSLATE(x) ((unsigned)(x) <= b4_maxtok ? yytranslate[[x]] : b4_nsym)
/* YYTRANSLATE[[YYLEX]] -- Bison symbol number corresponding to YYLEX. */ /* YYTRANSLATE[[YYLEX]] -- Bison symbol number corresponding to YYLEX. */
static const char yytranslate[[]] = static const yy_token_number_type yytranslate[[]] =
{ {
b4_translate b4_translate
}; };

View File

@@ -38,7 +38,7 @@ int nsyms = 0;
int ntokens = 1; int ntokens = 1;
int nvars = 0; int nvars = 0;
short *token_translations = NULL; token_number_t *token_translations = NULL;
int start_symbol = 0; int start_symbol = 0;

View File

@@ -148,11 +148,11 @@ extern struct rule_s *rules;
/* Table of the symbols, indexed by the symbol number. */ /* Table of the symbols, indexed by the symbol number. */
extern symbol_t **symbols; extern symbol_t **symbols;
/* token translation table: indexed by a token number as returned by /* TOKEN_TRANSLATION -- a table indexed by a token number as returned
the user's yylex routine, it yields the internal token number used by the user's yylex routine, it yields the internal token number
by the parser and throughout bison. */ used by the parser and throughout bison. */
typedef short token_number_t;
extern short *token_translations; extern token_number_t *token_translations;
extern int max_user_token_number; extern int max_user_token_number;
/* SEMANTIC_PARSER is nonzero if the input file says to use the hairy /* SEMANTIC_PARSER is nonzero if the input file says to use the hairy

View File

@@ -40,6 +40,13 @@ const char *muscle_find PARAMS ((const char *key));
muscle_insert (Key, obstack_finish (&muscle_obstack)); \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \
} }
#define MUSCLE_INSERT_LONG_INT(Key, Value) \
{ \
obstack_fgrow1 (&muscle_obstack, "%ld", Value); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
#define MUSCLE_INSERT_STRING(Key, Value) \ #define MUSCLE_INSERT_STRING(Key, Value) \
{ \ { \
obstack_sgrow (&muscle_obstack, Value); \ obstack_sgrow (&muscle_obstack, Value); \

View File

@@ -147,15 +147,19 @@ get_lines_number (const char *s)
} }
/* FIXME. */ /*----------------------------------------------------------------.
| Format the FIRST and then TABLE_DATA[BEGIN..END[ into OOUT, and |
| return the number of bits needed for its longuest value. |
`----------------------------------------------------------------*/
static inline void static inline long int
output_table_data (struct obstack *oout, output_table_data (struct obstack *oout,
short *table_data, short *table_data,
short first, short first,
int begin, int begin,
int end) int end)
{ {
long int max = first;
int i; int i;
int j = 1; int j = 1;
@@ -171,8 +175,12 @@ output_table_data (struct obstack *oout,
else else
++j; ++j;
obstack_fgrow1 (oout, "%6d", table_data[i]); obstack_fgrow1 (oout, "%6d", table_data[i]);
if (table_data[i] > max)
max = table_data[i];
} }
obstack_1grow (oout, 0); obstack_1grow (oout, 0);
return max;
} }
@@ -184,9 +192,10 @@ output_table_data (struct obstack *oout,
static void static void
prepare_tokens (void) prepare_tokens (void)
{ {
output_table_data (&format_obstack, token_translations, long int max = output_table_data (&format_obstack, token_translations,
0, 1, max_user_token_number + 1); 0, 1, max_user_token_number + 1);
muscle_insert ("translate", obstack_finish (&format_obstack)); muscle_insert ("translate", obstack_finish (&format_obstack));
MUSCLE_INSERT_LONG_INT ("token_number_max", max);
XFREE (token_translations); XFREE (token_translations);
{ {

View File

@@ -1691,7 +1691,7 @@ token_translations_init (void)
max_user_token_number = this->user_token_number; max_user_token_number = this->user_token_number;
} }
token_translations = XCALLOC (short, max_user_token_number + 1); token_translations = XCALLOC (token_number_t, max_user_token_number + 1);
/* Initialize all entries for literal tokens to 2, the internal /* Initialize all entries for literal tokens to 2, the internal
token number for $undefined., which represents all invalid token number for $undefined., which represents all invalid

View File

@@ -433,7 +433,7 @@ AT_CHECK([bison -v input.y -o input.c])
# Check only the tables. We don't use --no-parser, because it is # Check only the tables. We don't use --no-parser, because it is
# still to be implemented in the experimental branch of Bison. # still to be implemented in the experimental branch of Bison.
AT_CHECK([[sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c]], 0, AT_CHECK([[sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c]], 0,
[[static const char yytranslate[] = [[static const yy_token_number_type yytranslate[] =
{ {
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,

View File

@@ -127,11 +127,9 @@ mv stdout $1
## Big triangle. ## ## Big triangle. ##
## -------------- ## ## -------------- ##
# Arg, the upper limit, currently, is 124. Afterwards, the
# executable dumps core...
AT_SETUP([Big triangle]) AT_SETUP([Big triangle])
AT_DATA_TRIANGULAR_GRAMMAR([input.y], [124]) AT_DATA_TRIANGULAR_GRAMMAR([input.y], [253])
AT_CHECK([bison input.y -v -o input.c]) AT_CHECK([bison input.y -v -o input.c])
AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore]) AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore])
AT_CHECK([./input]) AT_CHECK([./input])