Re: flex c++ question

Thomas Buecher <buecher@swt.ruhr-uni-bochum.de>
27 May 1997 23:47:14 -0400

          From comp.compilers

Related articles
flex c++ question moleary@primus.com (Michael O'Leary) (1997-05-22)
Re: flex c++ question buecher@swt.ruhr-uni-bochum.de (Thomas Buecher) (1997-05-27)
| List of all articles for this month |

From: Thomas Buecher <buecher@swt.ruhr-uni-bochum.de>
Newsgroups: comp.compilers
Date: 27 May 1997 23:47:14 -0400
Organization: Ruhr-Universitaet Bochum, Rechenzentrum
References: 97-05-271
Keywords: lex, C++

Michael O'Leary wrote:


> ........ I am wondering if there is a way to continue having the
> tokenizer be defined as a c++ class and enable the yacc (actually
> bison) parser to access it without recourse to global variables. The
> parser's yyparse function calls yylex, but a c++-based flex
> tokenizer gets its input (as I understand it) from
> MyClass::LexerInput. I could define yylex to call LexerInput, but it
> looks like I would have to define a global variable of type MyClass
> and use it within yylex to make the call to LexerInput for this to
> work. Is this true, or have I perhaps misunderstood how the
> integration of lex and yacc works? Otherwise, has any version of
> yacc or any of its variants been provided with c++ features in the
> way that flex has in a way that would enable them to work together
> without recourse to such things as global variables? Thanks for any
> advice you can provide.


Hi !


Like with flex for yacc (bison) also exists an c++ version, called
bison++ (or bison_pp for Windows). Using this c++ generating version
of yacc, there is no need for global variables merely serving for
parser - scanner communications. bison++ generates a c++ parser
class, that can be configured by means of various macro like %define
... statements. By defining LEX_BODY = 0, a pure virtual
yylex-function will be used for information interchange among parser
and scanner. To do so, you need a derived class that inherits from
the generated scanner and generated parser class (multiple
inheritance). The redifinition of the virtual int yylex function in
the derived class (just calling ScannerClass::yylex(..)) implements
the necessary communications. For accessing the data read by the
scanner the parser may pass a structure to the the yylex(..)
function. Through the use of virtual functions (redefined in the
compiler class for redirecting the function calls to the desired base
class), the information-interchange between scanner and parser can
easily be realised.


The advantage of this architecture is, that you actually do not need
any global variables. You can use an automatic or dynamically created
compiler-class instance, that can be destroyed when finishing parsing.


Thomas Buecher
buecher@swt.ruhr-uni-bochum.de
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.