]> granicus.if.org Git - flex/commitdiff
Bison bridge code now works for all C scanners and pure/non-pure bison parsers.
authorJohn Millaway <john43@users.sourceforge.net>
Fri, 13 Sep 2002 01:17:22 +0000 (01:17 +0000)
committerJohn Millaway <john43@users.sourceforge.net>
Fri, 13 Sep 2002 01:17:22 +0000 (01:17 +0000)
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.

16 files changed:
configure.in
flex.skl
flex.texi
flexdef.h
gen.c
main.c
misc.c
options.c
options.h
scan.l
tables.h
tests/Makefile.am
tests/descriptions
tests/test-bison-yylloc/scanner.l
tests/test-bison-yylval/scanner.l
tests/test-table-opts/scanner.l

index 352f61af7390de7909fefdbb10858fac3bb24696..54945c72f805e14e16f50c4cb87f255c60d1697b 100644 (file)
@@ -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.
 )
 
index c12868580811a1ba9f463043b3bb714cffe0ca18..f6eeacd4a10354049120de8640ffbfc42c9906a4 100644 (file)
--- a/flex.skl
+++ b/flex.skl
@@ -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;
 }
 
index 87ab079e2e9a2c92b9116f7771adaca9aa994eb8..d183347959166da0a662d0bc4f2f7d84812162b8 100644 (file)
--- a/flex.texi
+++ b/flex.texi
@@ -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
 
index ad346c13fb4848ffcb68d89213060f78620640a1..84867b20abb19bfce7c8a2c31e7e102c4879debb 100644 (file)
--- a/flexdef.h
+++ b/flexdef.h
@@ -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;
diff --git a/gen.c b/gen.c
index 885f6fe7781d78271543433c5d7cc8bf8ffc09d5..2a634a13f2dae05410ce8f91edc192c11c83f48b 100644 (file)
--- a/gen.c
+++ b/gen.c
@@ -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);
diff --git a/main.c b/main.c
index 7524f08dbef48c35033dec904741909d68f419b9..19ed11bb16f68bb8c3a7ba3c374488e2252e7815 100644 (file)
--- a/main.c
+++ b/main.c
@@ -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"
diff --git a/misc.c b/misc.c
index b73f13d0b904b7abc9dcb75e75d7b1cea9381f90..20a284c7486b7b085f06d00229fd24cb48182387 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -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;
index 6d43014b341d96d4bb7cf32f98499e8d99f269c2..99cacf92e13c0016d72d763e07cda16178f86b60 100644 (file)
--- a/options.c
+++ b/options.c
@@ -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}
index fdb54231c8bafefe23a1c65e3344bd0729669aa5..3cdbfe35aa3c82be85c1bd148169affee20fdb0b 100644 (file)
--- a/options.h
+++ b/options.h
@@ -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,
diff --git a/scan.l b/scan.l
index 31d93efee309c09c029623406ee1e1ee9ea801ca..7d5530fce654192f7cfb27644d4a88fdd9d896c0 100644 (file)
--- a/scan.l
+++ b/scan.l
@@ -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;
index 35289519c24a382a1c0dafdf4ce39405065f98da..87326ed7d9df1c811d3fd140db4c8400c2599493 100644 (file)
--- a/tables.h
+++ b/tables.h
@@ -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 *);
index 75232efa81cb6a782fb085c3a7feedb6bc68ee55..19a168a9a58bd04ddc8de9e42dc5c25ba73ec38e 100644 (file)
@@ -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
 
index 00660258afb6a2cce25d9f38eaba82f5ce7172ac..90e842047b758187473a6d6e3ae96553b0abcb31 100644 (file)
@@ -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.
index ed22fe8baa8eb6bf9b34220f6d64851053925731..0ae65ed32bc45ea3b6704a6d83146461396ffe19 100644 (file)
@@ -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"
 
index 1af8db3561692be1d2b17282f00f375a1626f17d..7e902f764c0f85547722d54eb3c42ec494d23b24 100644 (file)
@@ -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
index 9efd49f367c733fbcb5a4d25a026b9629c0e9b86..4a3bf9596542c36e76123ff136e3f2fb5df30d2b 100644 (file)
@@ -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 */