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

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

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

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

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

izj3ouym

izj3ouym1#

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

DEBUG: 'some\\"quoted\\"string.'
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:
我认为可以做一个简单的重排,至少看起来像:

template <typename It> struct parser : qi::grammar<It> {
    parser() : parser::base_type(value) {
        phx::function some_func = [](auto const& s) { //
            std::cout << "DEBUG: " << s << "\n";
        };

        value = qi::raw['"' >> *('\\' >> qi::char_ | ~qi::char_('"')) >> '"'][some_func(qi::_1)];
    }
  private:
    qi::rule<It> value;
};

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

#include <boost/phoenix.hpp>
#include <boost/range/iterator_range_io.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iomanip>

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

template <typename It> struct parser : qi::grammar<It> {
    parser() : parser::base_type(value) {
        phx::function some_func = [](auto const& s) { //
            std::cout << "DEBUG: " << s << "\n";
        };

        value = qi::raw['"' >> *('\\' >> qi::char_ | ~qi::char_('"')) >> '"'][some_func(qi::_1)];
    }
  private:
    qi::rule<It> value;
};

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

    try
    {
        parser<It> const p;

        bool ok = qi::phrase_parse(f, l, p, qi::space);
        if (ok)
            std::cout << "parse success\n";
        else
            std::cerr << "parse failed: " << quoted(std::string(f, l), '\'') << "\n";

        if (f!=l) std::cerr << "trailing unparsed: " << quoted(std::string(f,l), '\'') << "\n";
        return ok;
    } catch (qi::expectation_failure<It> const& e) {
        std::string frag(e.first, e.last);
        std::cerr << e.what() << quoted(frag, '\'') << "\n";
    }

    return false;
}

int main() {
    return doParse(R"("some \"quoted\" string.")") ? 0 : 255;
}

指纹

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

相关问题