簡體   English   中英

無法以增強精神指定隊長(編譯器錯誤)

[英]Can not specify a skipper in boost spirit (compiler error)

我正在嘗試使用boost::spirit構建一個解析器,該解析器除了其他功能外,還應該能夠解析成對的整數,例如“(3,4)”。

我的代碼正在運行,但我也想接受包含空格的對,即“(4,6)”。 當嘗試按boost spirit教程中所示添加space_type船長時,以下代碼無法編譯。 我看不到我正在犯的嚴重錯誤(我懷疑使用了錯誤的名稱空間,但這似乎是正確的名稱空間)。

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/std_pair.hpp>

using namespace std;
using namespace boost::spirit::qi;

using position = std::pair<int,  int>;

template<typename Iterator>
struct position_grammar : grammar<Iterator, position(), boost::spirit::ascii::space_type> {
    position_grammar() : position_grammar::base_type(start) {
        start = lit("(") >> int_ >> lit(",") >> int_ >> lit(")");
    }
    rule<Iterator, position(),boost::spirit::ascii::space_type> start;
};

int main() {
    std::string s = "(1,2)";
    position_grammar<std::string::iterator> grammar;
    position p;
    bool r = parse(s.begin(), s.end(), grammar,p);
    cout << "parsing: " << r << " position: " << p.first << ", " << p.second << "\n";
    return 0;
}

編譯器輸出:

In file included from /usr/include/boost/spirit/home/qi/nonterminal.hpp:14:0,
                 from /usr/include/boost/spirit/home/qi.hpp:21,
                 from /usr/include/boost/spirit/include/qi.hpp:16,
                 from /home/pansen/proggs/foo/src/foo/model/routing_parser_test.cpp:2:
/usr/include/boost/spirit/home/qi/nonterminal/rule.hpp: In instantiation of ‘bool boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Context = boost::spirit::context<boost::fusion::cons<std::pair<int, int>&, boost::fusion::nil_>, boost::spirit::locals<> >; Skipper = boost::spirit::unused_type; Attribute = std::pair<int, int>; Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; T1 = std::pair<int, int>(); T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’:
/usr/include/boost/spirit/home/qi/reference.hpp:43:72:   required from ‘bool boost::spirit::qi::reference<Subject>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<std::pair<int, int>&, boost::fusion::nil_>, boost::spirit::locals<> >; Skipper = boost::spirit::unused_type; Attribute = std::pair<int, int>; Subject = const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >, std::pair<int, int>(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::spirit::unused_type, boost::spirit::unused_type>]’
/usr/include/boost/spirit/home/qi/parse.hpp:86:82:   required from ‘bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Expr = position_grammar<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> > >; Attr = std::pair<int, int>]’
/usr/include/boost/spirit/home/qi/parse.hpp:98:25:   required from ‘bool boost::spirit::qi::parse(const Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Expr = position_grammar<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> > >; Attr = std::pair<int, int>]’
/home/pansen/proggs/foo/src/foo/model/routing_parser_test.cpp:23:46:   required from here
/usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:304:17: error: no match for call to ‘(const function_type {aka const boost::function<bool(__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<std::pair<int, int>&, boost::fusion::nil_>, boost::fusion::vector0<> >&, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&)>}) (__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >, std::pair<int, int>(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::spirit::unused_type, boost::spirit::unused_type>::context_type&, const boost::spirit::unused_type&)’
                 if (f(first, last, context, skipper))
                 ^
In file included from /usr/include/boost/function/detail/maybe_include.hpp:33:0,
                 from /usr/include/boost/function/detail/function_iterate.hpp:14,
                 from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:67,
                 from /usr/include/boost/function.hpp:64,
                 from /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:16,
                 from /usr/include/boost/spirit/home/qi/nonterminal.hpp:14,
                 from /usr/include/boost/spirit/home/qi.hpp:21,
                 from /usr/include/boost/spirit/include/qi.hpp:16,
                 from /home/pansen/proggs/foo/src/foo/model/routing_parser_test.cpp:2:
/usr/include/boost/function/function_template.hpp:767:17: note: candidate: boost::function4<R, T1, T2, T3, T4>::result_type boost::function4<R, T1, T2, T3, T4>::operator()(T0, T1, T2, T3) const [with R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<std::pair<int, int>&, boost::fusion::nil_>, boost::fusion::vector0<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&; boost::function4<R, T1, T2, T3, T4>::result_type = bool]
     result_type operator()(BOOST_FUNCTION_PARMS) const
                 ^
/usr/include/boost/function/function_template.hpp:767:17: note:   no known conversion for argument 4 from ‘const boost::spirit::unused_type’ to ‘const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&’

錯誤指向if (f(first, last, context, skipper)) ,看起來像這里的錯誤(請參見sehe的答案)。 但是我已經正確指定了屬性(至少我認為是這樣)。

如果您想使用一個船長,則必須通過調用它的一個實例來傳遞它的一個實例,方法是調用phrase_parse而不是parse

bool r = phrase_parse(s.begin(), s.end(), grammar, qi::space, p);

另外,您可以通過在帶有skip(qi::space) [ real_start_rule_with_skipper ]船長規則中聲明該船長來隱藏有關船長的詳細信息

另請參閱: 提高精神隊長的問題

筆記:

  • 不要using namespace - 特別是不要同時使用stdboost::spirit::qi 您可以始終使用using namespace qi; 本地
  • 無需將所有文字都包裝在lit() 這是簡化的規則:

     position_rule = '(' >> qi::int_ >> ',' >> qi::int_ >> ')'; 

DEMO

生活在Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace qi = boost::spirit::qi;

using position = std::pair<int, int>;

template <typename Iterator> struct position_grammar : qi::grammar<Iterator, position()> {
    position_grammar() : position_grammar::base_type(start) {

        position_rule = '(' >> qi::int_ >> ',' >> qi::int_ >> ')';
        start         = qi::skip(boost::spirit::ascii::space) [ position_rule ];

    }
    qi::rule<Iterator, position()> start;
    qi::rule<Iterator, position(), boost::spirit::ascii::space_type> position_rule;
};

int main() {
    std::string s = "  ( 1\t,\r\n2 )";
    position_grammar<std::string::iterator> grammar;
    position p;

    bool r = parse(s.begin(), s.end(), grammar, p);

    std::cout << "parsing: " << r << " position: " << p.first << ", " << p.second << "\n";
}

打印

parsing: 1 position: 1, 2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM