> On 9 Mar 2018, at 22:59, Frank Heckenbach <f.heckenb...@fh-soft.de> wrote: > > Hans Åberg wrote: > >>>> We are speaking about different things here: In Yacc grammar one [can't] >>>> drop the ";". >>> >>> OK, but how is this relevant here? >> >> An example of Bison not being Yacc. > > Obviously. As I said, nothing about the C++ mode is required for > Yacc compatibility. It just seems gratuitous to me to drop the > default action when it's so easy to implement. -- Actually, even > easier now that I use std::variant; I was able to unify this code > with the non-variant version to always do the default action when no > user action is given, and always default-initialize $$ when there is > one, in order to avoid any illusion that there is a pre-action, and > the relavant code is now shorter than before.
Akim Demaille wrote the C++ parser, and he is not active now. I thought the default should have been there, and it is unclear to me why it isn't. Maybe there should be an option for the choice. >>>>> so expensive. Also bison by default reserve()s 200 entries, and I >> >> It might be remnant from the C parser. > > Even if so, it's still a good idea to keep it, so vector basically > never actually needs to reallocate. It depends on the grammar. >>> I looked into the code. Just adding std::move seems rather easy, but >>> finding out if a $n is mentioned several times might be tricky on >>> the m4 level, might require changes to Bison itself. >>> >>> And the question remains what to do then. One possibility would be >>> an option auto-move or such. If not set, std::move is not inserted; >>> if set it's always inserted, but Bison warns if $n is mentioned >>> several times. >>> >>> Then there might need to be a way to suppress this warning for >>> individual cases which gets complicated again. Or there is no such >>> way, and if needed, one has to work around it. That would work fine >>> with my grammar -- for the few such rules as mentioned above I could >>> just move $n to temporaries. But for grammars that have this more >>> often, this might get cumbersome, so I'm not sure how useful such an >>> option would be to others. >>> >>> Any ideas? >> >> No ideas. I suspect moves are from the point of view just an >> optimization, lacking features for application like this. > > Well, std::move works alright. The only rule to remember (which is > obvious when you consider what moving means) is that you cannot move > from the same thing twice. To a C++11 programmer, that's natural. > The question is just if we can make Bison do that automatically, at > least in most cases. It is interesting to think about: the lifetime objects are known, but not regulated by the stack. >>>>> I did so at first, but then I realized that Bison would have to >>>>> replace "$$ =" with "return" which is dangerous as I said. So it >>>>> would probably be easier in the long run to leave this to the >>>>> programmer. (But again, I doubt this will be implemented.) >>>> >>>> And maybe the C++ standard does not admit one relying on it. >>> >>> I think move on return (when the target is a local variable or >>> parameter) is guaranteed in recent standards (C++14 or so). >> >> Then it might be possible. > > Only for "$$ =" in the best case. IMHO it's only a few rules (such > as "'(' expr ')'") that would really profit from this (apart from > the default action which I've already covered), so I don't think > that's worth the effort. It might be too special to worry about, given the required effort. >> It would be enough for just keeping track of the semantic value in >> the parser. It is more optimal to do the deallocations by hand as >> in the C parser if one wants to optimize. > > Well, that's what I've been doing so far, hope to change it. As I > said, my parser can suffer a little inefficiency (though with move > semantics, it won't even have to), but the rest of my program must > not. Then some reference count might suffice. >>>> I am not sure why you need it in the parser. Just put the object >>>> on the heap and use shared_ptr in the semantic value, but nowhere >>>> else. >>> >>> That's exactly what I'd need a release method for when transferring >>> objects from the parsed structures to the rest of the program. >> >> Can't you use the shared_ptr::reset function? > > Nope, reset destroys the object. See the stackoverflow page I linked > in my first mail for a discussion. There doesn't seem to be a "nice" > way, and that seems to be intentional. It seems shared_ptr [1] can use a deleter object, which might then be set to do nothing. Cf. function 3 in [2] and constructor 5 in [3]. Otherwise, I wrote a ref count class with a detach function. I have class functions that may return a reference to *this or make a new allocation, so the count had to be put in the class object and not the reference object. This is why shared_ptr wouldn't work, as it holds the count. 1. http://en.cppreference.com/w/cpp/memory/shared_ptr 2. http://en.cppreference.com/w/cpp/memory/shared_ptr/reset 3. http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr