1

GCC3.4.6とBoost1.43を使用して、次の一見単純なコードをコンパイルしようとしていますが、内部コンパイラエラーが発生しています。

#include <string>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>

namespace lex    = boost::spirit::lex;
namespace qi     = boost::spirit::qi;

typedef lex::lexertl::token<std::string::iterator> TokenT;
typedef lex::lexertl::actor_lexer<TokenT> LexerT;

template <typename LexerT>
struct Tokens: public lex::lexer<LexerT>
{};

int main()
{
   typedef Tokens<LexerT>::iterator_type IteratorT;
   qi::rule<IteratorT, int> expression;

   expression = (qi::int_ >> qi::int_) [ qi::_val = qi::_1 ];
}

生成されたエラー:

.../boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:83: internal compiler error: in lookup_member, at cp/search.c:1300

の最後の行は、main()このエラーを生成しています。このエラーは、の代わりにexpressionルールを機能させることで解消されます。std::string::iteratorIteratorT

レクサーを使用しながらエラーを修正するためのヘルプをいただければ幸いです。

ありがとう!

4

1 に答える 1

1

あなたは括弧を逃しました:

qi::rule<IteratorT, int()> expression;

これにより、コンパイル エラーが修正される可能性があります (ただし、gcc、clang、および msvc の両方が問題なくコンパイルしたため、確認することはできません)。


コンパイラのストレスを軽減したい場合があります。

  • 利用可能なRAMを増やす
  • 制限を下げる (下記参照)
  • デバッグ情報を無効にする (-g0)
  • および最適化 (-O0; または、サイズの最適化 -Os)

おそらくその地域ではもっと多いでしょう。

限界

私は簡単なことをしました

grep -EoRh '\<\w+_LIMIT\>' ~/custom/boost_1_50_0/boost/spirit/home/ -h | sort -u

可能な定義のリストを取得し、それに基づいて次の変更を行います。

#ifdef LEAN
#define PHOENIX_ACTOR_LIMIT      3 // boost 1_50 default: 10
#define PHOENIX_ARG_LIMIT        5 // boost 1_50 default: 10
#define PHOENIX_CATCH_LIMIT      1 // boost 1_50 default:  9
#define PHOENIX_COMPOSITE_LIMIT  5 // boost 1_50 default: 10
#define PHOENIX_DYNAMIC_LIMIT    1 // boost 1_50 default: 10
#define PHOENIX_LIMIT            5 // boost 1_50 default: 10
#define PHOENIX_LOCAL_LIMIT      3 // boost 1_50 default: 10
#define PHOENIX_MEMBER_LIMIT     3 // boost 1_50 default:  8
#define SPIRIT_ARGUMENTS_LIMIT   5 // boost 1_50 default: 10
#define SPIRIT_ATTRIBUTES_LIMIT  5 // boost 1_50 default: 10
#endif

#include <string>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace lex    = boost::spirit::lex;
namespace qi     = boost::spirit::qi;
namespace phx    = boost::phoenix;

struct funcImpl
{
   template <typename T>
   struct result { typedef int type; };

   template <typename T>
   int operator()(T& x) const {
      return 0;
   }
};

typedef lex::lexertl::token<std::string::iterator> TokenT;
typedef lex::lexertl::actor_lexer<TokenT> LexerT;

template <typename LexerT>
struct Tokens: public lex::lexer<LexerT>
{};

int main()
{
   //typedef Tokens<LexerT>::iterator_type IteratorT;
   typedef char* IteratorT;
   qi::rule<IteratorT, int()> expression;

   phx::function<funcImpl> func = funcImpl();
   expression = (qi::int_ >> qi::int_) [ qi::_val = func(qi::_1) ];


   std::cout   << "#define PHOENIX_ACTOR_LIMIT "                       << PHOENIX_ACTOR_LIMIT                       << '\n';
   std::cout   << "#define PHOENIX_ARG_LIMIT "                         << PHOENIX_ARG_LIMIT                         << '\n';
   std::cout   << "#define PHOENIX_CATCH_LIMIT "                       << PHOENIX_CATCH_LIMIT                       << '\n';
   std::cout   << "#define PHOENIX_COMPOSITE_LIMIT "                   << PHOENIX_COMPOSITE_LIMIT                   << '\n';
   std::cout   << "#define PHOENIX_DYNAMIC_LIMIT "                     << PHOENIX_DYNAMIC_LIMIT                     << '\n';
   std::cout   << "#define PHOENIX_LIMIT "                             << PHOENIX_LIMIT                             << '\n';
   std::cout   << "#define PHOENIX_LOCAL_LIMIT "                       << PHOENIX_LOCAL_LIMIT                       << '\n';
   std::cout   << "#define PHOENIX_MEMBER_LIMIT "                      << PHOENIX_MEMBER_LIMIT                      << '\n';
   std::cout   << "#define SPIRIT_ARGUMENTS_LIMIT "                    << SPIRIT_ARGUMENTS_LIMIT                    << '\n';
   std::cout   << "#define SPIRIT_ATTRIBUTES_LIMIT "                   << SPIRIT_ATTRIBUTES_LIMIT                   << '\n';
   //std::cout << "#define BOOST_PHOENIX_LIMIT "                       << BOOST_PHOENIX_LIMIT                       << '\n';
   //std::cout << "#define BOOST_SPIRIT_CLOSURE_LIMIT "                << BOOST_SPIRIT_CLOSURE_LIMIT                << '\n';
   //std::cout << "#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT " << BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT << '\n';
   //std::cout << "#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT "       << BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT       << '\n';
   //std::cout << "#define BOOST_SPIRIT_SELECT_LIMIT "                 << BOOST_SPIRIT_SELECT_LIMIT                 << '\n';
   //std::cout << "#define BOOST_SPIRIT_SWITCH_CASE_LIMIT "            << BOOST_SPIRIT_SWITCH_CASE_LIMIT            << '\n';
   //std::cout << "#define PHOENIX_CONSTRUCT_LIMIT "                   << PHOENIX_CONSTRUCT_LIMIT                   << '\n';
   //std::cout << "#define SPIRIT_CLOSURE_LIMIT "                      << SPIRIT_CLOSURE_LIMIT                      << '\n';
}

ここで、次のサイズ変更が発生します (LoC 前処理):

sehe@mint12:/tmp$ g++ -g0 -O0 -I /home/sehe/custom/boost_1_50_0/ test.cpp -E | wc -l
193011
sehe@mint12:/tmp$ g++ -g0 -O0 -I ./boost_1_43_0/ test.cpp -DLEAN -E | wc -l
168862

基本的に、コード行が 10% 以上削減されます。それはちょうど役立つかもしれません。

于 2012-07-17T21:39:10.687 に答える