Re: Small grammar, long compilation time

Larry Evans <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
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
wccs_parser.compilation (text/plain, 13.2 KB)
  Shows 'template instantiation exceeded maximum depth'
  error msg when not using get_rhs branch of fork:
  
https://github.com/cppljevans/spirit/tree/get_rhs  
  
--{--cut here--
-*- mode: compilation; default-directory: "~/prog_dev/boost/releases/ro/boost_1_65_1/sandbox/pull_requests/context_debug_fix.fork/spirit/workbench/x3/rec_ex_orig/" -*-
Compilation started at Fri Oct 27 07:09:07

make compile
time timeout 10.0s /home/evansl/dwnlds/llvm/5.0/prebuilt/clang+llvm-5.0.0-linux-x86_64-ubuntu16.04/bin/clang++ -c -std=c++14 -fdiagnostics-show-template-tree -ftemplate-depth=200 -ftemplate-backtrace-limit=0  -I/home/evansl/prog_dev/boost/releases/ro/boost_1_65_1 -I/home/evansl/prog_dev/boost/sandbox/lje/non_variadic_templates -DBOOST_SPIRIT_X3_EXPERIMENTAL_GET_RHS_NS=1 -DBOOST_SPIRIT_X3_EXPERIMENTAL_GET_RHS_CRTP=0 -DBOOST_SPIRIT_X3_EXPERIMENTAL_ATTR_XFORM_IN_RULE=0  wccs_parser.cpp
In file included from wccs_parser.cpp:19:
In file included from /home/evansl/prog_dev/boost/releases/ro/boost_1_65_1/boost/spirit/home/x3.hpp:14:
In file included from /home/evansl/prog_dev/boost/releases/ro/boost_1_65_1/boost/spirit/home/x3/auxiliary.hpp:11:
In file included from /home/evansl/prog_dev/boost/releases/ro/boost_1_65_1/boost/spirit/home/x3/auxiliary/any_parser.hpp:11:
In file included from /home/evansl/prog_dev/boost/releases/ro/boost_1_65_1/boost/spirit/home/x3/core/parser.hpp:18:
/home/evansl/prog_dev/boost/releases/ro/boost_1_65_1/boost/spirit/home/x3/support/context.hpp:99:59: fatal error: recursive
      template instantiation exceeded maximum depth of 200
        return detail::make_unique_context<ID>(val, next, x3::get<ID>(next));
                                                          ^
/home/evansl/prog_dev/boost/releases/ro/boost_1_65_1/boost/spirit/home/x3/support/context.hpp:99:16: note: while substituting
      deduced template arguments into function template 'make_unique_context' [with ID = _, T = const
      boost::spirit::x3::alternative<boost::spirit::x3::sequence<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::not_predicate<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type> > >, boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::list<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >,
      wccs_parser::AstCompositionProcess, false> >, Next = boost::spirit::x3::context<_, const
      boost::spirit::x3::list<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >,
      boost::spirit::x3::context<_, const boost::spirit::x3::sequence<boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type>, boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::sequence<boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::lexeme_directive<boost::spirit::x3::sequence<boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii,
      boost::spirit::x3::lower_tag>,
      boost::spirit::x3::kleene<boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii,
      boost::spirit::x3::alnum_tag> > > >, std::__cxx11::basic_string<char>, false>,
      boost::spirit::x3::matches_directive<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type> > >, wccs_parser::AstChannel, false> >,
      boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >,
      boost::spirit::x3::uint_parser<unsigned long, 10, 1, -1> >,
      boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >,
      wccs_parser::AstAction, false>,
      boost::spirit::x3::expect_directive<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type>,
      boost::spirit::x3::expect_directive<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false> > > > >, boost::spirit::x3::context<_, const
      boost::spirit::x3::alternative<boost::spirit::x3::sequence<boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::alternative<boost::spirit::x3::sequence<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::not_predicate<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type> > >, boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::list<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >,
      wccs_parser::AstCompositionProcess, false> >,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::not_predicate<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type> > >, boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::list<boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::alternative<boost::spirit::x3::sequence<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::not_predicate<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type> > >, boost::spirit::x3::rule_definition<_,
      boost::spirit::x3::list<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >,
      wccs_parser::AstCompositionProcess, false> >,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >,
      wccs_parser::AstChoiceProcess, false> >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const
      boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag>,
      boost::spirit::x3::unused_type> > > >]
        return detail::make_unique_context<ID>(val, next, x3::get<ID>(next));
               ^
.
.
.               
/home/evansl/prog_dev/boost/releases/ro/boost_1_65_1/boost/spirit/home/x3/nonterminal/detail/rule.hpp:281:20: note: in
      instantiation of function template specialization
      'boost::spirit::x3::detail::rule_parser<boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >,
      _>::parse_rhs_main<boost::spirit::x3::alternative<boost::spirit::x3::sequence<boost::spirit::x3::rule<wccs_parser::actionPrefixingRule,
      boost::spirit::x3::variant<boost::spirit::x3::forward_ast<wccs_parser::AstNullProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstActionPrefixProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstChoiceProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstCompositionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRestrictionProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstRenamingProcess>,
      boost::spirit::x3::forward_ast<wccs_parser::AstConstantProcess> >, false>,
      boost::spirit::x3::not_predicate<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard,
      boost::spirit::x3::unused_type> >
real	0m10.002s
user	0m0.004s
sys	0m0.000s
Makefile:32: recipe for target 'compile' failed
make: *** [compile] Error 124

Compilation exited abnormally with code 2 at Fri Oct 27 07:09:17

--}--cut here--
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.