【发布时间】:2015-11-24 06:15:33
【问题描述】:
我在玩Boost.Spirit。作为一项更大工作的一部分,我正在尝试构建一个用于解析 C/C++ 样式字符串文字的语法。我遇到了一个问题:
我如何创建一个子语法,追加一个std::string()结果到调用语法的std::string()属性(而不仅仅是一个char?
这是我的代码,目前正在运行。 (其实我已经得到了更多的东西,包括'\n' 之类的东西,但我把它精简到了要领。)
#define BOOST_SPIRIT_UNICODE
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
using namespace boost;
using namespace boost::spirit;
using namespace boost::spirit::qi;
template < typename Iterator >
struct EscapedUnicode : grammar< Iterator, char() > // <-- should be std::string
{
EscapedUnicode() : EscapedUnicode::base_type( escaped_unicode )
{
escaped_unicode %= "\\" > ( ( "u" >> uint_parser< char, 16, 4, 4 >() )
| ( "U" >> uint_parser< char, 16, 8, 8 >() ) );
}
rule< Iterator, char() > escaped_unicode; // <-- should be std::string
};
template < typename Iterator >
struct QuotedString : grammar< Iterator, std::string() >
{
QuotedString() : QuotedString::base_type( quoted_string )
{
quoted_string %= '"' >> *( escaped_unicode | ( char_ - ( '"' | eol ) ) ) >> '"';
}
EscapedUnicode< Iterator > escaped_unicode;
rule< Iterator, std::string() > quoted_string;
};
int main()
{
std::string input = "\"foo\u0041\"";
typedef std::string::const_iterator iterator_type;
QuotedString< iterator_type > qs;
std::string result;
bool r = parse( input.cbegin(), input.cend(), qs, result );
std::cout << result << std::endl;
}
这将打印fooA——QuotedString 语法调用EscapedUnicode 语法,这导致char 被添加到QuotedString 的std::string 属性(A、0x41 )。
但我当然需要为 0x7f 以外的任何内容生成一个 sequence 字符(字节)。 EscapedUnicode 需要生成一个std::string,它必须附加到QuotedString 生成的字符串中。
这就是我遇到障碍的地方。我不明白 Boost.Spirit 与 Boost.Phoenix 协同工作时所做的事情,并且我所做的任何尝试都会导致冗长且几乎无法解读的与模板相关的编译器错误。
那么,我该怎么做呢?答案实际上不需要进行正确的 Unicode 转换;这是std::string 的问题,我需要一个解决方案。
【问题讨论】:
-
“但我当然需要为 0x7f 以外的任何内容生成一个字符序列(字节)。” - 你想要什么编码?
-
就像评论一样:一般来说,当您有诸如“为什么不使用我的序列附加/连接/做我想做的事情”之类的问题时,请查看备忘单:boost.org/doc/libs/1_58_0/libs/spirit/doc/html/spirit/qi/…
标签: c++11 boost boost-spirit boost-spirit-qi