无法编译用Boost :: Spirit库编写的简单解析器

时间:2015-06-12 08:17:39

标签: c++ boost

以下是一个最小尺寸的程序,我无法在Boost :: spirit库中编译。

    #include <iostream>
    #include <string>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/lexical_cast.hpp>
    using namespace boost::spirit;

    template <typename Iterator>
    struct z3_exp_grammars : qi::grammar<Iterator, std::string(), ascii::space_type>
    {
        z3_exp_grammars() : z3_exp_grammars::base_type(text)
        {


            text = qi::int_[qi::_val = boost::lexical_cast<std::string>(qi::_1)];
         }

        qi::rule<Iterator, std::string(), ascii::space_type> text;

    };


    int main(){

        std::string test("3");
            std::string result;
            std::string::const_iterator beg = test.begin();
            std::string::const_iterator end = test.end();
            typedef z3_exp_grammars<std::string::const_iterator> z3_exp_grammars;
            z3_exp_grammars par;
            qi::phrase_parse(beg,end,par,result);
            std::cout<<"Result is "<<result<<std::endl;
}

我希望在变量结果中看到字符串3,但代码没有编译。而不是查看错误日志(由于模板而非常具有威胁性),如果有人能够在代码中发现我的错误,那将会很棒。谢谢你的帮助。

使用编译T.C提供的相同代码后得到的编译错误更新问题。

Test.cpp:9:11: error: expected nested-name-specifier before ‘result_type’
Test.cpp:9:11: error: using-declaration for non-member at class scope
Test.cpp:9:23: error: expected ‘;’ before ‘=’ token
Test.cpp:9:23: error: expected unqualified-id before ‘=’ token
In file included from /home/jaganmohini/Downloads/boost_1_58_0/boost/proto/proto_fwd.hpp:28:0,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/phoenix/core/limits.hpp:26,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/spirit/include/phoenix_limits.hpp:11,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/spirit/home/support/meta_compiler.hpp:16,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/spirit/home/qi/action/action.hpp:14,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/spirit/home/qi/action.hpp:14,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/spirit/home/qi.hpp:14,
                 from /home/jaganmohini/Downloads/boost_1_58_0/boost/spirit/include/qi.hpp:16,
                 from Test.cpp:3:
/home/jaganmohini/Downloads/boost_1_58_0/boost/utility/result_of.hpp: In instantiation of ‘boost::detail::result_of_nested_result<const to_string_, const to_string_(int&)>’:
/home/jaganmohini/Downloads/boost_1_58_0/boost/utility/result_of.hpp:197:1:   instantiated from ‘boost::detail::tr1_result_of_impl<const to_string_, const to_string_(int&), false>’

2 个答案:

答案 0 :(得分:2)

两个单独的问题:

  1. phrase_parse期待船长作为其第四个参数。因此,您应该使用qi::phrase_parse(beg, end, par, ascii::space, result);

  2. 您不能在像这样的凤凰占位符上使用boost::lexical_cast。它受到了热切的评价。您需要create a lazy function

    struct to_string_ {
        using result_type = std::string;
        template<class T>
        std::string operator()(const T& arg) const {
            return boost::lexical_cast<std::string>(arg); 
        }
    };
    
    boost::phoenix::function<to_string_> to_string;
    

    并做

    text = qi::int_[qi::_val = to_string(qi::_1)];
    
  3. Demo

答案 1 :(得分:1)

你不能表演&#34;渴望&#34;功能于&#34;懒惰&#34;演员如qi::_1

qi::_1的类型只是qi::_1_type:它是占位符。

要么你必须

  • 调整功能
  • 创建/包装一个懒惰的仿函数(boost::phoenix::function<>BOOST_PHOENIX_ADAPT_FUNCTION等)
  • 使用phx::bind例如用lambda
  • 传递一个可调用的原始语义操作(参见docs)

在这种情况下,我会上述 ,因为在实施解析器时使用lexical_cast是可疑的(这就像放置收据一样你在床下的袜子里开户,或者喜欢开车去自行车棚。

我在这里解析了一个int(因为那正是qi::int_旨在匹配公开的内容)。

如果您想要匹配为int的输入字符串,请使用

    text = qi::raw [ qi::int_ ];

如果你坚持&#34;重新格式化&#34;,我会这样做:

<强> Live On Coliru

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/lexical_cast.hpp>

namespace qi = boost::spirit::qi;

int main()
{
    using It = std::string::const_iterator;
    std::string const test("3");

    It beg = test.begin(), end = test.end();

    int result;
    if (qi::phrase_parse(beg, end, qi::int_, qi::space, result))
        std::cout << "Result is " << boost::lexical_cast<std::string>(result) << std::endl;
}

注意:

  • 单独关注(解析与演示)
  • phrase_parse中传递队长:)