增强精神使整个比赛像弦一样 [英] Boost spirit get the whole match as a string

查看:49
本文介绍了增强精神使整个比赛像弦一样的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Boost Spirit框架定义自己的语法,并且正在定义这样的匹配规则:

I'm trying to define my own grammar using boost spirit framework and I'm defining such a matching rule:

value = (
        char_('"') >>
        (*qi::lexeme[
                char_('\\') >> char_('\\') |
                char_('\\') >> char_('"')  |
                graph - char_('"') |
                char_(' ')
        ])[some_func] >>
        char_('"')
);

我想将一个动作-some_func-赋给它的一部分,并将整个匹配的字符串作为参数传递.但不幸的是我会得到 vector< boost :: variant< boost :: fusion :: vector2 ..很多东西...)...> 之类的东西.我能以某种方式将整个数据作为具有大小的char *,std :: string或什至void *来获取吗?

I'd like to assing an action - some_func - to the part of it, and pass the whole matching string as a parameter. But unfortunately I will get something like vector<boost::variant<boost::fusion::vector2 ..a lot of stuff...)...> . Can I somehow get the whole data as a char*, std::string or even void* with size?

推荐答案

查看演示程序的输出:

DEBUG: 'some\\"quoted\\"string.'
parse success

老实说,您似乎真的在尝试使用可能的转义字符来解析'verbatim'字符串.在这方面,使用 lexeme 似乎是错误的(空格被占用了).如果您想查看转义字符串解析的示例,请参见例如

To be honest, it looks like you are really trying to parse 'verbatim' strings with possible escape chars. In the respect, the use of lexeme seem wrong (the spaces get eaten). If you want to see samples of escaped string parsing, see e.g.

  • Boost Spirit Implement small one-line DSL on a server application (for this style)
  • Compiling a simple parser with Boost.Spirit (for escaping by duplication)
  • Parsing escaped strings with boost spirit
  • Parse quoted strings with boost::spirit

我认为可以进行一次简单的重新排列,至少看起来像这样:

A simple rearrangement that I think could be made, at least might look like:

  value = qi::lexeme [ 
          char_('"') >>
          qi::as_string [
           *(
                 string("\\\\") 
               | string("\\\"") 
               | (graph | ' ') - '"'
            )
          ] [some_func(_1)] >>
          char_('"')
      ];

但是请注意,您可以简单地声明规则而不使用船长,并将所有 lexeme 放在一起: http://liveworkspace.org/code/1oEhei$0

Note however that you could simply declare the rule without a skipper and drop the lexeme alltogether: http://liveworkspace.org/code/1oEhei$0

代码(在 liveworkspace 上直播)

#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi    = boost::spirit::qi;
namespace phx   = boost::phoenix;

struct some_func_t 
{
    template <typename> struct result { typedef void type; };
    template <typename T> 
        void operator()(T const& s) const
        {
            std::cout << "DEBUG: '" << s << "'\n";
        }
};

template <typename It, typename Skipper = qi::space_type>
    struct parser : qi::grammar<It, Skipper>
{
    parser() : parser::base_type(value)
    {
        using namespace qi;
        // using phx::bind; using phx::ref; using phx::val;

        value = (
                 char_('"') >>
                     qi::as_string
                     [
                         (*qi::lexeme[
                          char_('\\') >> char_('\\') |
                          char_('\\') >> char_('"')  |
                          graph - char_('"') |
                          char_(' ')
                          ])
                     ] [some_func(_1)] >>
                 char_('"')
            );
        BOOST_SPIRIT_DEBUG_NODE(value);
    }

  private:
    qi::rule<It, Skipper> value;
    phx::function<some_func_t> some_func;
};

bool doParse(const std::string& input)
{
    typedef std::string::const_iterator It;
    auto f(begin(input)), l(end(input));

    parser<It, qi::space_type> p;

    try
    {
        bool ok = qi::phrase_parse(f,l,p,qi::space);
        if (ok)   
        {
            std::cout << "parse success\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("\"some \\\"quoted\\\" string.\"");
    return ok? 0 : 255;
}

这篇关于增强精神使整个比赛像弦一样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