2012-02-26 21 views
2

boost :: spiritを使用して作成された電卓に奇妙な問題があります。この計算機は、 "a + 4 * 5,77、(b-c)* 4"のようにコンマで区切られた一連の算術式を表す引数として文字列を取ります。また、文字列 "?"この場合は-1を含む配列を返します。計算機はSymTableで初期化されます。これは、変数の値を解決する[string] - > int演算子(例:マップ)を提供するクラスを記述するためのテンプレートクラス引数です。boost :: spiritパーサーでのコンパイルエラー

私のUbuntu 10.4では、gcc 4.6.2とgcc 4.4の両方で以下のコードが動作し、1.47と1.48の両方が向上します。これは過去にgray 4.5.3とboost 1.47のCray Linuxマシンでも働いていました。

#include <boost/bind.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 

namespace sp = boost::spirit; 
namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 

namespace Damaris { 

template <typename Iterator, typename SymTable> 
struct Calc : qi::grammar<Iterator, std::vector<int>(), ascii::space_type> 
{ 
     qi::rule<Iterator, std::vector<int>(), ascii::space_type> start; 
     qi::rule<Iterator, int(), ascii::space_type> expr; 
     qi::rule<Iterator, int(), ascii::space_type> qmark; 
     qi::rule<Iterator, int(), ascii::space_type> factor; 
     qi::rule<Iterator, int(), ascii::space_type> simple; 
     qi::rule<Iterator, std::string(), ascii::space_type> identifier; 
     qi::rule<Iterator, int(SymTable), ascii::space_type> value; 

     /** 
     * \brief Constructor. 
     * \param[in] sym : table of symboles. 
     */ 
     Calc(SymTable &sym) : Calc::base_type(start) 
     { 
       identifier = qi::lexeme[(qi::alpha | '_') >> *(qi::alnum | '_')]; 

       value = identifier[qi::_val = qi::labels::_r1[qi::_1]]; 

       simple = ('(' >> expr >> ')') 
         | qi::int_ 
         | value(boost::phoenix::ref(sym)); 

       factor %= (simple >> '*' >> factor)[qi::_val = qi::_1 * qi::_2] 
         | (simple >> '/' >> factor)[qi::_val = qi::_1/qi::_2] 
         | (simple >> '%' >> factor)[qi::_val = qi::_1 % qi::_2] 
         | simple; 

       expr %= (factor >> '+' >> expr)[qi::_val = qi::_1 + qi::_2] 
         | (factor >> '-' >> expr)[qi::_val = qi::_1 - qi::_2] 
         | factor; 

       qmark = qi::char_('?')[qi::_val = -1]; 

       start = qmark 
         | (expr % ','); 
     } 
}; 

} 

今日は、私は(私が思うに、それ以来アップグレードされている)を再度クレイ・マシン上で同じコードをコンパイルしてみました、私は、GCC 4.6.2およびGCC 4.5.2を試みたが、両方のブースト1.48とし、

/nics/b/home/mdorier/damaris-0.4/common/Calc.hpp:74:3: instantiated from 'Damaris::Calc<Iterator, SymTable>::Calc(SymTable&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, SymTable = Damaris::ParameterSet]' 
/nics/b/home/mdorier/damaris-0.4/common/MetadataManager.cpp:45:79: instantiated from here 
/nics/b/home/mdorier/deploy/include/boost/spirit/home/qi/detail/assign_to.hpp:123:13: error: invalid static_cast from type 'const boost::fusion::vector2<int, int>' to type 'int' 

Calc.hppにおけるライン74は、ライン「ファクター= ...」に対応:1.49は、と私はいつも、私は理解していない同じコンパイルエラーが発生します。 (MetadataManager.cpp:45)に示さ インスタンス化ラインは:

layoutInterp = new Calc<std::string::const_iterator,ParameterSet>(*parameters); 

layoutInterpタイプのCalc *およびパラメータ・タイプParameterSetであるからであると以下です。

このエラーの原因は何ですか?ありがとう

答えて

4

私はあなたのルールのものを並べ替えているかもしれないと確信しています。実際には、%=自動ルールの式の割り当ては、構文解析式の合成タイプがintに似ていないため機能しません。

基本的に、あなたは私が私の知る限り1を言うことができるように、いくつかの小さな問題を固定され、働くあなたのポストのSSCCEを作成している

