bug-bison
[Top][All Lists]
Advanced

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

Re: beta testing


From: Philippe Bekaert
Subject: Re: beta testing
Date: Tue, 20 Feb 2001 23:43:31 +0100

Hans Aberg wrote:

> For C++, there are two version though that comes to my mind: yyparse is
> impure but its external variables are local to the class, and where yyparse
> itself is pure, and thus all variables local to yyparse.
> 
> The first version suffices as a thread-safe version, if one only makes sure
> there are no two instantiations of yyparse on the _same_ parse object.
> Thus, write
>   Parse p1, p2;
>   p1.parse(); first invocation of yyparse
>   p2.parse(); second invocation of yyparse
> 
> -- Thus, for C++, some data may end up in the class declaration, and other
> in its definition. Some of it may then be user data (or methods), and one
> problem is how the user should get that data into the class declaration, if
> it say is going to happen via the .y file.
> 
>   One may have to divide the first %{ ... %} into two sections, where the
> first section writes it into the class declaration.
What about providing two base classes from which parser classes shall be
derived:

class PureBisonParser {
public:
  virtual void yyparse(void);
  virtual void yyerror( ... );
};

class BisonParser: public PureBisonParser {
public:
  // all global variables of a non-pure parser come here
};

Someone writing a parser declares then

class MyParser: public BisonParser {
public:
  void yyparse(void);
};

Or if you want, like me, the parser also to inherit from the scanner
cless generated by flex, you get

class MyParser: public BisonParser, public MyScanner {
public:
  ...
};

where MyScanner inherits from FlexLexer, for instance:

#include "y.tab.h"
class MyScanner: public FlexLexer {
public:
  int yylex(YYSTYPE *lvalp);
};

(The advantage of doing so is that each parser object also has its own
private copy of all lex variables and functions)

OR if the parser is a pure parser, it shall be declared as

class MyParser: public PureBisonParser {
...
};

The one who writes the parser knows whether it is a pure or non-pure
parser, of course - I don't think we are asking much to derive his
parser form the right base class.

All you need in order to do such things with bison are:

Pure parser:

- get rid of the forward declaration of yyparse()
- redefine yyparse as MyParser::yyparse()

Non-pure parser: in addition to the above:

- get rid of the global declarations of yychar, ...
- redefine yychar ... as BisonParser::yychar

Philippe.

Btw:

  #ifndef my_project_h
  #define my_project_h
  class my_type {
  public:
    ...
  };
  #define YYSTYPE my_type
  #endif /* my_project_h */

If you change the union declaration in the bison script, my_type will
not be automatically updated. This can be dangerous.

Ideally, there should be a switch so bison does not generate the YYSTYPE
union declaration in y.tab.c, but only in y.tab.h.

-- 
Philippe Bekaert
Post-doctoral Research Fellow
Max-Planck-Institut fuer Informatik
Im Stadtwald, Geb. 46.1
66123 Saarbruecken - Germany
+49 681 9325422 (office phone)
+49 681 9325499 (office fax)
+49 179 4503121 (private phone)



reply via email to

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