Thanks for your help Akim! I've been using Bison for a while now without issues (except for building from sources, but I'll write a separate email about that later).
--- Best regards, Wouter Beek. Email: wou...@triply.cc WWW: https://triply.cc Tel: +31647674624 On Tue, Dec 4, 2018 at 6:30 AM Akim Demaille <a...@lrde.epita.fr> wrote: > > Hi Wouter! > > > Le 3 déc. 2018 à 22:38, Wouter Beek <wou...@triply.cc> a écrit : > > > > Dear Bison devs, > > > > I really like the recent developments in Bison 3.1 and 3.2 that improve the > > support for modern C++ programming techniques. > > Thanks for saying this! > > > As a result, I'm writing my > > first C++ Bison parser, but run into some issues that may or may not be > > limitations of the current state of C++ support: > > > > 1. When I use a user-defined class in my Bison parser, I *must* define a > > default constructor. Is this an inherent requirement/limitation of Bison? > > Well, it's a limitation inherent to the Yacc model I guess. > > The way Yacc works is by letting the user write actions as code, > involving the "input" ($1, $2, etc.), to compute and store the output > in $$. > > exp > : exp "+" exp { $$ = $1 + $3; } > | exp "*" exp { $$ = $1 * $3; } > | "number" { $$ = $1; } > ; > > So $$ must be constructed before we hand it over to the user action. > > In some other world, it would have been possible to require that > the user action is not a statement, but an expression, something > like > > exp > : exp "+" exp ($1 + $3) > | exp "*" exp ($1 * $3) > | "number" ($1) > ; > > in which case I guess it would have been possible to build $$ instead > of assigning to it. > > But anyway C, C++ and Java (the languages currently supported by Bison) > offering a really poor support for rich expressions, I very much doubt > there would be enough interest to justify this new model of actions. > > > While it is always possible to define a ‘dummy’ default constructor in > > combination with using pointers for all member values, this sometimes makes > > the code less logical/pretty. Specifically, when I use a user-defined > > class `A' with no default constructor the compiler emits the following > > errors: > > I'll see if I can get a better error message in modern C++. > > > 2. When I use a user-defined sub-class (`B') of a virtual class (`A'), I > > get the following errors during compilation. Could it be that Bison does > > not (yet) support sub-classes / virtual classes? > > I don't really see in what way Bison is concerned by the inheritance. > Note that you have to use the super classes in your %type. Don't do > this (provide Sum derived from Exp): > > %type <Exp*> exp > %type <Sum*> sum > sum: exp "+" exp { $$ = new Sum{$1, $3}; } > exp: sum > > do this: > > %type <Exp*> exp sum > sum: exp "+" exp { $$ = new Sum{$1, $3}; } > exp: sum > > This is ok too: > > %type <Exp*> exp > %type <Sum*> sum > sum: exp "+" exp { $$ = new Sum{$1, $3}; } > exp: sum { $$ = $1; } > > but your problem seems to be elsewhere. > > > Or is this something one > > can work around in some way? I have an actual use case for this: I would > > like to define a pure virtual `Term' with sub-classes `BlankNode', `Iri', > > and `Literal'. > > > > In file included from > > /usr/include/c++/8/x86_64-redhat-linux/bits/c++allocator.h:33, > > from /usr/include/c++/8/bits/allocator.h:46, > > from /usr/include/c++/8/string:41, > > from /usr/include/c++/8/bits/locale_classes.h:40, > > from /usr/include/c++/8/bits/ios_base.h:41, > > from /usr/include/c++/8/ios:42, > > from /usr/include/c++/8/ostream:38, > > from /usr/include/c++/8/iostream:39, > > from parser.yy:14, > > from parser.cpp:40: > > Guessing your grammar file from the compiler errors is too hard for me > to be able to help you. > > Of course, if Exp is an abstract class (A in your case) you cannot > do this: > > %type <Exp> exp > > you must go through a pointer (raw or not). > > > > 3. I regularly run into compilation issues due to the definition of the > > driver's methods `scan_begin()' and `scan_end()' in the parser source file > > `scanner.ll'. Is it possible to make these methods part of `driver.cpp'? > > It would make sense, sure, but these functions often need to call > functions of the scanner that are not exposed in a header file. > If it works for you to put them in the driver's implementation, that's > fine by me. > > > > The way in which the code is currently spread over files seems a bit > > unorganized. > > > > PS: I have published the accompanying code over at > > https://github.com/wouterbeek/bison-cpp > > Doh. I should have started there... > > Well, I believe the problem is here: > > > class driver { > > public: > > int parse(std::string& file_name); > > std::string file_name; > > yy::location location; > > bool trace_parser {false}; > > bool trace_scanner {false}; > > std::vector<A> values; <============= > > void scan_begin(); > > void scan_end(); > > }; > > Don't try to make vectors of abstract classes. You need a pointer > or some indirection. _______________________________________________ help-bison@gnu.org https://lists.gnu.org/mailman/listinfo/help-bison