Hans Åberg wrote: > >> 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.
I remember it used to do this before every action, even user-supplied actions, which was questionable. But now I see, it doesn't do it at all, even with no user action. This seems to contradict the documentation https://www.gnu.org/software/bison/manual/html_node/Actions.html : If you don't specify an action for a rule, Bison supplies a : default: $$ = $1 Is this intentional? If so, I'd have to add this action to some of my rules (in some cases with std::move). Good to know this now. But anyway, the issues with unique_ptr and other move-only types are not mainly in the actions, but more in the generated code, starting with the make_FOO functions. Again, I don't see that the default versions in 3.0.4 support moving. Do you use another version? > > 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. I don't think deque makes it any clearer; the code should be the same, provided stack_symbol_type has proper move semantics, which it needs anyway. (In fact, after my patches, I could remove the assignment operator from lalr1.cc. It was specially provided for vector::push_back, but is no more needed then.) > >> 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. That may be so, but both my implementation language (C++) and my target language are strongly typed, and so are all terminals and nonterminals in my grammar. But again, what/where is this "untyped grammar C++ parser" you mentioned? I might try it, but I don't see it anywhere. And when you say "the typed does not work properly", are you referring to lalr1.cc? What doesn't work? With the calc++ example I saw no problems, but it's just a toy, of course. So if there are serious problems, I'd like to know about them before I try to port my parser. > > 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; I don't think they're very tricky. shared_ptr does everything behind the scenes, except in special cases such as circular references. But of course, unique_ptr is always preferable when it does the job. > 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. I think we agree here. If I'd always use shared_ptr, I wouldn't have any problems since it's copyable. But as I said, I want to use unique_ptr (or other move-only types) in most cases, that's why I need move semantics. Regards, Frank