factor = (simple >> '*' >> factor)[ _val = _1 * _2 ] 
     | (simple >> '/' >> factor)[ _val = _1/_2 ] 
     | (simple >> '%' >> factor)[ _val = _1 % _2 ] 
     | (simple) [_val = _1 ]; 

expr = (factor >> '+' >> expr)[ _val = _1 + _2 ] 
     | (factor >> '-' >> expr)[ _val = _1 - _2 ] 
     | (factor) [_val = _1 ]; 

factor %= (simple >> '*' >> factor)[ _val = _1 * _2 ] 
    | (simple >> '/' >> factor)[ _val = _1/_2 ] 
    | (simple >> '%' >> factor)[ _val = _1 % _2 ] 
    | simple; 

expr %= (factor >> '+' >> expr)[ _val = _1 + _2 ] 
    | (factor >> '-' >> expr)[ _val = _1 - _2 ] 
    | factor; 

に変更したいです:

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/karma.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

namespace sp = boost::spirit; 
namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 
namespace karma = boost::spirit::karma; 
namespace phx = boost::phoenix; 

namespace Damaris { 

    template <typename Iterator, typename SymTable> 
    struct Calc : qi::grammar<Iterator, std::vector<int>(), ascii::space_type> 
    { 
     qi::rule<Iterator, std::vector<int>(), ascii::space_type> start; 
     qi::rule<Iterator, int(), ascii::space_type> expr; 
     qi::rule<Iterator, int(), ascii::space_type> qmark; 
     qi::rule<Iterator, int(), ascii::space_type> factor; 
     qi::rule<Iterator, int(), ascii::space_type> simple; 
     qi::rule<Iterator, std::string(), ascii::space_type> identifier; 
     qi::rule<Iterator, int(SymTable), ascii::space_type> value; 

     Calc(SymTable &sym) : Calc::base_type(start) 
     { 
      using namespace qi; 

      identifier = lexeme[(alpha | '_') >> *(alnum | '_')]; 

      value = identifier[ _val = _r1[_1] ]; 

      simple = ('(' >> expr >> ')') 
        | int_ 
        | value(boost::phoenix::ref(sym)); 

      factor = (simple >> '*' >> factor)[ _val = _1 * _2 ] 
        | (simple >> '/' >> factor)[ _val = _1/_2 ] 
        | (simple >> '%' >> factor)[ _val = _1 % _2 ] 
        | (simple) [_val = _1 ]; 

      expr = (factor >> '+' >> expr)[ _val = _1 + _2 ] 
        | (factor >> '-' >> expr)[ _val = _1 - _2 ] 
        | (factor) [_val = _1 ]; 

      qmark = char_('?')[ _val = -1 ]; 

      start = qmark 
       | (expr % ','); 

      BOOST_SPIRIT_DEBUG_NODE(start); 
      BOOST_SPIRIT_DEBUG_NODE(qmark); 
      BOOST_SPIRIT_DEBUG_NODE(expr); 
      BOOST_SPIRIT_DEBUG_NODE(factor); 
      BOOST_SPIRIT_DEBUG_NODE(simple); 
      BOOST_SPIRIT_DEBUG_NODE(value); 
      BOOST_SPIRIT_DEBUG_NODE(identifier); 
     } 
    }; 

} 

int main(int argc, const char *argv[]) 
{ 
    typedef std::map<std::string, int> SymTable; 
    SymTable symbols; 
    Damaris::Calc<std::string::const_iterator, SymTable> calc(symbols); 

    symbols["TheAnswerToLifeUniverse"] = 100; 
    symbols["Everything"] = -58; 

    std::string input = "3*4+5/4, TheAnswerToLifeUniverse + Everything"; 
    std::string::const_iterator f(input.begin()), l(input.end()); 
    std::vector<int> data; 

    if (qi::phrase_parse(f,l,calc,ascii::space,data)) 
     std::cout << "output: " << karma::format(karma::int_ % ", " << karma::eol, data); 
    else 
     std::cout << "problem: '" << std::string(f,l) << "'\n"; 

    return 0; 
} 

出力:

output: 13, 42 

のgcc 4.6.1、後押し1_48

+0

は(http://en.wikipedia.org/ [ライフ、宇宙、およびすべての究極の質問への答え]を付属しますwiki/Phrases_from_The_Hitchhiker's_Guide_to_the_Galaxy#回答_to_the_Ultimate_Question_of_Life.2C_the_Universe.2C_and_Everything_.2842.29) – sehe

関連する問題