2013-02-21 54 views
5

我试图使用升压精神框架来定义我自己的语法,我定义这样的匹配规则:升压精神得到了全场比赛作为字符串

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

我想assing动作 - some_func - 到它的一部分,并传递整个匹配字符串作为参数。但不幸的是我会得到像vector<boost::variant<boost::fusion::vector2 ..a lot of stuff...)...>。我可以以某种方式获取整个数据作为char *,std :: string甚至void *的大小?

+0

什么是错的矢量? – 2013-02-21 01:27:14

+0

我将它描述为一个向量 >>>但它是由sehe编辑的。 – Dejwi 2013-02-21 16:18:03

回答

8

qi::as_string

演示程序的输出:

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

说实话,它看起来像你确实试图解析与可能的逃逸字符“逐字”字符串。在这方面,使用lexeme似乎是错误的(空间被吃掉)。如果您想查看转义字符串解析的样本,请参阅

一个简单的重排,我认为可以做,至少可能看起来像:

0然而

需要注意的是,你可以简单地声明该规则没有船长和删除lexeme总数: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; 
} 
+1

+1我早些时候会用'as_string'来回答,但是我不能在文档中找到它 - “解析器指令”,呃! – ildjarn 2013-02-21 01:36:35

+0

新增了一个具体说明,我认为_needs_在使用'lexeme'时会被固定。 – sehe 2013-02-21 08:11:27