diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2020-10-10 17:21:11 -0400 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2020-10-10 17:21:11 -0400 |
commit | 0d1959c5956173060389021e931091269af6216e (patch) | |
tree | d40c210553c52b9d267038cdad3a102afed10123 | |
parent | 76affdf8942bf5627a815edcb486f9dcc3067ae6 (diff) | |
download | flex-git-0d1959c5956173060389021e931091269af6216e.tar.gz |
Implement and document %yydecl directive to replace #define YY_DECL.
Also added a deprecation note abut the old mechanism.
-rw-r--r-- | doc/flex.texi | 47 | ||||
-rw-r--r-- | src/cpp-flex.skl | 2 | ||||
-rw-r--r-- | src/flexdef.h | 1 | ||||
-rw-r--r-- | src/main.c | 12 | ||||
-rw-r--r-- | src/scan.l | 1 | ||||
-rwxr-xr-x | tests/test-yydecl | 14 |
6 files changed, 46 insertions, 31 deletions
diff --git a/doc/flex.texi b/doc/flex.texi index 337de10..5c6c04e 100644 --- a/doc/flex.texi +++ b/doc/flex.texi @@ -259,7 +259,6 @@ FAQ * unnamed-faq-99:: * unnamed-faq-100:: * unnamed-faq-101:: -* What is the difference between YYLEX_PARAM and YY_DECL?:: * Why do I get "conflicting types for yylex" error?:: * How do I access the values set in a Flex action from within a Bison action?:: @@ -1474,22 +1473,21 @@ default, @code{yylex()} is declared as follows: @end verbatim @end example -@cindex yylex(), overriding +@cindex yylex(), overriding, %yydecl (If your environment supports function prototypes, then it will be -@code{int yylex( void )}.) This definition may be changed by defining -the @code{YY_DECL} macro. For example, you could use: +@code{int yylex( void )}.) This definition may be changed with the +the @code{%yydecl} directive. For example, you could put this in +among your directives: @cindex yylex, overriding the prototype of @example @verbatim - #define YY_DECL float lexscan( a, b ) float a, b; +%yydecl float lexscan(float a, float b) @end verbatim @end example to give the scanning routine the name @code{lexscan}, returning a float, -and taking two floats as arguments. Note that if you give arguments to -the scanning routine using a K&R-style/non-prototyped function -declaration, you must terminate the definition with a semi-colon (;). +and taking two floats as arguments. @code{flex} generates @samp{C99} function definitions by default. Flex used to have the ability to generate obsolete, er, @@ -4734,7 +4732,7 @@ YY_AT_BOL() @item <*> @item -YY_DECL +%yydecl @item YY_START @item @@ -5514,7 +5512,6 @@ publish them here. * unnamed-faq-99:: * unnamed-faq-100:: * unnamed-faq-101:: -* What is the difference between YYLEX_PARAM and YY_DECL?:: * Why do I get "conflicting types for yylex" error?:: * How do I access the values set in a Flex action from within a Bison action?:: @end menu @@ -6766,6 +6763,9 @@ for sure won't be for many months to come). @c TODO: Evaluate this faq. @node ERASEME55 @unnumberedsec ERASEME55 +(Note: The @code{YY_DECL} macro is deprecated. Use the @code{%yydecl} +option instead.) + @example @verbatim To: Colin Paul Adams <colin@colina.demon.co.uk> @@ -8131,27 +8131,12 @@ then the problem is that the last rule needs to be "{whitespace}" ! @end verbatim @end example -@node What is the difference between YYLEX_PARAM and YY_DECL? -@unnumberedsec What is the difference between YYLEX_PARAM and YY_DECL? - -YYLEX_PARAM is not a flex symbol. It is for Bison. It tells Bison to pass extra -params when it calls yylex() from the parser. - -YY_DECL is the Flex declaration of yylex. The default is similar to this: - -@example -@verbatim -#define int yy_lex () -@end verbatim -@end example - - @node Why do I get "conflicting types for yylex" error? @unnumberedsec Why do I get "conflicting types for yylex" error? This is a compiler error regarding a generated Bison parser, not a Flex scanner. It means you need a prototype of yylex() in the top of the Bison file. -Be sure the prototype matches YY_DECL. +Be sure the prototype matches what you declarted with @code{%yydecl}. @node How do I access the values set in a Flex action from within a Bison action? @unnumberedsec How do I access the values set in a Flex action from within a Bison action? @@ -8719,9 +8704,10 @@ so will hinder forward portability someday. These changes are necessary because the documented Flex interface can no longer rely on controlling scanner generation by defining preprocessor macros. Most languages other than C/C++ don't have text -macros, and none of those that do emulate C #define. Thus, interface -calls need to be functions, at least syntactically (though many are -still implemented as macros for C/C++). +macros, and none of those that do emulate C #define closely enough to +preserve the behavior dependent on it. Thus interface calls in +multi-language Flex need to be functions, at least syntactically +(though many are still implemented as macros for C/C++). A list of deprecated interfaces and their replacements follows. Again, all are still available in the default C/C++ back end, but not @@ -8736,6 +8722,9 @@ ECHO: Replaced by yyecho() @item REJECT: Replaced by yyreject() + +@item +YY_DECL: Replaced by the %yydecl directive. @end itemize @node Indices, , Appendices, Top diff --git a/src/cpp-flex.skl b/src/cpp-flex.skl index 1eced3d..59a717e 100644 --- a/src/cpp-flex.skl +++ b/src/cpp-flex.skl @@ -89,6 +89,8 @@ m4_define([[M4_HOOK_EOF_STATE_CASE_TERMINATE]], [[ yyterminate(); m4_define([[M4_HOOK_CONST_DEFINE]], [[#define $1 $2 ]]) +m4_define([[M4_HOOK_SET_YY_DECL]], [[#define YY_DECL $1]]) + %% [0.0] Make hook macros available to Flex %not-for-header diff --git a/src/flexdef.h b/src/flexdef.h index d2d61cb..10bc90f 100644 --- a/src/flexdef.h +++ b/src/flexdef.h @@ -351,6 +351,7 @@ struct ctrl_bundle_t { bool use_read; // (-f, -F, or -Cr) use read() for scanner input // otherwise, use fread(). char *yyclass; // yyFlexLexer subclass to use for YY_DECL + char *yydecl; // user-specfied prototype for yylex. bool yytext_is_array; // if true (i.e., %array directive), then declare // yytext as array instead of a character pointer. // Nice and inefficient. @@ -1280,12 +1280,20 @@ void readin (void) /* Place a bogus line directive, it will be fixed in the filter. */ line_directive_out(0, false); + /* User may want to set the scanner prototype */ + if (ctrl.yydecl != NULL) { + char *cp; + for (cp = ctrl.yydecl; isspace(*cp); cp++) + continue; + out_str ("M4_HOOK_SET_YY_DECL(%s)\n", cp); + } + /* Dump the user defined preproc directives. */ if (userdef_buf.elts) outn ((char *) (userdef_buf.elts)); /* If the user explicitly requested posix compatibility by specifing the - * posix-compat option, then we check for conflicting ctrl. However, if + * posix-compat option, then we check for conflicting options. However, if * the POSIXLY_CORRECT variable is set, then we quietly make flex as * posix-compatible as possible. This is the recommended behavior * according to the GNU Coding Standards. @@ -1295,7 +1303,7 @@ void readin (void) */ if (ctrl.posix_compat) { /* TODO: This is where we try to make flex behave according to - * posiz, AND check for conflicting ctrl. How far should we go + * POSIX, *and* check for conflicting ctrl. How far should we go * with this? Should we disable all the neat-o flex features? */ /* Update: Estes says no, since other flex features don't violate posix. */ @@ -194,6 +194,7 @@ M4QEND "]""]" ^"%pointer".*{NL} ctrl.yytext_is_array = false; ++linenum; ^"%array".*{NL} ctrl.yytext_is_array = true; ++linenum; + ^"%yydecl".* ctrl.yydecl = xstrdup(yytext+7); ^"%option" BEGIN(OPTION); return TOK_OPTION; diff --git a/tests/test-yydecl b/tests/test-yydecl new file mode 100755 index 0000000..1b4efad --- /dev/null +++ b/tests/test-yydecl @@ -0,0 +1,14 @@ +#! /bin/sh +# Test %yydecl option of flex in any cpp-based back end + +trap 'rm /tmp/td$$' EXIT HUP INT QUIT TERM +cat >/tmp/td$$ <<EOF +%yydecl int foobar(void) +%% +%% +EOF + +( ../src/flex -t /tmp/td$$ | grep "#define YY_DECL int foobar(void)" >/dev/null ) || (echo "%yydecl test failed." >&2; exit 1) + + + |