2013-05-27 15 views
5

文法を働かせることができませんでしたので、整数を解析するまで単純化しました。まだそれを働かせることはできません。これは、次の文法である:ちょうど、整数を解析することになっている簡単なBoost :: Spirit文法を使用していますか?

template<typename Iterator> 
struct rangeGrammar : qi::grammar<Iterator, int()> 
{ 
    rangeGrammar() : 
    rangeGrammar::base_type(number) 
    { 
     using qi::int_; 
     using qi::_1; 
     using qi::_val; 

     number = int_[_val = _1]; 
    } 
    qi::rule<Iterator, int()> number; 
}; 

(私はちょうど文法としてINT_使用するparse関数を言うことができる知っているが、私はこれで間違っているかを知るためにwan't例)。

私の解析機能は次のとおりです。

/* n is a std::string provided by the user */ 
rangeGrammar<std::string::const_iterator> grammar; 
int num = 0; 
qi::phrase_parse(n.start(), n.end(), grammar, num); 
std::cout << "Number: " << num << std::endl; 

は、私は、次のコンパイラエラーを取得:

/boost/spirit/home/qi/reference.hpp: In member function ‘bool boost::spirit::qi::reference::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator >, Context = boost::spirit::context, boost::spirit::locals<> >, Skipper = boost::spirit::unused_type, Attribute = int, Subject = const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator >, int(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>]’: /boost/spirit/home/qi/parse.hpp:89:82: instantiated from ‘bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator >, Expr = rangeGrammar<__gnu_cxx::__normal_iterator > >, Attr = int]’ ../parameter_parser.h:95:46: instantiated from here boost/spirit/home/qi/reference.hpp:43:71: error: no matching function for call to ‘boost::spirit::qi::rule<__gnu_cxx::__normal_iterator >, int(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>::parse(__gnu_cxx::__normal_iterator >&, const __gnu_cxx::__normal_iterator >&, boost::spirit::context, boost::spirit::locals<> >&, const boost::spirit::unused_type&, int&) const’ cc1plus: warnings being treated as errors /boost/spirit/home/qi/reference.hpp:44:9: error: control reaches end of non-void function * exit status 1 *

は、問題が何であるかを把握することはできません。どんな助けでも大歓迎です。

+7

笑@「シンプルブースト::精神は文法」あなたが発見したよう –

+2

を、単純なブーストスピリット文法はありません。代わりにANTLRを使用してください。 –

+0

先日、私はIRCのブースト「チーム」から親切に話を聞き、スピリットがそのような低いドキュメンテーションカバレッジを持つ理由を尋ねました。彼はそれが実際に非常によく文書化されていると叫んだ... ANTLRの使用+1。 – Kivin

答えて

11

A:あり文法と 何も 少し間違っているのですが、あなたは船長が必要ですqi::phrase_parseを使用しています。 qi::parseを使用すると問題が解決します。

注1:[_val=_1]を使用すると完全に冗長です。 意味規則なしの規則自動属性伝播を楽しむ規則。

注2:あなたは、このようにパースを行うに気::一致を使用することがあります:

#include <boost/spirit/include/qi_match.hpp> 

const std::string input = "1234"; 
std::istringstream iss(input); 
iss >> qi::match(qi::int_ [ std::cout << qi::_1 ]); 

最後にご関心をが、ここではスケルトンショーというテストを実行すると「doParse」関数です良いチーの練習のいくつかのより多くの要素:

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

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

template<typename Iterator> 
struct rangeGrammar : qi::grammar<Iterator, int()> 
{ 
    rangeGrammar() : rangeGrammar::base_type(number) 
    { 
     number = qi::int_; 
    } 
    qi::rule<Iterator, int()> number; 
}; 

bool doParse(const std::string& input) 
{ 
    typedef std::string::const_iterator It; 
    It f(begin(input)), l(end(input)); 

    try 
    { 
     rangeGrammar<It> p; 
     int data; 

     bool ok = qi::parse(f,l,p,data); 
     if (ok) 
     { 
      std::cout << "parse success\n"; 
      std::cout << "data: " << data << "\n"; 
     } 
     else  std::cerr << "parse failed: '" << std::string(f,l) << "'\n"; 

     if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n"; 
     return ok; 
    } catch(const qi::expectation_failure<It>& e) 
    { 
     std::string frag(e.first, e.last); 
     std::cerr << e.what() << "'" << frag << "'\n"; 
    } 

    return false; 
} 

int main() 
{ 
    bool ok = doParse("1234"); 
    return ok? 0 : 255; 
} 
+0

返信いただきありがとうございます!そうです、parse_phrase()にはスキッパーが含まれている必要があります。私はそれを認識していませんでした。代わりにparse()を使用するようにコードを変更しましたが、同じエラーがそのまま残ります。最初のエラーを読んだ場合、「エラー: 'boost :: spirit :: qi :: rule <...」を呼び出す関数がありません。これは私の持つ唯一のルールと何か関係がありますか?しかし、私はそれに間違って何も表示されません。また、私がやろうとしていることを達成するためのもっと簡単な方法があることを知っていますが、私は間違いを見つけるために文法を単純化しました。 – jay1189947

+0

最後に解決しました。間違いは、私は文字列ではなくconst文字列ではなく、イテレータを使用していたということでした。あなたのコードは私にこれを実感させました。返信にもう一度感謝します! – jay1189947

+0

うれしいことを聞いてうれしいです:) – sehe

関連する問題