【问题标题】:Using simple Boost::Spirit grammars?使用简单的 Boost::Spirit 语法?
【发布时间】:2013-05-22 16:39:56
【问题描述】:

我无法使用语法,所以我对其进行了简化,直到它只解析一个整数。仍然无法让它工作。就是如下语法:

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&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator >, Context = boost::spirit::context, boost::spirit::locals >, Skipper = boost::spirit::unused_type, Attribute = int, Subject = const boost::spirit ::qi::rule<:__normal_iterator>, int(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>]': /boost/spirit/home/qi/parse.hpp:89:82: 从 'bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) 实例化 [with Iterator = __gnu_cxx::__normal_iterator > , expr = rangeGrammar<:__normal_iterator>>, Attr = int]' ../parameter_parser.h:95:46: 从这里实例化 boost/spirit/home/qi/reference.hpp:43:71: 错误: 没有匹配函数调用'boost::spirit::qi::rule<:__normal_iterator>, int(), boost::spirit ::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>::parse(__gnu_cxx::__normal_iterator >&, const __gnu_cxx::__normal_iterator >&, boost::spirit::context, boost:: Spirit::locals >&, const boost::spirit::unused_type&, int&) const' cc1plus:警告被视为错误 /boost/spirit/home/qi/reference.hpp:44:9:错误:控制到达非空函数的结尾 * 退出状态 1 *

无法弄清楚问题所在。任何帮助将不胜感激。

【问题讨论】:

  • 大声笑@“简单的 Boost::spirit 语法”
  • 如您所见,没有简单的 Boost Spirit 语法。请改用 ANTLR。
  • 前几天,我在 IRC 上与 boost“团队”的一位好心人交谈,并询问为什么 Spirit 的文档覆盖率如此之低。他惊呼它实际上有很好的记录...... +1 使用 ANTLR。
  • @Kivin 您对 Spirit 文档有何不满?它有据可查。作为 eDSL,它并不简单,诊断也不简单。如果它不适合你,那就不适合你。但我非常怀疑文档是否会成为决定性因素?

标签: c++ boost-spirit-qi


【解决方案1】:

答:语法没有nothing 少许错误,但您使用的是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;
}

【讨论】:

  • 感谢您的回复!你是对的, parse_phrase() 必须包含一个船长,我不知道这一点。我将代码更改为使用 parse() ,但同样的错误仍然存​​在。如果您阅读第一个错误,它会说:“错误:没有调用'boost::spirit::qi::rule<...>
  • 终于解决了。错误是我在字符串上使用迭代器而不是 const 字符串......我觉得很愚蠢。您的一段代码让我意识到这一点,再次感谢您的回复!
猜你喜欢
  • 2012-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
相关资源
最近更新 更多