Re: Small grammar, long compilation time

Søren Enevoldsen <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
On 2017-10-27 15:35, Larry Evans wrote:
> On 10/27/2017 08:24 AM, Søren Enevoldsen wrote:
>> On 2017-10-27 14:41, Larry Evans wrote:
>>> On 10/26/2017 04:33 PM, Larry Evans wrote:
>>>> On 10/26/2017 09:03 AM, Søren Enevoldsen wrote:
>>>>> The following program takes about 10s to compile. However, the 
>>>>> rule currently used in parenProcess, 'nullProcess' should actually 
>>>>> be 'process'. However, when I make the change, compilation does 
>>>>> not finish. Instead CPU keeps spinning hot, and memory usage 
>>>>> gradually increases. Since it is a rather small grammar, I am 
>>>>> guessing I am doing something wrong. How do I make the grammar 
>>>>> work then I correct it by changing parenProcess to '(' > process > 
>>>>> ')' ? (Note I cannot reduce the number of rules between process 
>>>>> and parenProcess for a smaller example, since then the compile 
>>>>> time immediately decreases).
>>>>>
>>>>> - Søren
>>>>>
>>>>> ====================================================================
>>>>>
>>>>> #include <boost/config/warning_disable.hpp>
>>>>> #include <boost/spirit/home/x3.hpp>
>>>>> #include <boost/spirit/home/x3/support/ast/variant.hpp>
>>>>> #include <boost/spirit/include/qi_char_class.hpp>
>>>>> #include <boost/fusion/include/adapt_struct.hpp>
>>>> [snip]
>>>>> x3::rule<struct processRule, AstAnyProcess> process{"process"};
>>>>>
>>>>> ///  Here be compile time dragons.
>>>>> auto const parenProcess = '(' > nullProcess > ')';
>>>>>
>>>>> auto const primitive = rule<AstAnyProcess>("primitive")
>>>>>      = parenProcess
>>>>>      | nullProcess
>>>>>      | constant;
>>>> [snip]
>>>> With this "convenience" change:
>>>>
>>>> #define USE_PROCESS_IN_PAREN
>>>> auto const parenProcess
>>>>    = '('
>>>> #ifdef USE_PROCESS_IN_PAREN
>>>>    ///  Here be compile time dragons.
>>>>    > process
>>>> #else
>>>>    > nullProcess
>>>> #endif
>>>>    > ')'
>>>>    ;
>>>>
>>>> and when compiled, it did take more than 10s (way more)
>>>> and I did see my memory use go up and 100% of some of
>>>> my cpu's.  However, when the get_rhs branch of a spirit
>>>> fork here:
>>>>
>>>> https://github.com/cppljevans/spirit/tree/get_rhs
>>>>
>>>> was -I included in front of the standard boost,
>>>> it compiled in a flash.
>>>>
>>>> This problem has been reported before; however, I've
>>>> been advised that it needs more documentation before
>>>> submitting it as a pull request.  I'm working slowly
>>>> on that.
>>>>
>>>> HTH.
>>>>
>>>> -regards,
>>>> Larry
>>>
>>> If you limit the instantiation depth to 200, you can
>>> get some idea of why it fails as shown in the attached.
>>> In brief, the context is being repeatedly augmented
>>> by the make_unique_context leading to the excessive
>>> instantiations.  The get_rhs branch avoids that
>>> repeated call to make_unique_context.
>>>
>>> -regards,
>>> Larry
>>>
>>>
>>> ------------------------------------------------------------------------------ 
>>>
>>> Check out the vibrant tech community on one of the world's most
>>> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>>>
>>>
>>> _______________________________________________
>>> Spirit-general mailing list
>>> [email protected]
>>> https://lists.sourceforge.net/lists/listinfo/spirit-general
>>
>> Thanks for the explanation and pointers Larry. But I am not sure what 
>> is happening for me.
>>
>> I am using GCC 7.2.0 and compile using:
>> g++ wccs_parser.cpp -Wall -pedantic -O2 -march=x86-64 -std=c++17 -m64 
>> -I. -flto=4 -static-libgcc -static-libstdc++ -ljemalloc -o wccs_parser
>>
>> A. Compiling without the equivalent of "USE_PROCESS_IN_PAREN" takes 
>> ~14s and ~930MB (maximum resident).
>>
>> 1. I clone your repo into ~/spirit
>> 2. I add ~/spirit to very front of my CPLUS_INCLUDE_PATH . The full 
>> boost package (1.65.1) is very last. In fact these are the only two 
>> paths there.
>> 3. I compile again and it takes ~15s and ~925MB.
>>
>> I am quite sure it now uses your ~/spirit because now I get a pragma 
>> warning from the original boost (which I did not get before):
>>
>> /home/soren/spirit/include/boost/spirit/home/x3/nonterminal/rule.hpp:23:19: 
>> note: #pragma message: not(BOOST_SPIRIT_ATTR_XFORM_IN_RULE)
>>     #pragma message "not(BOOST_SPIRIT_ATTR_XFORM_IN_RULE)"
>>                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> /home/soren/spirit/include/boost/spirit/home/x3/nonterminal/rule.hpp:28:19: 
>> note: #pragma message: not(BOOST_SPIRIT_GET_RHS_CRTP)
>>     #pragma message "not(BOOST_SPIRIT_GET_RHS_CRTP)"
>
> Ah!  I forgot to add that you need to #define those 2 macros to
> avoid the long compile times.  Otherwise, the branch behaves
> just like the existing spirit.
>
>>
>> And I can still not compile with "USE_PROCESS_IN_PAREN".
>>
>> - Søren
>>
>>
>>
>>
>>
>> ------------------------------------------------------------------------------ 
>>
>> Check out the vibrant tech community on one of the world's most
>> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>>
>>
>>
>> _______________________________________________
>> Spirit-general mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/spirit-general
>>
>
>
>
> ------------------------------------------------------------------------------ 
>
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> Spirit-general mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/spirit-general

That certainly sped things up. But now it fails with template static 
assertion. This is the very end, but it occurs at least thrice in the 
output.

wccs_parser.cpp:226:59:   required from here
/home/soren/spirit/include/boost/spirit/home/x3/operator/detail/sequence.hpp:143:9: 
error: static assertion failed: Attribute does not have the expected size.

Line 226:59 is essentially root, in the parse call (last line in below):

         wccs_parser::AstAnyProcess root;
         auto iter = str.begin();
         auto end = str.end();
         bool r = parse(iter, end, wccs_parser::entry, root);

This also occurs a bit up:

.....

..... , boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >&)’
              rat_v.post(ok_parse,attr,attr_);



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.