c++ - 将 qi::lexeme 添加到 spirit qi 中的规则时编译失败

标签 c++ boost boost-spirit boost-spirit-qi

我一直在使用 Boost 库中的 Spirit Qi 用 C++ 编写语法。作为该语言的新手,很难习惯该库的语法和怪癖,但现在我有点了解它的工作原理。

我在使用 qi::lexeme 时遇到错误。我的实际语法相当大,所以我在存在相同问题的地方制作了一个小代码片段。以下代码编译无误:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/boost_tuple.hpp>

#include <set>
#include <iostream>
#include <string>
#include <complex>

namespace client
{
    namespace qi = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;

    typedef boost::tuple<char, char> range;
}

namespace client
{
    template <typename Iterator>
    struct employee_parser : qi::grammar<Iterator, range(), ascii::space_type>
    {
        employee_parser() : employee_parser::base_type(start)
        {
            using qi::lit;
            using qi::lexeme;
            using ascii::char_;

            range_rule = 
                char_("a-z") >> lit("-") >> char_("a-z")
                | char_("A-Z") >> lit("-") >> char_("A-Z")
                | char_("0-9") >> lit("-") >> char_("0-9")
                ;

            start = range_rule;
        }

        qi::rule<Iterator, range(), ascii::space_type> range_rule;
        qi::rule<Iterator, range(), ascii::space_type> start;
    };
}

int main()
{
    typedef std::string::const_iterator iterator_type;
    typedef client::employee_parser<iterator_type> employee_parser;
    employee_parser g;
    return 0;
}

现在,如果我替换行 start = range_rule; 并改用 start = lexeme[range_rule];,编译将失败。

正如我从 the docs 中读到的那样, lexeme[a] 应该保留主题解析器的属性,所以我不明白为什么它会失败。输出错误很大而且很神秘,所以我没有任何线索:

In file included from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/nonterminal.hpp:14:0,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi.hpp:21,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/include/qi.hpp:16,
                 from cpp/tests/test2.cpp:2:
/home/martin/vscode_cpp_projects/boost_1_68_0/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<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = boost::spirit::qi::detail::unused_skipper<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> > >; Attribute = boost::tuples::tuple<char, char>; Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; T1 = boost::tuples::tuple<char, char>(); 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> >, 0>; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’:
/home/martin/vscode_cpp_projects/boost_1_68_0/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<const char*, std::__cxx11::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = boost::spirit::qi::detail::unused_skipper<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> > >; Attribute = boost::tuples::tuple<char, char>; Subject = const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type>]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/directive/lexeme.hpp:66:64:   required from ‘typename boost::disable_if<boost::spirit::qi::detail::is_unused_skipper<Skipper>, bool>::type boost::spirit::qi::lexeme_directive<Subject>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >; Attribute = boost::tuples::tuple<char, char>; Subject = boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> >; typename boost::disable_if<boost::spirit::qi::detail::is_unused_skipper<Skipper>, bool>::type = bool]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:43:54:   required from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::call(Iterator&, const Iterator&, Context&, const Skipper&, mpl_::false_) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >; Context = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >; Parser = boost::spirit::qi::lexeme_directive<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> > >; Auto = mpl_::bool_<false>; mpl_::false_ = mpl_::bool_<false>]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:53:24:   required from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::operator()(Iterator&, const Iterator&, Context&, const Skipper&) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >; Context = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >; Parser
= boost::spirit::qi::lexeme_directive<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> > >; Auto = mpl_::bool_<false>]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/function_template.hpp:138:22:   required from ‘static R boost::detail::function::function_obj_invoker4<FunctionObj, R, T0, T1, T2, T3>::invoke(boost::detail::function::function_buffer&, T0, T1, T2, T3) [with FunctionObj = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::lexeme_directive<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> > >, mpl_::bool_<false> >; R = bool; T0 = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/function_template.hpp:936:38:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/function_template.hpp:1074:16:   required from ‘boost::function<R(T0, T1, T2, T3)>::function(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::lexeme_directive<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> > >, mpl_::bool_<false> >; R = bool; T0 = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/function_template.hpp:1127:5:   required from ‘typename boost::enable_if_c<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::lexeme_directive<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> > >,
mpl_::bool_<false> >; R = bool; T0 = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >&, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&)>&]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/nonterminal/rule.hpp:183:19:   required from ‘static void boost::spirit::qi::rule<Iterator,
T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::lexeme>, 0>&, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2>; Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; T1 = boost::tuples::tuple<char, char>(); 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> >, 0>; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::true_ = mpl_::bool_<true>]’
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/nonterminal/rule.hpp:221:32:   required from ‘boost::spirit::qi::rule<Iterator, T1, T2, T3,
T4>& boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::lexeme>, 0>&, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2>; Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; T1 = boost::tuples::tuple<char, char>(); 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> >, 0>; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’
cpp/tests/test2.cpp:40:19:   required from ‘client::employee_parser<Iterator>::employee_parser() [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >]’
cpp/tests/test2.cpp:56:21:   required from here
/home/martin/vscode_cpp_projects/boost_1_68_0/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<const char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >&, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&)>}) (__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >, boost::tuples::tuple<char, char>(), 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> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type>::context_type&, const boost::spirit::qi::detail::unused_skipper<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))
                 ^~
