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

Not able to compile a simple parser written in Boost::Spirit library

本文关键字:简单 编译 Boost Spirit      更新时间:2023-10-16

下面是一个最小尺寸的程序,我无法在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>’

两个独立的问题:

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

  2. 你不能在这样的凤凰占位符上使用boost::lexical_cast。它被热切地评估。你需要创建一个惰性函数:

    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)];
    

演示。

你不能像qi::_1这样对"懒惰"的演员执行"渴望"的功能。

qi::_1的类型很简单qi::_1_type:它是一个占位符。

要么你必须

  • 调整功能
  • 创建/包装一个惰性函子(boost::phoenix::function<>BOOST_PHOENIX_ADAPT_FUNCTION等)
  • 使用phx::bind例如与λ一起使用
  • 传递可调用的原始语义操作(请参阅文档)

在这种情况下,我不会做上述任何一项,因为在实现解析器时使用lexical_cast是可疑的(这就像将银行帐户的收据放在床下的袜子里一样。或者像开车去自行车棚一样)。

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

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

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

如果你坚持"重新格式化",我会做:

住在科里鲁

#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 :)通过船长