9 Feb 23:46
Explicit Instantiation support
James H. Hill <hillj <at> cs.iupui.edu>
2010-02-09 22:46:04 GMT
2010-02-09 22:46:04 GMT
Hi, I am trying to compile a really large grammar (~110+ rules and counting). As expected, it takes forever to compile. But what is worse is that Visual Studio runs out of heap space and the compilation does not finish.I am going to take a guess and say there is a memory leak somewhere in their preprocessor (or its not that optimized to handle the cool features of Boost.Spirit 2.0), but that is besides the point. So, I tried breaking the grammar to into many different files and compiling it. Unfortunately, I got the same results as before. I then realized that these are template and no matter how I break up the grammar, I will get the same results!! After scratching my head, I remember *explicit instantiation* and thought that would help me out. The plan was to break up the large grammar into smaller grammars, instantiate the grammars with the desire iterator type, and export it from an shared library. I thought this should work, however, there are compile errors when trying to do explicit instantiation. Below is my simple grammar (thanks to breaking it up, I can now include the example
): -------- namespace qi = ::boost::spirit::qi; namespace ascii = ::boost::spirit::ascii; template <typename IteratorT> class ident : public qi::grammar < IteratorT, std::string (), ascii::space_type > { public: ident (void) : ident::base_type (ident_) { this->ident_ %= qi::lexeme[qi::alpha >> *(qi::alnum | '_')]; } private: qi::rule <IteratorT, std::string (), ascii::space_type> ident_; }; // IDLTEXTEDITOR_CORE_Export is a macro that is either __declspec (dllexport) // or __declspec (dllimport) template class IDLTEXTEDITOR_CORE_Export ident <std::string::iterator>; template class IDLTEXTEDITOR_CORE_Export ident <std::string::const_iterator>; -------- Also, attached is the error output from Visual Studio.
1>------ Build started: Project: IDLTextEditor_Core, Configuration: Debug Win32 ------ 1>Compiling... 1>ident.cpp 1>using native typeof 1>E:\utils\boost\include\boost-1_41\boost/proto/extends.hpp(501) : error C2512: 'boost::proto::exprns_::expr<Tag,Args,Arity>' : no appropriate default constructor available 1> with 1> [ 1> Tag=boost::proto::tag::terminal, 1> Args=boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,std::basic_string<char,std::char_traits<char>,std::allocator<char>> (void),boost::spirit::ascii::space_type,boost::fusion::unused_type>>>, 1> Arity=0 1> ] 1> E:\utils\boost\include\boost-1_41\boost/proto/extends.hpp(499) : while compiling class template member function 'boost::proto::exprns_::extends<Expr,Derived>::extends(void)' 1> with 1> [ 1> Expr=boost::proto::exprns_::expr<boost::proto::tag::terminal,boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,std::basic_string<char,std::char_traits<char>,std::allocator<char>> (void),boost::spirit::ascii::space_type,boost::fusion::unused_type>>>,0>, 1> Derived=boost::spirit::qi::grammar<std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,std::string (void),boost::spirit::ascii::space_type> 1> ] 1> E:\utils\boost\include\boost-1_41\boost/spirit/home/qi/nonterminal/grammar.hpp(38) : see reference to class template instantiation 'boost::proto::exprns_::extends<Expr,Derived>' being compiled 1> with 1> [ 1> Expr=boost::proto::exprns_::expr<boost::proto::tag::terminal,boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,std::basic_string<char,std::char_traits<char>,std::allocator<char>> (void),boost::spirit::ascii::space_type,boost::fusion::unused_type>>>,0>, 1> Derived=boost::spirit::qi::grammar<std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,std::string (void),boost::spirit::ascii::space_type> 1> ] 1> e:\proj\cosmic\pim\picml\interpreters\idltexteditor\rules\ident.hpp(16) : see reference to class template instantiation 'boost::spirit::qi::grammar<Iterator,T1,T2>' being compiled 1> with 1> [ 1> Iterator=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>, 1> T1=std::string (void), 1> T2=boost::spirit::ascii::space_type 1> ] 1> e:\proj\cosmic\pim\picml\interpreters\idltexteditor\rules\ident.hpp(32) : see reference to class template instantiation 'ident<IteratorT>' being compiled 1> with 1> [ 1> IteratorT=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>> 1> ] 1>Build log was saved at "file://e:\proj\CoSMIC\PIM\PICML\interpreters\IDLTextEditor\Debug\IDLTextEditor_Core\I386\BuildLog.htm" 1>IDLTextEditor_Core - 1 error(s), 0 warning(s) ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
As a quick workaround, I am removing the template parameter(s) and defining the grammars using the target iterator type. But, in the long run I would really like to use explicit instantiation and templates to help reduce compile time and improve modularity. So, is it possible to use this technique based on the example I provided above, which is directly from my grammar?? Or, what advice do you have in this situation?? Thanks, James
------------------------------------------------------------------------------ SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev
_______________________________________________ Spirit-general mailing list Spirit-general <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spirit-general
I am going to take a guess and say there is a memory
leak somewhere in their preprocessor (or its not that optimized to
handle the cool features of Boost.Spirit 2.0), but that is besides the
point.
So, I tried breaking the grammar to into many different files and
compiling it. Unfortunately, I got the same results as before. I then
realized that these are template and no matter how I break up the
grammar, I will get the same results!!
After scratching my head, I remember *explicit instantiation* and
thought that would help me out. The plan was to break up the large
grammar into smaller grammars, instantiate the grammars with the
desire iterator type, and export it from an shared library. I thought
this should work, however, there are compile errors when trying to do
explicit instantiation. Below is my simple grammar (thanks to breaking
it up, I can now include the example
):
--------
namespace qi = ::boost::spirit::qi;
namespace ascii = ::boost::spirit::ascii;
template <typename IteratorT>
class ident : public qi::grammar < IteratorT,
std::string (),
ascii::space_type >
{
public:
ident (void)
: ident::base_type (ident_)
{
this->ident_ %=
qi::lexeme[qi::alpha >> *(qi::alnum | '_')];
}
private:
qi::rule <IteratorT,
std::string (),
ascii::space_type>
ident_;
};
// IDLTEXTEDITOR_CORE_Export is a macro that is either __declspec
(dllexport)
// or __declspec (dllimport)
template class IDLTEXTEDITOR_CORE_Export ident <std::string::iterator>;
template class IDLTEXTEDITOR_CORE_Export ident
<std::string::const_iterator>;
--------
Also, attached is the error output from Visual Studio.
RSS Feed