首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提升精神气:专业uint_parser的更名

提升精神气:专业uint_parser的更名
EN

Stack Overflow用户
提问于 2017-05-24 10:45:47
回答 1查看 52关注 0票数 2

我刚刚在Qi中实现了一个基本的解析器来验证一个指定的TCP端口范围,例如80-444。

代码语言:javascript
复制
  template<class It>
  struct port_range_grammar : qi::grammar<It, port_range_type()>
  {
    port_range_grammar()
      : port_range_grammar::base_type(start, "port_range")
    {
      using qi::lit;

      start = port > lit("-") > port;
    }

  private:
    qi::rule<It, port_range_type()> start;
    qi::uint_parser<uint16_t, 10, 2, 5> port;
  };

为了使错误更具描述性,我在start规则上附加了一个错误处理程序(在一些高级语法中,它嵌入了这个规则),例如:

代码语言:javascript
复制
 // this how the code is attached to the start rule in the top level grammar:

  start = (tcp_endpoint | ipc_endpoint | inproc_endpoint)[_val=_1] > eoi;

  on_error<fail>
    ( start
    , pnx::bind
      ( [](auto const& what, auto begin, auto end)
          {
            ERROR_AC << "Expecting "
                     << what
                     << " here: '"
                     << std::string(begin, end)
                     << "'"
            ;
          }
      , _4
      , _3
      , _2
      )
    )
  ;

所有操作都很好,只有一个小例外,当我作为端口传递无效的16位无符号数字时,我看到一个错误,但它的描述性不够:

代码语言:javascript
复制
Expecting <unsigned-integer> here: '74888'

现在,库的用户无法理解74888是无效的16位uint。unsiged-integer是一个附加在qi::uint_parser上的标记。有办法改变这个标签吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-24 12:11:01

我只需将一个名称附加到一个非终端规则:

代码语言:javascript
复制
        port = uint_parser<uint16_t, 10, 2, 5>();
        port.name("valid port number 10-65535");

看吧,住在Coliru

代码语言:javascript
复制
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace pnx = boost::phoenix;

using port_range_type = std::pair<uint16_t, uint16_t>;

template<class It>
struct port_range_grammar : qi::grammar<It, port_range_type()>
{
    port_range_grammar()
        : port_range_grammar::base_type(start, "port_range")
    {
        using namespace qi;
        port = uint_parser<uint16_t, 10, 2, 5>();
        port.name("valid port number 10-65535");

        start = port > lit("-") > port;
        /*start = (tcp_endpoint | ipc_endpoint | inproc_endpoint)[_val=_1] > eoi;*/

        on_error<fail>
            ( start
              , pnx::bind
              ( [](auto const& what, auto begin, auto end)
                {
                    std::cerr << "Expecting "
                        << what
                        << " here: '"
                        << std::string(begin, end)
                        << "'\n"
                        ;
                } , _4 , _3 , _2
              )
            )
            ;
    }

  private:
    qi::rule<It, port_range_type()> start;
    qi::rule<It, uint16_t()> port;
};

int main() {
    using It = std::string::const_iterator;
    std::string const input = "11-1q0";

    It f = input.begin(), l = input.end();
    port_range_type range;
    bool ok = qi::parse(f, l, port_range_grammar<It>{}, range);

    if (ok) {
        std::cout << "Parsed port " << range.first << " to " << range.second << "\n";
    } else {
        std::cout << "Parse failed\n";
    }

    if (f!=l)
        std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}

打印

代码语言:javascript
复制
Expecting <valid port number 10-65535> here: '1q0'
Parse failed
Remaining unparsed: '11-1q0'
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44156112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档