Hans Åberg wrote: > Otherwise, there is no reason for Bison to be Yacc compatible, > except for the special Yacc mode, which Paul Eggert worked on > becoming POSIX compliant. For example, Yacc has optional rule > colons, but that might have been removed in Bison in some modes at > least. And Bison now has grammar variable naming, as I indicated, > which in fact is very convenient.
Sure, it's not required (nothing about the C++ mode is), but it might be convenient for the user as it avoids a trap. I have a number of such rules in my grammars, and if you hadn't mentioned it, I'd have been caught by this, not even at compile-time, but at runtime. (Though such a bug would probably be rather obvious and easy to fix in all places, not the end of the world.) But if fixing the behaviour (especially with std::variant) is not more effort than fixing the documentation (which should be done otherwise), why not fix the behaviour? > C++ std::stack though has std::deque as default. If one wants to > access elements not on top, std::stack does not work, though. Which Bison needs to do, so std::stack is out. But Bison's stack implementation is rather short and unproblematic (and it can also work with std::deque -- I still don't see an advantage of doing so, but if you insist, you could probably add a %define or #define to use it). > > We're talking about user-actions here. To them, $$, $1, etc. do and > > should behave just like varibles. (That $1 is an element of a > > container is irrelevant, and again, there's no difference between > > vector and deque in this regard.) The user action might use them > > twice ("foo ($1); bar ($1);"), so always moving would be wrong. It's > > up to the user to move when wanted. And it's not really a problem -- > > with a move-only type, the compiler will complain when you forget > > it. > > Using inline functions for the actions might do it. The compiler > can then remove the inlines, but the moves should be still applied > correctly. Or maybe not, depending on how the C++ standard is > written. AFAIK, it allows for (and modern compilers do) automatic moving for the return value only. So inline functions would help in cases such as the default action ("$$ = $1", if "$$ =" was replaced by "return" and "$1" was a function parameter), and similar cases such as "$$ = $2" (which typically occurs in rules such as '(' expr ')') where a default action doesn't help. I think it's an interesting idea, also for syntactic reasons: Writing "return" instead of "$$ =" seems more natural (though of course, you have to watch out: "$$ =" can be followed by other statements, "return" cannot, so Bison couldn't simply replace it, but a user can deal with it). Also functions could have named parameters (which you seem to prefer anyway) always instead of "$1" etc. So if I'd design Bison now, that's probably what I'd do. But given things as they are, this might be too big a change, both to implement, and for many users to adopt. So I'm not sure it's worth the effort. But if, say, a lot of users now scream they want this feature, I might actually take a stab trying to implementing it ... :) I wouldn't mind my grammars to look this way. But just to be sure, this still doesn't eliminate the need for manual moves in many cases such as "$$ = myfunc (std::move ($1), std::move ($2))", where myfunc might be a typical builder function that wants to take ownership of its arguments. > >>> GC doesn't call destructors, does it? > >> > >> One can a could of different things with the Boehm GC, register > >> finalizers, and it also a deallocation function. > > > > If you have to register them explictly, all the beauty of RAII is > > lost. > > One can mix both GC and standard stack allocations. Stack allocations are no problem. It's about heap allocations. My programs have very many of them, and most of them outside of the parser. Even if GC can deal with them, it will slow it down, since it has to track all of them for liveness analysis, just to find the few dead ones. Also some of my programs have soft realtime requirements, so I prefer more deterministic behaviour. > Guile uses now the Boehm GC, and I have a similar dynamic > polymorphy. For that I wrote a template reference class. The use > of finalizers did not seem to impose a significant overhead. They > are otherwise only needed so collect non-memory resources, such as > open streams. I destructors for various things, e.g. unregistering objects. I think RAII is a general way for any kind of cleanup; freeing resources is just a special case of it; freeing memory is a special case of the special case (though the most common one). GC set out to solve the special case. Unfortunately, RAII wasn't invented and fully understood until later; otherwise GC might never have seen widespead usage. I agree with most of what's written here: https://minorfs.wordpress.com/2011/04/29/why-garbage-collection-is-anti-productive/ Or as http://viming.de/gc_vs_raii.html put it in the conclusion: RAII has many advantages over GC, while it solves problems that GC is supposed to solve as a "side-effect". > Just to let me follow. You did not explain why you can't allocate > the move-only type on the heap, and keep a pointer. What kind of pointer: 1. Raw pointer (manually managed): That's what I've been doing so far. I don't need the C++ skeleton for this, the C one suffices. 2. unique_ptr: I'd like to, but it's move-only. 3. shared_ptr: Has the performance problems as I described. 4. A manually made shared pointer which a release method. That's possible to implement, and since I don't need all the advanced features of shared_ptr, it would be easier than a full reimplementation of shared_ptr, but still some work. Now, I might do 4. if it was my only choice because 2. didn't work. But so far it looks like 2. does work with relatively small changes to the skeletons, and it's a more general approach, and hopefully more useful to user users (if accepted upstream). > > I didn't remove any CC. You CC'ed one (short) mail to Paul Eggert > > which just said that Akim Demaille has not been active for some time > > now. > > I did not see his reply. Sorry, my "which" (not "who") was referring to your mail, not to Paul Eggert (who hasn't replied so far). I will try to contact him again soon. > > Bison's variant implementation really breaks down here. One could > > work around it with some extra code to keep track of the dynamic > > type of $<...>, but that gets really close to reimplementing > > std::variant, so it seems rather pointless. So std::variant is the > > way to go, at least in the long run. (As I said, I don't use gcc7 > > set, but I don't require $<...>, so for now I'll be fine with > > Bison's variant.) > > Since C++17 now is available and supported by GCC7, std::variant would be > best to use. Agreed. It will require some changes to the code using it, but it will actually make it simpler. Regards, Frank