In file included from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/detail/maybe_include.hpp:43:0,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/detail/function_iterate.hpp:14,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/preprocessor/iteration/detail/iter/forward1.hpp:67,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/function.hpp:70,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/nonterminal/rule.hpp:16,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi/nonterminal.hpp:14,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/home/qi.hpp:21,
                 from /home/martin/vscode_cpp_projects/boost_1_68_0/boost/spirit/include/qi.hpp:16,
                 from cpp/tests/test2.cpp:2:
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/function_template.hpp:763: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<const char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<boost::tuples::tuple<char, char>&, boost::fusion::nil_>, boost::fusion::vector<> >&; 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
                 ^~~~~~~~
/home/martin/vscode_cpp_projects/boost_1_68_0/boost/function/function_template.hpp:763:17: note:   no known conversion for argument 4 from ‘const boost::spirit::qi::detail::unused_skipper<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> > >’ to ‘const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >&’

最佳答案

As I read from the docs, lexeme[a] should preserve the subject parser's attributes, so I can't understand why it fails.

是的,它保留了属性。它保留 skipper (原因很明显),并且您的range_rule 声明了一个。编译器消息包含以下信息:

BOOST_STATIC_ASSERT_MSG((is_same<skipper_type, unused_type>::value ||
            !is_same<Skipper, unused_type>::value),
            "The rule was instantiated with a skipper type but you have not pass any. "
            "Did you use `parse` instead of `phrase_parse`?");

因此,从 range_rule 中删除 skipper 。具有讽刺意味的是,只是删除它会隐式地使它表现得像一个词素,所以你无论如何都不需要 lexeme[] 围绕它。

另见 Boost spirit skipper issues

简而言之:

  • 不能调用需要 skipper 而没有 skipper 的规则
  • 可以从具有 skipper 上下文的解析器调用隐式词素规则

我通常将我的规则分组以尽可能多地表示,并在它们前面加上评论,例如:

  private:
    qi::rule<Iterator, range(), ascii::space_type> start;

    // lexmes
    qi::rule<Iterator, range()> range_rule;

但我通常也会封装 skipper ,除非调用者更改 skipper 真的有意义(?!)。

另见类似任务:

建议的修复

Live On Coliru

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/boost_tuple.hpp>

#include <set>
#include <iostream>
#include <string>
#include <complex>

namespace client
{
    namespace qi = boost::spirit::qi;
    typedef boost::tuple<char, char> range;
}

namespace client
{
    template <typename Iterator>
    struct employee_parser : qi::grammar<Iterator, range()>
    {
        employee_parser() : employee_parser::base_type(start)
        {
            using qi::lit;
            using qi::lexeme;
            using qi::ascii::char_;

            range_rule = 
                char_("a-z") >> lit("-") >> char_("a-z")
              | char_("A-Z") >> lit("-") >> char_("A-Z")
              | char_("0-9") >> lit("-") >> char_("0-9")
              ;

            start = qi::skip(qi::ascii::space) [ range_rule ];
        }

      private:
        qi::rule<Iterator, range()> start;

        // lexmes
        qi::rule<Iterator, range()> range_rule;
    };
}

int main()
{
    typedef std::string::const_iterator iterator_type;
    typedef client::employee_parser<iterator_type> employee_parser;
    employee_parser g;

    std::string const input("a-k");
    client::range r;
    return parse(begin(input), end(input), g, r)
        ? 0
        : 1;
}

关于c++ - 将 qi::lexeme 添加到 spirit qi 中的规则时编译失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57817852/

相关文章:

c# - 有没有一种简单有效的方法可以在 C# 或 C/C++ 中列出所有 USB 设备?

c++ - 在模板类上 boost property_tree : multiple values per key,

c++ - boost spirit x3 : parse into structs

c++ - glsl解析器的boost wave或spirit

c++ - 如何在 MVS 中使用 OpenGL 绘制实时二维图形

c++ - 上下文菜单适用于子组件但不适用于父组件

lhs 上的 C++ 模板和函数

c++ - io_service::run() 永不返回

gcc - 将 boost 版本从 1.52 切换到 1.53 后与 GCC 链接失败

c++ - boost::spirit::position_iterator2 的奇怪错误