[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Flex & Bison under C++
From: |
Hans Aberg |
Subject: |
Re: Flex & Bison under C++ |
Date: |
Wed, 30 Oct 2002 11:40:32 +0100 |
At 18:23 -0500 2002/10/29, John Millaway wrote:
>> The main objective is to have a scanner that compiles correctly
>> under C++ so that one can use C++ actions.
>>
>You can put C++ actions in the C scanner, then simply compile the
>scanner with a C++ compiler.
This is the naive starting point we started with on the Bison parser. Then
the stacks breaks, so one must write special C++ skeleton anyway. Then one
can just as well take advantage of the other C++ features available. Then
that pulls the want for a Flex C++ scanner.
>> The next objective is for convenience to wrap this up in a class
>> pure interface using namespaces, so it fits together with all the
>> other code one writes in C++.
>>
>The prefix is your namespace, i.e., "yylex()" is logically equivalent
>to "yy::lex()",
Right, that is what one wants to avoid under C++, as there is a "namespace"
construction.
>> When using Bison, it is imperative to...
>>
>I'm ignoring the bison issues, and focusing on flex.
Well, is Flex a program that is always to be used without a parser?
>> Such factors then pulls the need and want for a Bison parser C++
>> class which is class pure. And if one would want to use Flex, one
>> wants it to conveniently interface Bison.
>>
>A bison parser class can call a reentrant C scanner without any
>problems.
I haven't experimented with that pure lexer. -- But some scanner data
should be external to it, but logically localized in a lexer class.
Even though one might make workarounds, that is not the same thing as it is
convenient.
>> I can immediately note though that it defines a lot of macros. Under
>> C++, one does not want to have a lot of macros, as the names can be
>> wrapped up in a C++ namespace.
>>
>The macros would be present in the C++ scanner, too.
Right, that is what one wants to avoid, as C++ has language constructs
intended to substitute the need for macros.
> Also, none of
>flex's macros are exported -- they are used within the scanner, not
>from the calling function.
The advantage is that they are exported, at least to the debugger. Then C++
is such that despite that, the names cannot clash.
>> Also, my parser/lexer combination uses variables that are global to
>> the lexer, but local to the parser.
>>
>I'm not sure what you mean by this. Either a variable is global or
>it's not. But either way, the reentrant C scanner doesn't use any
>non-const globals.
I mean that it should be class local but not function local. This happens
if the lexer say have a variable that sets context which should not be
reinitialized form scan to scan. (Or take a token pipe, if you want a more
advanced example.)
Then one gets say:
class lexer {
public:
token_type context;
token_type lex(semantic_type&);
...
};
The parser will initialize the lexer, and get one copy of lexer::context,
and different initializations will get different copies as they should.
One can put the variable lexer::context in the parser class, or pass it
through the argument of lexer::lex.
But such solutions are only makeshift, if the variable logically does not
belong to the parser, but to the lexer:
Usually, when programming OO, like in C++, one realizes after a while that
certain components belong together. It then becomes annoying if the system
forces one to do workarounds.
Hans Aberg