2013-05-27 47 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_的語法,但我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

笑@「簡單的boost ::精神文法」 –

+2

正如你已經發現,有沒有簡單的升壓精神的語法。改用ANTLR。 –

+0

那天我和IRC的助推團隊中的一位善良的人談過話,並問道爲什麼Spirit的文檔覆蓋率很低。他驚呼其實際上有很好的文件記錄......使用ANTLR。 – Kivin

回答

11

答:有錯誤的語法 什麼 ,但你使用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

終於解決了。錯誤在於我在一個字符串上使用了一個迭代器而不是一個常量字符串......我感覺真的很愚蠢。你的一段代碼讓我意識到這一點,再次感謝回覆! – jay1189947

+0

很高興聽到你得到它的工作:) – sehe

相關問題