> On 4 Mar 2018, at 22:19, Frank Heckenbach <[email protected]> wrote: > >>>> 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. >> >> OK in C, as it just copied the chunk. > > It would work in C, but users were advised not to rely on it.
No problem in C, as there are no copy constructors, just an overhead. >>> 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. >> >> The way it should work now is providing if no explicit action is >> given, otherwise not. Before, one always got it first, before the >> eventual explicit action. > > That's what I thought too, but it doesn't seem to (and it wouldn't > work with move-only types without std::move). It just seems to leave > $$ unset (i.e. default-constructed) without an explicit action. If you don't have an {...}, one should get $$ = $1. Personally, I don't rely on it, one reason is that I have more that one field in the semantic value. So a rule may look like: identifier: "name"[x] { $$ = ... $x.name ...; } | ... ; Such variable naming is useful, avoiding having to keep track of the numbering. >>> 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? >> >> No versions support moving, and 3.0.4 may be the latest. The >> objects must be locations where it is expires, and that may not >> work well with the Bison parser. > > Sorry, I don't quite understand your last sentence. Even with a type support move constructors, the $$ and $k are not in positions where they will be invoked. >>> (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.) >> >> The Bison distributed skeleton file might change, and then yours become does >> not benefit from that. > > That's the problem: If Bison isn't developed, the skeleton file > won't change, so I could (and would have to) keep my changes > locally. But if it's developed and the skeleton file changes, I'd > like my version to benefit, so I'd like to get it integrated. If > Bison doesn't want to require C++11, my changes could be made > conditional, either with #ifdef or with m4 macros. I'd be willing to > work on that, but only if there's a point to it, i.e. if Bison is > still maintained. That is complicated. I jave tried it, so I decided to not do it. >>> But again, what/where is this "untyped grammar C++ parser" you >>> mentioned? I might try it, but I don't see it anywhere. >> >> Just don't use %union. > > Actually, I'm not using %union, but "%define api.value.type variant" > just like in the calc++ example. There was a report on som issue with that. So it would be better no using it now. > Do you mean using an "untyped" > semantic type, i.e. a kind of variant manually? But it would still > need to be copyable, or does moveable suffice then? The types one writes in the grammar selects fields in the %union or variants. For C++ it seems safest to not use the variants it has in view of that issue. >>> 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. >> >> It was an issue with the variants. > > Well, I read variant.hh, and I did't spot any serious problems. > Whatever the issue was, maybe it's fixed now. I don't think so, in view of that the C++ parser isn't developed. You might try searching the archives. > A questionable decision is that it doesn't keep track of the active > variant (the typeid is stored just for debugging) and relies on > external knowledge. It works, but makes other code more complicated, > e.g. implementing move constructor/assignment for basic_symbol. If > the variant itself had a move (and optionally, copy) > constructor/assignment, this would be more straightforward. > > In the long run, it might be preferable to switch to C++17 variants, > but ATM I don't actually use C++17 yet (maybe next year). GCC7 supports C++17, but as the Bison C++ parser isn't developed, that does not help. >>> 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. >> >> You might start with unique_ptr to see if it suffices. There is no >> Bison support for move semantics to be expected any time soon. > > I do want to start with unique_ptr, but unique_ptr requires move > semantics, that's just the point. I though the copy constructor moves the pointer just as well. But try shared_ptr then, the difference is just some overhead.
