> On 4 Mar 2018, at 16:58, Frank Heckenbach <[email protected]> wrote: > > Hans Åberg wrote: > >>> On 3 Mar 2018, at 22:36, Frank Heckenbach <[email protected]> wrote: >>> >>> So far my C++ parsers use the C template (which works, but with >>> obvious restrictions). >> >> Not recommended, as the compile C as C++ proved too difficult to maintain, >> and thus is not supported. > > That's why I'm looking for a better alternative. :) > >>> One of the main advantages I hope to achieve is to use proper C++ >>> classes for semantic values (where so far I've had to use manually >>> managed plain pointers). However, the generated parser requires >>> copyable types, just moveable isn't enough (even if I use std::move >>> in all user-defined actions). >> >> Actually not, as the default stack used std:deque, which does not invoke the >> copy constructor when reallocating. >> >>> ... What do other >>> C++11 users do in such cases? >> >> Later Bison versions work with unique_ptr; add %require to the >> grammar to make sure one does not compile with older versions. > > Which version? I tried 3.0.4 (the latest I could find;
That version is OK. In the past, there was a C hack where the default rule action was implemented by always doing $$ = $1, which does not work with unique_ptr. > seems to be > the same in git) which still seems to use vector: > > data/stack.hh: [[ template <class T, class S = std::vector<T> > > data/lalr1.cc: typedef stack<stack_symbol_type> stack_type; Indeed, I thought Akim set it to deque, which by the way is the default for std::stack. > I'm not really convinced deque is the way to go. It adds some > runtime overhead, maybe small, for what is really a single-ended > queue, i.e. stack. So if copying can be avoided, as my patches seem > to indicate, vector seems preferable. Most time is typically spent in the lexer and the actions, so the parser is usually not much to worry about: just write so it is clear and easy to maintain. >> For the untyped grammar C++ parser (the typed does not work >> properly), > > What is this? I'm still starting with C++ bison. I've been using the > calc example which uses %skeleton "lalr1.cc", and that seems to be > the only C++ skeleton I see, except for glr.cc (I don't need GLR > yet). There is a C++ equivalent of %union that allows for attaching types to the grammar rules, but there seems to be an issue with its variants (might be fixed using C++17 std::variant though). I found a typed grammar of not much use in a highly dynamic language. >> I found it best to use the Boehm GC together with a reference >> type. This is better than shared_ptr, which is a primitive form of >> reference counting. > > As I said, in most cases, I want to use unique_ptr or plain objects > without pointers (if they're small). > > For those (few) other cases, I don't really want to introduce GC; > I strongly prefer RAII. And that's especially true in those projects > I use bison: the parser deals only with a small fraction of all the > objects at runtime; most objects are used by other parts of the > program, yet GC would impose itself on them globally. RAII > (shared_ptr) deletes objects when necessary without going through > the millions of other live objects, and lets me do proper cleanup > via destructors. Reference counts are tricky to use and get right, so avoid them in general if you can; if the use is limited to keeping track of the references in the grammar, shared_ptr might be OK. A fellow on the Bison Help list decided to go for unique_ptr.
