Re: Design/structure X3 parser more like Qi parser
Larry Evans <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
On 12/20/2016 05:11 PM, Seth wrote:
> On 19-12-16 12:25, Larry Evans wrote:
>> This use of BOOST_SPIRIT_DEFINE avoids the extra compile time
>> needed by make_csv_parser method above;
> I don't know how you established that there is such a
> compile time penalty
Sorry for not listing my reasons. They are listed in my
other post:
https://sourceforge.net/p/spirit/mailman/message/35561750/
starting with the line:
I assume it would take more time because of the template
metaprogramming required at these places:
>> hence, Seth, I'm wondering what the advantage of *not*
>> using the BOOST_SPIRIT_DEFINE method for associating a
>> rule with it's rule_definition?
> That's not what the code does at all. It just creates a
> parser.
Sure, but that parser, the parse_rule parser, produced by
BOOST_SPIRIT_DEFINE, is only used in the
rule<ID,ATTR>::parse function:
https://github.com/boostorg/spirit/blob/master/include/boost/spirit/home/x3/nonterminal/rule.hpp#L116
Hence, it's only use is to allow the rule::parser to parse
it's right-hand-side (RHS).
Maybe I should have said:
A BOOST_SPIRIT_DEFINE call in *combination* with the
rule::parse call to parse_rule "associates a rule with
it's RHS.".
Is that a fair description?
> You can store it in an auto variable just like any other
> rule and use it. I have little to no reason to believe the
> performance of the code or compilation time would differ a
> lot from the equivalent using BOOST_SPIRIT_DEFINE, but I
> welcome the effort to produce more comparative benchmarks.
OK. Working on it. I'll post a followup when I've got some
sort of benchmark.
[snip]
>
> TBH I think the performance bug is the only real issue here.
>
I assume you meant the runtime performance bug you first and
then Sandro confirmed, and was probably, according to your
profile runs, somewhere in the `parse_into_container` code.
I agree that this is the most important and most immediate
problem; however, having 2 methods to associate the rule
with it's RHS results in more complicated metaprogramming
and harder to understand code. It took me a long while to
undersand how the parse_rule actually associated the rule
with it's RHS, and even after I thought I understood it, I
still made a mistake as shown by my post to spirit.devel:
http://boost.2283326.n4.nabble.com/x3-devel-design-add-is-default-parse-rule-true-flag-to-rule-definition-parse-tt4690489.html#none
If this added complexity doesn't buy you anything, then it
should be removed. As mentioned earlier, I'm working on a
benchmark to see if using 2 methods (Let's label them as the
in-context and BOOST_SPIRIT_DEFINE methods) instead of just
the BOOST_SPIRIT_DEFINE buys anything.
As a benchmark test case, I was thinking of this grammar:
rul<0> = char_('a');
rul<1> = char_('1') >> rul<0>;
rul<2> = char_('2') >> rul<1>;
rul<3> = char_('3') >> rul<2>;
.
.
.
rul<N> = char_('N') >> rul<N-1>;
Of course, by <I> I mean something like id<I> where id is:
template<unsigned I>struct id{};
Since the grammar is non-recursive, the in-context method
could handle it.
Of course, in the case of the in-context method, this would
be:
def<I> = rul<I> = char_('I') >> def<I-1>;
and, in the case of the BOOST_SPIRIT_DEFINE method, this
would be:
BOOST_SPIRIT_DEFINE
( (rul<0> = char_('a') )
, (rul<1> = char_('1') >> rul<0> )
, (rul<2> = char_('2') >> rul<1> )
, (rul<3> = char_('3') >> rul<2> )
.
.
.
, (rul<N> = char_('N') >> rul<N-1> )
)
where BOOST_SPIRIT_DEFINE is the one defined here:
https://github.com/cppljevans/spirit/blob/ExagonLinkingError/workbench/x3/rule_defns/parse_rule_crtp.cpp#L41
Since that code does no attribute processing, to be fair to
the in-context method, the code here:
https://github.com/cppljevans/spirit/blob/ExagonLinkingError/workbench/x3/rule_defns/rule_defns.cpp#L247
which also does no attribute processing, will be used, with
any modifications needed to accommodate the benchmark.
AFAICT, that code does the same template metaprogramming
that real spirit does to allow the rule::parse to call the
parser for it's RHS. (NOTE, if you run the code, you'll see
that the calc_gram_tree test calls parse_rhs_main; whereas
the calc_gram_recur test does not. That's because the
[rule]_def's in calc_gram_recur are not rule_definition's;
whereas, in calc_gram_tree, the [rule]_def's are
rule_definitions.).
Varying the size of the grammar (by varying N), should
highlight any affect that has on the meta-programming cost.
Does such a benchmark test seem fair to you?
-regards,
Larry
------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today.http://sdm.link/intel