c++ 振奋精神把整场比赛练成一根弦

juud5qan  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(112)

我试图使用boost spirit框架定义我自己的语法,我定义了这样一个匹配规则:

  1. value = (
  2. char_('"') >>
  3. (*qi::lexeme[
  4. char_('\\') >> char_('\\') |
  5. char_('\\') >> char_('"') |
  6. graph - char_('"') |
  7. char_(' ')
  8. ])[some_func] >>
  9. char_('"')
  10. );

我想将一个动作some_func分配给它的一部分,并将整个匹配字符串作为参数传递。但不幸的是,我会得到类似vector<boost::variant<boost::fusion::vector2 ..a lot of stuff...)...>的东西。我能以char*、std::string或void* 的形式获取整个数据吗?

izj3ouym

izj3ouym1#

查看qi::as_string
演示程序输出:

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

老实说,看起来你真的是在尝试解析可能带有转义字符的“逐字”字符串。在这方面,lexeme的使用似乎是错误的(空格被吃掉了)。如果您想查看转义字符串解析的示例,请参见例如_

  • 在服务器应用程序上实现小型单线DSL(适用于这种风格)
  • 用Boost.Spirit编译一个简单的解析器(用于通过复制进行转义)
  • 用boost精神解析转义字符串
  • 使用boost::spirit解析引用字符串

2023更新

由于www.example.com的链接中断,重新查看了这个答案,在2023年,我会这样写:liveworkspace.org, and in 2023 I'd write this like so:
我认为可以做一个简单的重排,至少看起来像:

  1. template <typename It> struct parser : qi::grammar<It> {
  2. parser() : parser::base_type(value) {
  3. phx::function some_func = [](auto const& s) { //
  4. std::cout << "DEBUG: " << s << "\n";
  5. };
  6. value = qi::raw['"' >> *('\\' >> qi::char_ | ~qi::char_('"')) >> '"'][some_func(qi::_1)];
  7. }
  8. private:
  9. qi::rule<It> value;
  10. };

请注意,我们只是声明了没有skipper的规则,并删除了lexeme(请参阅Boost spirit skipper issues)
Live On Coliru

  1. #include <boost/phoenix.hpp>
  2. #include <boost/range/iterator_range_io.hpp>
  3. #include <boost/spirit/include/qi.hpp>
  4. #include <iomanip>
  5. namespace qi = boost::spirit::qi;
  6. namespace phx = boost::phoenix;
  7. template <typename It> struct parser : qi::grammar<It> {
  8. parser() : parser::base_type(value) {
  9. phx::function some_func = [](auto const& s) { //
  10. std::cout << "DEBUG: " << s << "\n";
  11. };
  12. value = qi::raw['"' >> *('\\' >> qi::char_ | ~qi::char_('"')) >> '"'][some_func(qi::_1)];
  13. }
  14. private:
  15. qi::rule<It> value;
  16. };
  17. bool doParse(std::string const& input) {
  18. typedef std::string::const_iterator It;
  19. auto f(begin(input)), l(end(input));
  20. try
  21. {
  22. parser<It> const p;
  23. bool ok = qi::phrase_parse(f, l, p, qi::space);
  24. if (ok)
  25. std::cout << "parse success\n";
  26. else
  27. std::cerr << "parse failed: " << quoted(std::string(f, l), '\'') << "\n";
  28. if (f!=l) std::cerr << "trailing unparsed: " << quoted(std::string(f,l), '\'') << "\n";
  29. return ok;
  30. } catch (qi::expectation_failure<It> const& e) {
  31. std::string frag(e.first, e.last);
  32. std::cerr << e.what() << quoted(frag, '\'') << "\n";
  33. }
  34. return false;
  35. }
  36. int main() {
  37. return doParse(R"("some \"quoted\" string.")") ? 0 : 255;
  38. }

指纹

  1. DEBUG: "some \"quoted\" string."
  2. parse success
展开查看全部

相关问题