diff options
author | John Millaway <john43@users.sourceforge.net> | 2002-09-13 01:17:22 +0000 |
---|---|---|
committer | John Millaway <john43@users.sourceforge.net> | 2002-09-13 01:17:22 +0000 |
commit | 815fd665d8c46fc9f106fe65643c12614ffc9747 (patch) | |
tree | b1135a92b387ceb3d8629464bc0b57261d51343d | |
parent | f6904782ed84d7a946ecca17c1b1269eee0978c0 (diff) |
Bison bridge code now works for all C scanners and pure/non-pure bison parsers.
Added %option bison-bridge (--bison-bridge).
Removed %option reentrant-bison/--reentrant-bison/-Rb.
Scanner knows the name of its tables.
Tables serialization is OK on EOF.
yylineno is present in all scanners.
Modified nasty performance penalty warning w/ yylineno.
test-table-opts is now run last because it's so fat.
Updated manual.
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | flex.skl | 99 | ||||
-rw-r--r-- | flex.texi | 271 | ||||
-rw-r--r-- | flexdef.h | 4 | ||||
-rw-r--r-- | gen.c | 11 | ||||
-rw-r--r-- | main.c | 69 | ||||
-rw-r--r-- | misc.c | 7 | ||||
-rw-r--r-- | options.c | 8 | ||||
-rw-r--r-- | options.h | 2 | ||||
-rw-r--r-- | scan.l | 6 | ||||
-rw-r--r-- | tables.h | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 5 | ||||
-rw-r--r-- | tests/descriptions | 1 | ||||
-rw-r--r-- | tests/test-bison-yylloc/scanner.l | 2 | ||||
-rw-r--r-- | tests/test-bison-yylval/scanner.l | 2 | ||||
-rw-r--r-- | tests/test-table-opts/scanner.l | 4 |
16 files changed, 275 insertions, 220 deletions
diff --git a/configure.in b/configure.in index 352f61a..54945c7 100644 --- a/configure.in +++ b/configure.in @@ -97,6 +97,7 @@ tests/test-posix/Makefile tests/test-posixly-correct/Makefile tests/test-table-opts/Makefile tests/test-c++-basic/Makefile +tests/test-bison-nr/Makefile dnl --new-test-here-- This line is processed by tests/create-test. ) @@ -539,7 +539,7 @@ struct yyguts_t int yy_more_len; #endif -#ifdef YY_REENTRANT_BISON_PURE +#ifdef YY_BISON_BRIDGE YYSTYPE * yylval_r; #ifdef YYLTYPE YYLTYPE * yylloc_r; @@ -556,12 +556,14 @@ static int yy_init_globals YY_PARAMS(( YY_PROTO_ONLY_ARG )); %not-for-header These go in the .c file only. /* This must go here because YYSTYPE and YYLSTYPE are included * from bison output in section 1.*/ -#ifdef YY_REENTRANT_BISON_PURE +#ifdef YY_REENTRANT +#ifdef YY_BISON_BRIDGE # define yylval YY_G(yylval_r) # ifdef YYLTYPE # define yylloc YY_G(yylloc_r) # endif -#endif /* YY_REENTRANT_BISON_PURE */ +#endif /* YY_BISON_BRIDGE */ +#endif /* YY_REENTRANT */ %ok-for-header #endif /* end if YY_REENTRANT */ @@ -621,7 +623,7 @@ int yyget_lineno YY_PARAMS(( YY_PROTO_ONLY_ARG )); void yyset_lineno YY_PARAMS(( int line_number YY_PROTO_LAST_ARG )); #endif -#ifdef YY_REENTRANT_BISON_PURE +#ifdef YY_BISON_BRIDGE #ifndef YY_NO_GET_LVAL YYSTYPE * yyget_lval YY_PARAMS(( YY_PROTO_ONLY_ARG )); #endif @@ -634,7 +636,7 @@ void yyset_lval YY_PARAMS(( YYSTYPE * yylvalp YY_PROTO_LAST_ARG )); void yyset_lloc YY_PARAMS(( YYLTYPE * yyllocp YY_PROTO_LAST_ARG )); #endif #endif /* YYLTYPE */ -#endif /* YY_REENTRANT_BISON_PURE */ +#endif /* YY_BISON_BRIDGE */ /* Macros after this point can all be overridden by user definitions in * section 1. @@ -792,7 +794,7 @@ struct yytbl_reader { /* If the bison pure parser is used, then bison will provide one or two additional arguments. */ -#ifdef YY_REENTRANT_BISON_PURE +#ifdef YY_BISON_BRIDGE # ifdef YYLTYPE # define YY_LEX_PROTO YY_PARAMS((YYSTYPE * yylvalp, YYLTYPE * yyllocp YY_PROTO_LAST_ARG)) # define YY_LEX_DECLARATION YYFARGS2(YYSTYPE *,yylvalp, YYLTYPE *,yyllocp) @@ -834,10 +836,18 @@ YY_DECL register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; +#ifdef YY_BISON_BRIDGE +# ifndef YY_REENTRANT + YYSTYPE * yylval; +# ifdef YYLTYPE + YYLTYPE * yylloc; +# endif +# endif +#endif %% [7.0] user's declarations go here -#ifdef YY_REENTRANT_BISON_PURE +#ifdef YY_BISON_BRIDGE yylval = yylvalp; #ifdef YYLTYPE yylloc = yyllocp; @@ -1798,21 +1808,24 @@ void yyFlexLexer::LexerError( yyconst char msg[] ) -#ifdef YY_REENTRANT - /* Accessor methods (get/set functions) to struct members. */ +%c-only +#ifdef YY_REENTRANT #ifndef YY_NO_GET_EXTRA YY_EXTRA_TYPE yyget_extra YYFARGS0(void) { return yyextra; } #endif /* !YY_NO_GET_EXTRA */ +#endif /* YY_REENTRANT */ #ifndef YY_NO_GET_LINENO int yyget_lineno YYFARGS0(void) { +#ifdef YY_USE_LINENO return yylineno; +#endif } #endif /* !YY_NO_GET_LINENO */ @@ -1844,12 +1857,14 @@ char *yyget_text YYFARGS0(void) } #endif /* !YY_NO_GET_TEXT */ +#ifdef YY_REENTRANT #ifndef YY_NO_SET_EXTRA void yyset_extra YYFARGS1( YY_EXTRA_TYPE ,user_defined) { yyextra = user_defined ; } #endif /* !YY_NO_SET_EXTRA */ +#endif /* YY_REENTRANT */ #ifndef YY_NO_SET_LINENO void yyset_lineno YYFARGS1( int ,line_number) @@ -1887,11 +1902,12 @@ void yyset_debug YYFARGS1( int ,bdebug) yy_flex_debug = bdebug ; } #endif /* !YY_NO_SET_DEBUG */ +%c-or-c++ - +#ifdef YY_REENTRANT /* Accessor methods for yylval and yylloc */ -#ifdef YY_REENTRANT_BISON_PURE +#ifdef YY_BISON_BRIDGE #ifndef YY_NO_GET_LVAL YYSTYPE * yyget_lval YYFARGS0(void) { @@ -1922,7 +1938,7 @@ void yyset_lloc YYFARGS1( YYLTYPE * ,yyllocp) #endif /* !YY_NO_SET_LLOC */ #endif /* YYLTYPE */ -#endif /* YY_REENTRANT_BISON_PURE */ +#endif /* YY_BISON_BRIDGE */ static int yy_init_globals YYFARGS0(void) @@ -2110,6 +2126,7 @@ static int yytbl_read32 (void *v, struct yytbl_reader * rd) return 0; } +/** Read the header */ static int yytbl_hdr_read YYFARGS2 (struct yytbl_hdr *, th, struct yytbl_reader *, rd) { int bytes; @@ -2141,6 +2158,8 @@ static int yytbl_hdr_read YYFARGS2 (struct yytbl_hdr *, th, struct yytbl_reader /* we read it all into th_version, and point th_name into that data */ if (fread (th->th_version, 1, bytes, rd->fp) != bytes){ errno = EIO; + free(th->th_version); + th->th_version = NULL; return -1; } else @@ -2377,44 +2396,82 @@ static int yytbl_data_load YYFARGS2 (struct yytbl_dmap *, dmap, struct yytbl_rea return 0; } +%define-yytables The name for this specific scanner's tables. /* Find the key and load the DFA tables from the given stream. */ int yytbl_load YYFARGS2 (FILE *, fp, const char *, key) { + int rv=0; struct yytbl_hdr th; struct yytbl_reader rd; rd.fp = fp; rd.bread = 0; + th.th_version = NULL; /* Keep trying until we find the right set of tables or end of file. */ while (!feof(rd.fp)) { - if (yytbl_hdr_read (&th, &rd YY_CALL_LAST_ARG) != 0) - return -1; + if (yytbl_hdr_read (&th, &rd YY_CALL_LAST_ARG) != 0){ + rv = -1; + goto return_rv; + } /* A NULL key means choose the first set of tables. */ if (key == NULL) break; - if (strcmp(th.th_name,key) != 0) + if (strcmp(th.th_name,key) != 0){ /* Skip ahead to next set */ fseek(rd.fp, th.th_ssize - th.th_hsize, SEEK_CUR); + free(th.th_version); + th.th_version = NULL; + } + else + break; } while (rd.bread < th.th_ssize){ /* Load the data tables */ - if(yytbl_data_load (yydmap,&rd YY_CALL_LAST_ARG) != 0) - return -1; + if(yytbl_data_load (yydmap,&rd YY_CALL_LAST_ARG) != 0){ + rv = -1; + goto return_rv; + } } - return 0; +return_rv: + if(th.th_version){ + free(th.th_version); + th.th_version = NULL; + } + + return rv; } -/* Load the DFA tables for this scanner from the given stream. */ +/** Load the DFA tables for this scanner from the given stream. */ int yytables_load YYFARGS1 (FILE *, fp) { - /* TODO: generate key "yytables" using prefix */ - yytbl_load(fp,NULL YY_CALL_LAST_ARG); + if( yytbl_load(fp, YYTABLES_NAME YY_CALL_LAST_ARG) != 0) + return -1; + return 0; +} + +/** Destroy the loaded tables, freeing memory, etc.. */ +int yytables_destroy YYFARGS0(void) +{ + struct yytbl_dmap *dmap=0; + + if(!YY_TABLES_VERIFY){ + /* Walk the dmap, freeing the pointers */ + for(dmap=yydmap; dmap->dm_id; dmap++) { + void * v; + v = dmap->dm_arr; + if(v && *(char**)v){ + free(*(char**)v); + *(char**)v = NULL; + } + } + } + return 0; } @@ -69,7 +69,6 @@ Reentrant C Scanners * Reentrant Overview:: * Reentrant Example:: * Reentrant Detail:: -* Bison Pure:: * Reentrant Functions:: The Reentrant API in Detail @@ -200,6 +199,7 @@ FAQ Appendices * Makefiles and Flex:: +* Bison Bridge:: Indices @@ -2370,6 +2370,21 @@ is used, the generated scanner will run faster (see the @samp{--perf-report} fla Only users who wish to squeeze every last cycle out of their scanners need worry about this option. (@pxref{Performance}). +@anchor{option-bison-bridge} +@item --bison-bridge, @code{%option bison-bridge} +instructs flex to generate a C scanner that is +meant to be called by a +@code{GNU bison} +parser. The scanner has minor API changes for +@code{bison} +compatibility. In particular, the declaration of +@code{yylex} +is modified, and support for +@code{yylval} +and +@code{yylloc} +is incorporated. @xref{Bison Bridge}. + @item -c is a do-nothing option included for POSIX compliance. @@ -2574,24 +2589,7 @@ reentrant and non-reentrant @code{flex} scanners, non-reentrant flex code must be modified before it is suitable for use with this option. This option is not compatible with the @samp{--c++} option. -@anchor{option-reentrant-bison} -@item -Rb, --reentrant-bison, @code{%option reentrant-bison} -instructs flex to generate a reentrant C scanner that is -meant to be called by a -@code{GNU bison} -pure parser. The scanner is the same as the scanner generated by the -@samp{--reentrant} -option, but with minor API changes for -@code{bison} -compatibility. In particular, the declaration of -@code{yylex} -is modified, and support for -@code{yylval} -and -@code{yylloc} -is incorporated. @xref{Bison Pure}. - -The options @samp{--reentrant} and @samp{--reentrant-bison} do not affect the performance of +The option @samp{--reentrant} does not affect the performance of the scanner. @anchor{option-trace} @@ -3558,20 +3556,17 @@ and may change considerably between major releases. @cindex reentrant, explanation @code{flex} has the ability to generate a reentrant C scanner. This is -accomplished by specifying @code{%option reentrant} (@samp{-R}) or -@code{%option reentrant-bison} (@samp{-Rb}). The generated scanner is -both portable, and safe to use in one or more separate threads of +accomplished by specifying @code{%option reentrant} (@samp{-R}) The generated +scanner is both portable, and safe to use in one or more separate threads of control. The most common use for reentrant scanners is from within -multi-threaded applications. Any thread may create and execute a -reentrant @code{flex} scanner without the need for synchronization with -other threads. +multi-threaded applications. Any thread may create and execute a reentrant +@code{flex} scanner without the need for synchronization with other threads. @menu * Reentrant Uses:: * Reentrant Overview:: * Reentrant Example:: * Reentrant Detail:: -* Bison Pure:: * Reentrant Functions:: @end menu @@ -3982,116 +3977,6 @@ an internal structure. You should never access this value directly. In particular, you should never attempt to free it (use @code{yylex_destroy()} instead.) - -@node Bison Pure -@section Reentrant C Scanners with Bison Pure Parsers - -@cindex bison, with reentrant -@vindex yylval -@vindex yylloc -@tindex YYLTYPE -@tindex YYSTYPE - -This section describes the @code{flex} features useful when integrating -@code{flex} with @code{GNU bison}@footnote{The features described here are -purely optional, and are by no means the only way to use flex with bison. -We merely provide some glue to ease development of your parser-scanner pair.}. -Skip this section if you are not using -@code{bison} with your scanner. Here we discuss only the @code{flex} -half of the @code{flex} and @code{bison} pair. We do not discuss -@code{bison} in any detail. For more information about generating pure -@code{bison} parsers, see @ref{Top, , , bison, the GNU Bison Manual}. - -A @code{bison}-compatible scanner is generated by declaring @samp{%option -reentrant-bison} or by supplying @samp{--reentrant-bison} when invoking @code{flex} -from the command line. This instructs @code{flex} that the macros -@code{yylval} and @code{yylloc} may be used. The data types for -@code{yylval} and @code{yylloc}, (@code{YYSTYPE} and @code{YYLTYPE}, -are typically defined in a header file, included in section 1 of the -@code{flex} input file. @code{%option reentrant-bison} implies -@code{%option reentrant}. If @code{%option reentrant-bison} is -specified, @code{flex} provides support for the functions -@code{yyget_lval}, @code{yyset_lval}, @code{yyget_lloc}, and -@code{yyset_lloc}, defined below, and the corresponding macros -@code{yylval} and @code{yylloc}, for use within actions. - -@deftypefun YYSTYPE* yyget_lval ( yyscan_t scanner ) -@end deftypefun -@deftypefun YYLTYPE* yyget_lloc ( yyscan_t scanner ) -@end deftypefun - -@deftypefun void yyset_lval ( YYSTYPE* lvalp, yyscan_t scanner ) -@end deftypefun -@deftypefun void yyset_lloc ( YYLTYPE* llocp, yyscan_t scanner ) -@end deftypefun - -Accordingly, the declaration of yylex becomes one of the following: - -@findex yylex (reentrant version) -@example -@verbatim - int yylex ( YYSTYPE * lvalp, yyscan_t scanner ); - int yylex ( YYSTYPE * lvalp, YYLTYPE * llocp, yyscan_t scanner ); -@end verbatim -@end example - -Note that the macros @code{yylval} and @code{yylloc} evaluate to -pointers. Support for @code{yylloc} is optional in @code{bison}, so it -is optional in @code{flex} as well. This support is automatically -handled by @code{flex}. Specifically, support for @code{yyloc} is only -present in a @code{flex} scanner if the preprocessor symbol -@code{YYLTYPE} is defined. The following is an example of a @code{flex} -scanner that is @code{bison}-compatible. - -@exindex bison, scanner to be called from bison -@example -@verbatim - /* Scanner for "C" assignment statements... sort of. */ - %{ - #include "y.tab.h" /* Generated by bison. */ - %} - - %option reentrant-bison - % - - [[:digit:]]+ { yylval->num = atoi(yytext); return NUMBER;} - [[:alnum:]]+ { yylval->str = strdup(yytext); return STRING;} - "="|";" { return yytext[0];} - . {} - % -@end verbatim -@end example - -As you can see, there really is no magic here. We just use -@code{yylval} as we would any other variable. The data type of -@code{yylval} is generated by @code{bison}, and included in the file -@file{y.tab.h}. Here is the corresponding @code{bison} parser: - -@exindex bison, parser -@example -@verbatim - /* Parser to convert "C" assignments to lisp. */ - %{ - /* Pass the argument to yyparse through to yylex. */ - #define YYPARSE_PARAM scanner - #define YYLEX_PARAM scanner - %} - %pure_parser - %union { - int num; - char* str; - } - %token <str> STRING - %token <num> NUMBER - %% - assignment: - STRING '=' NUMBER ';' { - printf( "(setf %s %d)", $1, $3 ); - } - ; -@end verbatim -@end example - @node Reentrant Functions @section Functions and Macros Available in Reentrant C Scanners @@ -4152,7 +4037,7 @@ In a reentrant C scanner, support for yylineno is always present the user to maintain the line count independently of @code{flex}. The following functions and macros are made available when @code{%option -reentrant-bison} (@samp{--reentrant-bison}) is specified: +bison-bridge} (@samp{--bison-bridge}) is specified: @example @verbatim @@ -7802,6 +7687,7 @@ then the problem is that the last rule needs to be "{whitespace}" ! @menu * Makefiles and Flex:: +* Bison Bridge:: @end menu @node Makefiles and Flex @@ -7913,6 +7799,117 @@ with your specific implementation of @command{make}. For more details on writing Makefiles, see @ref{Top, , , make, The GNU Make Manual}. +@node Bison Bridge +@section C Scanners with Bison Parsers + +@cindex bison, bridging with flex +@vindex yylval +@vindex yylloc +@tindex YYLTYPE +@tindex YYSTYPE + +This section describes the @code{flex} features useful when integrating +@code{flex} with @code{GNU bison}@footnote{The features described here are +purely optional, and are by no means the only way to use flex with bison. +We merely provide some glue to ease development of your parser-scanner pair.}. +Skip this section if you are not using +@code{bison} with your scanner. Here we discuss only the @code{flex} +half of the @code{flex} and @code{bison} pair. We do not discuss +@code{bison} in any detail. For more information about generating +@code{bison} parsers, see @ref{Top, , , bison, the GNU Bison Manual}. + +A compatible @code{bison} scanner is generated by declaring @samp{%option +bison-bridge} or by supplying @samp{--bison-bridge} when invoking @code{flex} +from the command line. This instructs @code{flex} that the macros +@code{yylval} and @code{yylloc} may be used. The data types for +@code{yylval} and @code{yylloc}, (@code{YYSTYPE} and @code{YYLTYPE}, +are typically defined in a header file, included in section 1 of the +@code{flex} input file. If @code{%option bison-bridge} is +specified, @code{flex} provides support for the functions +@code{yyget_lval}, @code{yyset_lval}, @code{yyget_lloc}, and +@code{yyset_lloc}, defined below, and the corresponding macros +@code{yylval} and @code{yylloc}, for use within actions. + +@deftypefun YYSTYPE* yyget_lval ( yyscan_t scanner ) +@end deftypefun +@deftypefun YYLTYPE* yyget_lloc ( yyscan_t scanner ) +@end deftypefun + +@deftypefun void yyset_lval ( YYSTYPE* lvalp, yyscan_t scanner ) +@end deftypefun +@deftypefun void yyset_lloc ( YYLTYPE* llocp, yyscan_t scanner ) +@end deftypefun + +Where yyscan_t is defined in the reentrant scanner @footnote{The bison bridge +works with non-reentrant scanners, too.}. Accordingly, the declaration of +yylex becomes one of the following: + +@findex yylex (reentrant version) +@example +@verbatim + int yylex ( YYSTYPE * lvalp, yyscan_t scanner ); + int yylex ( YYSTYPE * lvalp, YYLTYPE * llocp, yyscan_t scanner ); +@end verbatim +@end example + +Note that the macros @code{yylval} and @code{yylloc} evaluate to +pointers. Support for @code{yylloc} is optional in @code{bison}, so it +is optional in @code{flex} as well. This support is automatically +handled by @code{flex}. Specifically, support for @code{yyloc} is only +present in a @code{flex} scanner if the preprocessor symbol +@code{YYLTYPE} is defined. The following is an example of a @code{flex} +scanner that is compatible with @code{bison}. + +@exindex bison, scanner to be called from bison +@example +@verbatim + /* Scanner for "C" assignment statements... sort of. */ + %{ + #include "y.tab.h" /* Generated by bison. */ + %} + + %option reentrant-bison + % + + [[:digit:]]+ { yylval->num = atoi(yytext); return NUMBER;} + [[:alnum:]]+ { yylval->str = strdup(yytext); return STRING;} + "="|";" { return yytext[0];} + . {} + % +@end verbatim +@end example + +As you can see, there really is no magic here. We just use +@code{yylval} as we would any other variable. The data type of +@code{yylval} is generated by @code{bison}, and included in the file +@file{y.tab.h}. Here is the corresponding @code{bison} parser: + +@exindex bison, parser +@example +@verbatim + /* Parser to convert "C" assignments to lisp. */ + %{ + /* Pass the argument to yyparse through to yylex. */ + #define YYPARSE_PARAM scanner + #define YYLEX_PARAM scanner + %} + %pure_parser + %union { + int num; + char* str; + } + %token <str> STRING + %token <num> NUMBER + %% + assignment: + STRING '=' NUMBER ';' { + printf( "(setf %s %d)", $1, $3 ); + } + ; +@end verbatim +@end example + + @node Indices @unnumbered Indices @@ -413,7 +413,7 @@ __extension__ typedef unsigned long long int uint64_t; * C_plus_plus - if true (i.e., -+ flag), generate a C++ scanner class; * otherwise, a standard C scanner * reentrant - if true (-R), generate a reentrant C scanner. - * reentrant_bison_pure - if true (-Rb), bison pure calling convention. + * bison_bridge - if true (--bison-bridge), bison pure calling convention. * long_align - if true (-Ca flag), favor long-word alignment. * use_read - if true (-f, -F, or -Cr) then use read() for scanner input; * otherwise, use fread(). @@ -440,7 +440,7 @@ extern int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, extern int interactive, caseins, lex_compat, posix_compat, do_yylineno; extern int useecs, fulltbl, usemecs, fullspd; extern int gen_line_dirs, performance_report, backing_up_report; -extern int reentrant, reentrant_bison_pure; +extern int reentrant, bison_bridge; extern int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap; extern int csize; extern int yymore_used, reject, real_reject, continued_action, in_rule; @@ -1725,12 +1725,13 @@ void make_tables () /* End generating yy_NUL_trans */ } - if (ddebug) { /* Spit out table mapping rules to line numbers. */ - if (!C_plus_plus && !reentrant) { - indent_puts ("extern int yy_flex_debug;"); - indent_puts ("int yy_flex_debug = 1;\n"); - } + if (!C_plus_plus && !reentrant) { + indent_puts ("extern int yy_flex_debug;"); + indent_put2s ("int yy_flex_debug = %s;\n", + ddebug ? "1" : "0"); + } + if (ddebug) { /* Spit out table mapping rules to line numbers. */ out_str_dec (long_align ? get_int32_decl () : get_int16_decl (), "yy_rule_linenum", num_rules); @@ -54,7 +54,7 @@ int interactive, caseins, lex_compat, posix_compat, do_yylineno, int fullspd, gen_line_dirs, performance_report, backing_up_report; int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, csize; -int reentrant, reentrant_bison_pure; +int reentrant, bison_bridge; int yymore_used, reject, real_reject, continued_action, in_rule; int yymore_really_used, reject_really_used; int datapos, dataline, linenum, out_linenum; @@ -107,7 +107,7 @@ bool *rule_has_nl, *ccl_has_nl; int nlch = '\n'; bool tablesext, tablestoggle, tablesverify, gentables; -char *tablesfilename; +char *tablesfilename=0,*tablesname=0; struct yytbl_writer tableswr; /* Make sure program_name is initialized so we don't crash if writing @@ -208,9 +208,9 @@ void check_options () if (fulltbl || fullspd) flexerror (_("Can't use -f or -F with -l option")); - if (reentrant || reentrant_bison_pure) + if (reentrant || bison_bridge) flexerror (_ - ("Can't use -R or -Rb with -l option")); + ("Can't use --reentrant or --bison-bridge with -l option")); /* Don't rely on detecting use of yymore() and REJECT, * just assume they'll be used. @@ -274,8 +274,11 @@ void check_options () yytext_is_array = false; } - if (C_plus_plus && (reentrant || reentrant_bison_pure)) - flexerror (_("Options -+ and -R are mutually exclusive.")); + if (C_plus_plus && (reentrant)) + flexerror (_("Options -+ and --reentrant are mutually exclusive.")); + + if (C_plus_plus && bison_bridge) + flexerror (_("bison bridge not supported for the C++ scanner.")); if (useecs) { /* Set up doubly-linked equivalence classes. */ @@ -361,10 +364,9 @@ void check_options () yytbl_writer_init (&tableswr, tablesout); nbytes = strlen (prefix) + strlen ("tables") + 2; - pname = (char *) calloc (nbytes, 1); - sprintf (pname, "%stables", prefix); - yytbl_hdr_init (&hdr, flex_version, pname); - free (pname); + tablesname = (char *) calloc (nbytes, 1); + sprintf (tablesname, "%stables", prefix); + yytbl_hdr_init (&hdr, flex_version, tablesname); if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0) flexerror (_("could not write tables header")); @@ -379,8 +381,8 @@ void check_options () outn ("#define YY_TEXT_IS_ARRAY"); } - if (reentrant_bison_pure) - outn ("#define YY_REENTRANT_BISON_PURE 1"); + if ( bison_bridge) + outn ("#define YY_BISON_BRIDGE 1"); if (strcmp (prefix, "yy")) { #define GEN_PREFIX(name) out_str3( "#define yy%s %s%s\n", name, prefix, name ) @@ -423,7 +425,7 @@ void check_options () GEN_PREFIX ("realloc"); GEN_PREFIX ("free"); - outn ("#ifdef YY_REENTRANT_BISON_PURE"); + outn ("#ifdef YY_BISON_BRIDGE"); GEN_PREFIX ("get_lval"); GEN_PREFIX ("set_lval"); GEN_PREFIX ("get_lloc"); @@ -432,7 +434,7 @@ void check_options () } - if (do_yylineno && !reentrant) + if (!reentrant) GEN_PREFIX ("lineno"); if (do_yywrap) @@ -692,7 +694,7 @@ void flexend (exit_status) fprintf (header_out, "#undef YY_PROTO\n"); fprintf (header_out, "#undef YY_READ_BUF_SIZE\n"); fprintf (header_out, "#undef YY_REENTRANT\n"); - fprintf (header_out, "#undef YY_REENTRANT_BISON_PURE\n"); + fprintf (header_out, "#undef YY_BISON_BRIDGE\n"); fprintf (header_out, "#undef YY_RESTORE_YY_MORE_OFFSET\n"); fprintf (header_out, "#undef YY_RULE_SETUP\n"); fprintf (header_out, "#undef YY_SC_TO_UI\n"); @@ -845,12 +847,10 @@ void flexend (exit_status) putc ('p', stderr); if (spprdflt) putc ('s', stderr); - if (reentrant) { - putc ('R', stderr); - - if (reentrant_bison_pure) - putc ('b', stderr); - } + if (reentrant) + fputs ("--reentrant", stderr); + if (bison_bridge) + fputs ("--bison-bridge", stderr); if (use_stdout) putc ('t', stderr); if (printstats) @@ -1032,7 +1032,7 @@ void flexinit (argc, argv) yymore_really_used = reject_really_used = unspecified; interactive = csize = unspecified; do_yywrap = gen_line_dirs = usemecs = useecs = true; - reentrant = reentrant_bison_pure = false; + reentrant = bison_bridge = false; performance_report = 0; did_outfilename = 0; prefix = "yy"; @@ -1040,7 +1040,7 @@ void flexinit (argc, argv) use_read = use_stdout = false; tablesext = tablestoggle = tablesverify = false; gentables = true; - tablesfilename = NULL; + tablesfilename = tablesname = NULL; sawcmpflag = false; @@ -1205,27 +1205,16 @@ void flexinit (argc, argv) ++performance_report; break; - case OPT_REENTRANT_BISON: - reentrant = true; - reentrant_bison_pure = true; + case OPT_BISON_BRIDGE: + bison_bridge = true; break; case OPT_REENTRANT: reentrant = true; - - /* Optional 'b' follows -R */ - if (arg) { - if (strcmp (arg, "b") == 0) - reentrant_bison_pure = true; - else - lerrif (_ - ("unknown -R option '%c'"), - (int) arg[0]); - } break; case OPT_NO_REENTRANT: - reentrant = reentrant_bison_pure = false; + reentrant = false; break; case OPT_SKEL: @@ -1592,7 +1581,7 @@ void readin () else if (do_yylineno) { fprintf (stderr, _ - ("%%option yylineno entails a large performance penalty\n")); + ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n")); } if (performance_report > 1) { @@ -1705,12 +1694,10 @@ void readin () outn ("#define YY_FLEX_LEX_COMPAT"); if (!C_plus_plus && !reentrant) { - outn ("#ifdef YY_USE_LINENO"); outn ("extern int yylineno;"); OUT_BEGIN_CODE (); outn ("int yylineno = 1;"); OUT_END_CODE (); - outn ("#endif"); } if (C_plus_plus) { @@ -1900,7 +1887,7 @@ void usage () " -L, --noline suppress #line directives in scanner\n" " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n" " -R, --reentrant generate a reentrant C scanner\n" - " -Rb, --reentrant-bison reentrant scanner for bison pure parser.\n" + " --bison-bridge scanner for bison pure parser.\n" " --stdinit initialize yyin/yyout to stdin/stdout\n" " --nounistd do not include <unistd.h>\n" " --noFUNCTION do not generate a particular FUNCTION\n" @@ -37,6 +37,7 @@ #define CMD_TABLES_SER_BEGIN "%tables-serialization-code-begin" #define CMD_TABLES_SER_END "%tables-serialization-code-end" #define CMD_TABLES_YYDMAP "%tables-yydmap" +#define CMD_DEFINE_YYTABLES "%define-yytables" #define CMD_CPP_ONLY "%c++-only" #define CMD_C_ONLY "%c-only" #define CMD_C_OR_CPP "%c-or-c++" @@ -835,6 +836,8 @@ void skelout () /* We've been accused of using cryptic markers in the skel. * So we'll use emacs-style-hyphenated-commands. + * We might consider a hash if this if-else-if-else + * chain gets too large. */ #define cmd_match(s) (strncmp(buf,(s),strlen(s))==0) @@ -852,6 +855,10 @@ void skelout () if (tablesext && yydmap_buf.elts) outn ((char *) (yydmap_buf.elts)); } + else if (cmd_match (CMD_DEFINE_YYTABLES)) { + out_str("#define YYTABLES_NAME \"%s\"\n", + tablesname?tablesname:"yytables"); + } else if (cmd_match (CMD_CPP_ONLY)) { /* only for C++ */ do_copy = C_plus_plus; @@ -66,6 +66,8 @@ optspec_t flexopts[] = { , {"--batch", OPT_BATCH, 0} , /* Generate batch scanner (opposite of -I). */ + {"--bison-bridge", OPT_BISON_BRIDGE, 0} + , /* Scanner to be called by a bison pure parser. */ {"-i", OPT_CASE_INSENSITIVE, 0} , {"--case-insensitive", OPT_CASE_INSENSITIVE, 0} @@ -157,14 +159,14 @@ optspec_t flexopts[] = { , /* Define a preprocessor symbol. */ {"--read", OPT_READ, 0} , /* Use read(2) instead of stdio. */ - {"-R[b]", OPT_REENTRANT, 0} + {"-R", OPT_REENTRANT, 0} , {"--reentrant", OPT_REENTRANT, 0} , /* Generate a reentrant C scanner. */ {"--noreentrant", OPT_NO_REENTRANT, 0} , - {"--reentrant-bison", OPT_REENTRANT_BISON, 0} - , /* Reentrant scanner to be called by a bison pure parser. */ + {"--reentrant-bison", OPT_BISON_BRIDGE, 0} + , /* Deprecated. Replaced by --bison-bridge */ {"--reject", OPT_REJECT, 0} , {"--noreject", OPT_NO_REJECT, 0} @@ -47,6 +47,7 @@ enum flexopt_flag_t { OPT_ARRAY, OPT_BACKUP, OPT_BATCH, + OPT_BISON_BRIDGE, OPT_CASE_INSENSITIVE, OPT_COMPRESSION, OPT_CPLUSPLUS, @@ -106,7 +107,6 @@ enum flexopt_flag_t { OPT_PREPROCDEFINE, OPT_READ, OPT_REENTRANT, - OPT_REENTRANT_BISON, OPT_REJECT, OPT_SKEL, OPT_STACK, @@ -259,6 +259,7 @@ LEXOPT [aceknopr] array yytext_is_array = option_sense; backup backing_up_report = option_sense; batch interactive = ! option_sense; + bison-bridge bison_bridge = option_sense; "c++" C_plus_plus = option_sense; caseful|case-sensitive caseins = ! option_sense; caseless|case-insensitive caseins = option_sense; @@ -291,11 +292,6 @@ LEXOPT [aceknopr] pointer yytext_is_array = ! option_sense; read use_read = option_sense; reentrant reentrant = option_sense; - reentrant-bison { - /* reentrant-bison implies reentrant. */ - if ((reentrant_bison_pure = option_sense) != 0) - reentrant = 1; - } reject reject_really_used = option_sense; stack action_define( "YY_STACK_USED", option_sense ); stdinit do_stdinit = option_sense; @@ -55,12 +55,13 @@ struct yytbl_writer { * tablesext - if true, create external tables * tablestoggle - if true, output external tables code while processing skel * tablesfilename - filename for external tables + * tablesname - name that goes in serialized data, e.g., "yytables" * tableswr - writer for external tables * tablesverify - true if tables-verify option specified * gentables - true if we should spit out the normal C tables */ extern bool tablesext, tablestoggle, tablesverify,gentables; -extern char *tablesfilename; +extern char *tablesfilename, *tablesname; extern struct yytbl_writer tableswr; int yytbl_writer_init (struct yytbl_writer *, FILE *); diff --git a/tests/Makefile.am b/tests/Makefile.am index 75232ef..19a168a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,8 +26,8 @@ noinst_SCRIPTS = \ create-test SUBDIRS = \ + test-bison-nr \ test-c++-basic \ - test-table-opts \ test-posixly-correct \ test-posix \ test-mem-r \ @@ -56,7 +56,8 @@ SUBDIRS = \ test-pthread \ test-string-nr \ test-string-r \ - test-yyextra + test-yyextra \ + test-table-opts # clean up before running the test suite so we dont test old builds of test code diff --git a/tests/descriptions b/tests/descriptions index 0066025..90e8420 100644 --- a/tests/descriptions +++ b/tests/descriptions @@ -5,6 +5,7 @@ array-nr - Use %option array, non-reentrant. array-r - Use %option array, reentrant. basic-nr - Simple scanner, non-reentrant. basic-r - Simple scanner, reentrant. +bison-nr - Ordinary bison-bridge. bison-yylloc - Reentrant scanner + pure parser. Requires bison. bison-yylval - Reentrant scanner + pure parser. Requires bison. c-cpp-nr - Compile a C scanner with C++ compiler, nonreentrant. diff --git a/tests/test-bison-yylloc/scanner.l b/tests/test-bison-yylloc/scanner.l index ed22fe8..0ae65ed 100644 --- a/tests/test-bison-yylloc/scanner.l +++ b/tests/test-bison-yylloc/scanner.l @@ -32,7 +32,7 @@ static char* STRDUP(char* s1); %} %option 8bit outfile="scanner.c" prefix="test" -%option reentrant-bison yylineno +%option reentrant bison-bridge yylineno %option nomain nounput noyy_top_state noyywrap nodefault warn %option prefix="test" header="scanner.h" diff --git a/tests/test-bison-yylval/scanner.l b/tests/test-bison-yylval/scanner.l index 1af8db3..7e902f7 100644 --- a/tests/test-bison-yylval/scanner.l +++ b/tests/test-bison-yylval/scanner.l @@ -34,7 +34,7 @@ enum yesno_t { no=0, yes=1 }; %} %option 8bit outfile="scanner.c" prefix="test" -%option reentrant-bison +%option reentrant bison-bridge %option noyywrap nomain nounput noyy_top_state noyywrap nodefault warn %option prefix="test" header="scanner.h" %option stack diff --git a/tests/test-table-opts/scanner.l b/tests/test-table-opts/scanner.l index 9efd49f..4a3bf95 100644 --- a/tests/test-table-opts/scanner.l +++ b/tests/test-table-opts/scanner.l @@ -66,6 +66,10 @@ int main ( int argc, char** argv ) } while(yylex(YY_CALL_ONLY_ARG) != 0) ; + +#ifdef YY_TABLES_EXTERNAL + yytables_destroy(YY_CALL_ONLY_ARG); +#endif yylex_destroy(YY_CALL_ONLY_ARG); if(argc < 0) /* silence the compiler */ |