使用简单的Boost :: Spirit语法?

时间:2013-05-27 19:49:49

标签: c++ boost-spirit-qi

我无法使用语法,因此我将其简化为只解析整数。仍然无法让它发挥作用。它是以下语法:

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_作为语法,但我不知道这个例子中有什么问题)。

我的解析功能是:

/* 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:在成员函数'bool boost :: spirit :: qi :: reference :: parse(Iterator&amp;,const Iterator&amp;,Context&amp;,const Skipper&amp;,Attribute&amp; amp ;)const [与Iterator = __gnu_cxx :: __ normal_iterator&gt;,Context = boost :: spirit :: context,boost :: spirit :: locals&lt;&gt; &gt;,Skipper = boost :: spirit :: unused_type,Attribute = int,Subject = const boost :: spirit :: qi :: rule&lt; __ gnu_cxx :: __ normal_iterator&gt;,int(),boost :: spirit :: unused_type, boost :: spirit :: unused_type,boost :: spirit :: unused_type&gt;]':   /boost/spirit/home/qi/parse.hpp:89:82:从'bool boost :: spirit :: qi :: parse(Iterator&amp;,Iterator,const Expr&amp;,Attr&amp;)实例化[与Iterator = __gnu_cxx: :__ normal_iterator&gt;,Expr = rangeGrammar&lt; __ gnu_cxx :: __ normal_iterator&gt; &gt;,Attr = int]'   ../parameter_parser.h:95:46:从这里实例化   boost / spirit / home / qi / reference.hpp:43:71:错误:调用'boost :: spirit :: qi :: rule&lt; __ gnu_cxx :: __ normal_iterator&gt;,int(),boost ::没有匹配函数spirit :: unused_type,boost :: spirit :: unused_type,boost :: spirit :: unused_type&gt; :: parse(__ gnu_cxx :: __ normal_iterator&gt;&amp;,const __gnu_cxx :: __ normal_iterator&gt;&amp;,boost :: spirit :: context,boost :: spirit :: locals&lt;&gt;&gt;&amp;,const boost :: spirit :: unused_type&amp;,int&amp;)const'   cc1plus:警告被视为错误   /boost/spirit/home/qi/reference.hpp:44:9:错误:控件到达非void函数结束    *退出状态1 *

无法弄清问题是什么。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:11)

答:语法中没有没有 错误,但你使用qi::phrase_parse需要一个队长。使用qi::parse,问题就会消失。

注1:使用[_val=_1]完全是多余的;没有语义属性的规则享受自动属性传播

注2:您可能希望使用qi :: match进行这样的解析:

#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'函数,运行测试显示了更好的Qi练习元素:

#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;
}