提升精神范围字符规则创建空字符
boost spirit wide char rule create null char´s
使用此规则
name_valid %= (lexeme[+(boost::spirit::standard_wide::alpha | lit('_'))]);
类型
typedef qi::rule<Iterator, std::wstring()> name_valid;
在调试模式下运行一切正常。name_valid包含正确的字符串。在VC2017中进入发布模式时,我在此类输入上得到了NUL字符
Input : a_b
Output : a(NULL)b
我发现我必须像这样重写规则。看不到宽字符操作lit
。我在这里错过了什么吗?
name_valid %= +(boost::spirit::standard_wide::alpha | wide::char_(L'_'));
我发现我必须像这样重写规则
好吧,如果目标是将'_'
作为名称的一部分进行匹配,那么无论如何您都需要编写它。因为+(alpha | '_')
公开一个属性,该属性是所有alpha
字符的字符序列,但不公开'_'
因为文本不公开属性。
看不到点亮的宽字符操作。
这就是qi::lit(L'_')
我在这里错过了什么吗
我认为正在发生的事情是alpha|'_'
合成了一个optional<char>
。显然,传播规则非常宽松,optional<char>
可以通过其转换为布尔值操作分配给char
(导致 NUL 字符)。宽字符与它无关:
住在科里鲁
#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 << "Failedn";
}
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>
这突出表明c
公开的char
确实成为 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.
出于好奇:这可以修复它:住在科里鲁
qi::rule<It, std::string()> c = enc::alpha | '.'; qi::rule<It, std::string()> s = +c;
指纹
Parsed: 'AB'
完全符合预期
总结
自动属性传播规则功能强大,但可能令人惊讶。
不要在属性兼容性上玩得又快又松:说出你的意思。就您而言,alpha | char_('_')
从概念上讲是唯一应该做您所期望的事情。
相关文章:
- C++字符*缓冲区的大小
- HEX值到wchar_t字符(UTF-8)的转换
- 为什么 Serial.println(<char[]>);返回随机字符?
- 我的字符计数代码计算错误.为什么
- 字符串-C++后显示的随机字符
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 如何在C++中从字符串中分割字符
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 此代码是否违反一个定义规则
- 指向指向字符数组的指针数组的指针
- 如何用转义符替换字符串中的所有特殊字符
- Flex 词法分析器规则,对包含连字符和斜杠的字母数字字符串具有积极的前瞻断言
- C++20 中的严格别名规则是否允许标准 c++ unicode 字符和下划线类型之间"reinterpret
- 提升精神范围字符规则创建空字符
- 将字符阵列施放到另一种类型中是否违反了严格的确定规则
- 再次:严格的混叠规则和字符*
- 为什么提升区域设置不提供字符级别规则类型?
- Boyer-Moore-坏字符规则实现子字符串搜索
- 字符*转换和混叠规则
- 使用stack,编写一个程序,该程序使用以下规则确定字符模式是否有效:a ^N B^N