[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bison/flex compatibility revisited

From: Bruce Lilly
Subject: Re: Bison/flex compatibility revisited
Date: Wed, 26 Feb 2003 18:52:18 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021130

John wrote:
    y.tab.c: In function `yyparse':
    y.tab.c:4321: warning: implicit declaration of function `yylex'

The solution to the above error is the same as it has always been for
bison code.  You must predeclare yylex. The following line of code in
your bison input will suffice:

    extern int yylex(void);

That's incorrect for a reentrant lexical analyzer.
It's also pointless if the lexical analyzer entry point
is named foolex rather than yylex.

2. Flex header generated and included by parser, but w/o the
  magic #define YY_HEADER_NO_UNDEFS (or equivalent) before the

  Same compilation warnings as above, same consequences.  However,
  there is the potential for *some* name-space clashes, as *some*
  of the flex-defined names are visible (e.g. YY_FLEX_SUBMINOR_VERSION,
  which is a recent addition that probably was overlooked; there
  are others).

By defining YY_HEADER_NO_UNDEFS, you are explicitly asking flex not to
clean up the YY namespace. I don't see how this is a bug if you ask
for flex to leave all the YY_* garbage in your namespace.

The specific case described is where that is NOT defined, and
yet some YY macros remain defined, while yylex is not.

The only way (currently) to make the yylex declaration that is in
the flex-generated header visible (and the macro renaming it if
flex's prefix option is used) is to define YY_HEADER_NO_UNDEFS prior
to the inclusion, and that's the next scenario

This is entirely incorrect. The declaration of yylex is visible
without having to do any macro tricks.

From a flex-generated header using flex 2.5.28 as of the 2003-02-23

$ egrep 'yylex([^_.]|$)' mailflex.h
#define yylex maillex
extern int yylex YY_LEX_PROTO;
#define YY_DECL int yylex YY_LEX_DECLARATION
#undef yylex
$ cat foo.c
#define YYSTYPE void

#include "mailflex.h"

int foo(void) {
    YYSTYPE *x;

    return yylex(x);
$ cc -c foo.c
$ nm -e foo.o
00000000 T foo
00000000 t gcc2_compiled.
         U yylex

There's no call to maillex there, because, as I said, yylex
is undef'ed.  A declaration to the wrong function isn't
much use.  See the #undef line that egrep found.  Consider
foo.c to be a very condensed version of what bison generates.

4. For whatever reason, the programmer doesn't care about the
   yylex macro or prototype, but needs start condition definitions

There is a macro YY_HEADER_EXPORT_START_CONDITIONS for this explicit

OK, you're right on that one, YY_HEADER_NO_UNDEFS is not
also required if only start conditions are needed.

Aside from that, from my perspective it would be nice to
have some degree of control over what is exposed by the
flex-generated header, rather than the current basically
all-or-nothing choice.

You currently have these options:
  1. Expose only the documented flex API function -- NO MACROS.
  2. Expose ALL macros -- why anyone wants this I have no idea.
  3. Expose the start conditions.

What more control do you want? Anything else is an internal flex macro
and is not exposed -- nor should it be.

If a prefix is used to rename yylex to foolex or something
similar, it would be nice if the caller need only specify
"yylex", as bison does, and still have that work with the
flex header to get the correct foolex() call without having
to expose everything. See the foo.c example above.

If I put C code called by lexical analyzer pattern actions
in a separate module (a.k.a. file) and need to refer to
yyin, yyout, etc. I need that to be able to work,
whether the lexical analyzer is reentrant or not and whether
a prefix other than yy is specified or not.  In that case I
can probably live with having to expose everything to do that,
but I can imagine a situation where a programmer may wish to
refer to yyout in a parser, and exposing everything there may
lead to problems.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]