Boost logo

Boost :

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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk