$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Joel de Guzman (joel_at_[hidden])
Date: 2003-11-05 08:33:33
Brian McNamara <lorgon_at_[hidden]> wrote:
> On Wed, Nov 05, 2003 at 03:38:37PM +0800, Joel de Guzman wrote:
>> I tried to replace this with Brian's code, but the regression tests
>> failed.  Why?  Because [where o is an optional<T> and v is a T ] *o = v
>> only works when o is initialized, while o = v works even if o is
>> uninitialized.  IOTW, I need this to work:
>> 
>>     match<int> m; // unitialized
>>     m.value(3); // initializes m
>> 
>> So, Brian, to answer your question "So does my code above work for
>> you?", well, unfortunately, not.  I am now inclined to believe that,
>> indeed, "If it ain't broke, don't fix it".  However, in this case, "it"
>> means ***the tried and true C++ reference semantics***.
>> 
>> Thoughts?
> 
> I am a little unclear about the semantics of match, so I need to ask
> some more questions to try to understand it.  Your original use case was
> 
>>     match<T> m(i);
>>     m.value(x); // ok, set the attribute to x
>> 
>>     match<T&> m(r);
>>     m.value(x); // NO, please don't reset the reference, that's not
>>                 // what I want! references should only be set
>>                 // *at construction time*. I want the thing referenced
>>                 // by r set to x.
> 
> and so I didn't realize that match could also have a default
> constructor and hence I didn't forsee this problem.
Right. My mistake. I didn't notice too, until I actually ran the
regressions.
> So we need to also add this use case, I guess:
> 
>>     match<int> m; // unitialized
>>     m.value(3); // initializes m
> 
> Is this:
> 
>>     match<int&> m; // unitialized
>>     m.value(3); // initializes m
> 
> also supposed to be legal?  I am guessing no, (for the same reason that
> you can't say "int& x;") but I am not sure.
No, that's not legal.
> Who actually creates match objects?  The parser?  
Yes.
> When is the default
> constructor called?  (Maybe when a parse fails, but we still need to
> return a match object?)  
Yes.
> When is the non-default constructor called?
> (Maybe when the parse succeeds?)
Yes.
> When is the value(x) method called?  (I have no clue here.)  
Parser-decorators, for example, can call that function anytime post-parse.
For instance, closures set the match's value post-parse:
        template <typename ResultT, typename ParserT, typename ScannerT>
        ResultT& post_parse(ResultT& hit, ParserT const&, ScannerT const&)
        { 
            hit.value(frame[phoenix::tuple_index<0>()]); 
            return hit; 
        }
<< 
hit conforms to the match concept. Perhaps that's why you didn't see in 
the code where a concrete match object is instantiated. It is a concept.
>>
It is possible to have a successful match with an empty attribute (value)
where parser composites can fill in the missing blanks. 
> What is
> its semantics supposed to be?  Does it convert an "empty" match into a
> "full" one?  Or does it just change/update the value of a "full"
> match?  Or both?
<<
Actually, even an empty match can have a valid attribute (e.g. epsilon
match) -- I guess you meant "unsuccessful and successful" match?
>>
The important thing to note that the validity of an attribute of a match 
is not at all related to it's "success". While an unsuccessful match definitely
cannot have a valid attribute, a successful match *can* have an invalid
attribute. This flexibility allows composing parsers to set attributes to
an initially invalid match attribute. To clarify a bit more, here are the
constructors of match:
unsuccessful match, invalid attribute:
    match(); 
successful match, invalid attribute:
    explicit  match(std::size_t length);
successful match, valid attribute:
    match(std::size_t length, ctor_param_t val);
-- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net