我正在尝试使用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?
推荐答案查看 qi :: as_string :
演示程序的输出:
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实施服务器应用程序上的小型单线DSL (用于这种样式)
- 使用Boost.Spirit编译简单的解析器(用于通过复制进行转义)
- 以增强的精神解析转义的字符串
- 使用boost :: spirit 解析引用的字符串>
- 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 放在一起: liveworkspace/code/1oEhei$0
Note however that you could simply declare the rule without a skipper and drop the lexeme alltogether: liveworkspace/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; }更多推荐
增强精神使整个比赛像弦一样
发布评论