使用此规则
name_valid %= (lexeme[+(boost::spirit::standard_wide::alpha | lit('_'))]);
类型
typedef qi::rule<Iterator, std::wstring()> name_valid;
在调试模式下运行一切正常。 name_valid 包含正确的字符串。在VC2017中进入发布模式时,我在这些输入上获得了NUL char
Input : a_b
Output : a(NULL)b
我发现我必须像这样重写规则。无法将lit
视为宽字符操作。我在这里想念一下吗?
name_valid %= +(boost::spirit::standard_wide::alpha | wide::char_(L'_'));
答案 0 :(得分:2)
我发现我必须像这样重写规则
好吧,如果目标是将'_'
作为名称的一部分进行匹配,那么无论如何你都需要写出来。因为+(alpha | '_')
公开了一个属性,该属性是所有alpha
个字符的字符序列,而不是'_'
,因为文字不会公开属性。
看不到点亮为宽焦操作。
那是qi::lit(L'_')
我是否想念这里的东西
我认为正在发生的事情是alpha|'_'
合成optional<char>
。显然,传播规则非常宽松,optional<char>
可以通过转换为bool操作分配给char
(导致NUL特征)。宽字符与它无关:
<强> Mongoose aggregate 强>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace enc = boost::spirit::standard;
int main() {
std::string const input = "A.B";
auto f = input.begin(), l = input.end();
std::string output;
if (qi::parse(f, l, +(enc::alpha | '.'), output)) {
std::cout << "Parsed: '" << output << "'\n";
} else {
std::cout << "Failed\n";
}
if (f!=l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
打印
00000000: 5061 7273 6564 3a20 2741 0042 270a Parsed: 'A.B'.
在单独的规则中将其拆分可见: Live On Coliru
qi::rule<It, char()> c = enc::alpha | '.';
qi::rule<It, std::string()> s = +c;
BOOST_SPIRIT_DEBUG_NODES((s)(c))
打印
<s>
<try>A.B</try>
<c>
<try>A.B</try>
<success>.B</success>
<attributes>[A]</attributes>
</c>
<c>
<try>.B</try>
<success>B</success>
<attributes>[NUL]</attributes>
</c>
<c>
<try>B</try>
<success></success>
<attributes>[B]</attributes>
</c>
<c>
<try></try>
<fail/>
</c>
<success></success>
<attributes>[[A, NUL, B]]</attributes>
</s>
这突出显示char
公开的c
确实成为NUL字符。但是,以下内容清楚表明并非完全故意: Live On Coliru
qi::rule<It, boost::optional<char>()> c = enc::alpha | '.';
qi::rule<It, std::string()> s = +c;
BOOST_SPIRIT_DEBUG_NODES((s)(c))
将以断言中止:
sotest: /home/sehe/custom/boost_1_65_0/boost/optional/optional.hpp:1106: boost::optional::reference_const_type boost::optional<char>::get() const [T = char]: Assertion `this->is_initialized()' failed.
出于好奇:这解决了这个问题: Live On Coliru
qi::rule<It, std::string()> c = enc::alpha | '.'; qi::rule<It, std::string()> s = +c;
打印
Parsed: 'AB'
完全符合预期
自动属性传播规则功能强大,但可能会令人惊讶。
不要使用属性兼容性来快速松散地玩:说出你的意思。在你的情况下,alpha | char_('_')
在概念上是唯一应该按照你的期望做的事情。