|
Boost : |
From: Vladimir Prus (ghost_at_[hidden])
Date: 2002-10-18 10:08:30
Joel,
>>3. I have problems with parsing streams. As I understand, Spirit
>>requires forward iterators, and therefore can't work with
>>istream_iterator or istreambuf_iterator directly. It means that if I
>>need to parse *part* of stream, I'm in trouble. Consider these rules:
>>
>> rule<> element = ch_p('(') >> ( int_p % ch_p(',') ) >> ch_p(')');
>> rule<> r = ch_p('[') >> (element % ch_p(',')) >> ch_p(']');
>>
>>To parse 'r' with Spirit, I'd have to extract part of input
>>corresponding to 'r' and then call 'parse' rule. In this particular
>>case, this might be not very hard, but it's bad in general. Probably, a
>>wrapper around istream may be written, which will provide forward
>>iterators, getting additional symbols from istream as required. Hmm..
>>not sure what happens if you read more characters that belong to 'r'.
>
>
> You might want to check out multi_pass under Iterators section.
Oh, I see now. Several comments on docs
"will cause data to be buffered"
is probably not as scary as it should. I guess the real meaning is
"failed alternative might extract from stream that data that does not
belong to the parsed entity, thereby destroying data after the parsed
thing". I suggest that something like that is streesed.
"The input iterator moves on and is never stuck at the beginning"
I don't understand what "stuck" is.
"Be mindful if you use the free parse functions. All of these make
a copy of the iterator passed to them."
The problems are unclear, at least to me at 18:12 local time :-)
I have yet another question. Suppose, I *already* have operator>> for
something. Can I reuse that in Spirit? Something like:
'{' >> * ( int_p >> extractor_parser(My_type) >> ';' ) >> '}'
where 'extractor_parser' just tries to get My_type from stream. Well...
from what?! We've got iterators only... Despite this technical
difference, I think something like that is needed.
>>5. Say I'm parsing a list of pairs, something like:
>>
>> ch_p('[') >>
>>(
>> ( ch_p('(') >> int_p[??] >> ch_p(',')
>> >> int_p[??] >> ch_p(')') )
>> %
>> ch_p(',')
>> )
>> >> ch_p(']')
>>
>> How do I store those pairs, for example, in map? Does semantic action
>>for the first int should store the date in some variable, and semantic
>>action for the second it should read it? IOW, can semantic action for
>>the second int directly access part of string that corresponds to the
>>first int?
>
>
> There are many ways to do what you want. I'll present an
> implementation that uses boost::bind (see attachment for the complete
> runnable program). The core parser is:
Ok, I understand you now. More questions. As I realize, rules by
themself are not very usefull, because they are tied to particular
scanner. Ok, I have class I, and defined Spririt grammar for it,
I_grammar. Later on, I devised class O, and want to define grammar for
it, which must reference instances of "I", for example:
'{' >> *( int_p >> ":" >> I_parser ) >> '}'
If I have I_grammar already, how to implement I_parser?
And one question more.... if I assign a closure type to start rule for
I, how can I access it from semantic actions? The docs say that semantic
action take only a pair of iterators.
- Volodya
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk