qi :: as_stringを見てください:
デモプログラムの出力:
DEBUG: 'some\\"quoted\\"string.'
parse success
正直なところ、エスケープ文字を使用して「逐語的」文字列を解析しようとしているようです。その点で、使用はlexeme
間違っているようです(スペースが食べられます)。エスケープされた文字列解析のサンプルを確認したい場合は、例を参照してください。
少なくとも次のように見えるかもしれない、私が作ることができると思う単純な再配置。
value = qi::lexeme [
char_('"') >>
qi::as_string [
*(
string("\\\\")
| string("\\\"")
| (graph | ' ') - '"'
)
] [some_func(_1)] >>
char_('"')
];
ただし、スキッパーなしでルールを宣言し、すべてを一緒にドロップできることに注意してください:http lexeme
: //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;
}