Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Spirit X3,如何在非ascii输入上解析失败?_C++_Boost Spirit_Boost Spirit X3 - Fatal编程技术网

C++ Spirit X3,如何在非ascii输入上解析失败?

C++ Spirit X3,如何在非ascii输入上解析失败?,c++,boost-spirit,boost-spirit-x3,C++,Boost Spirit,Boost Spirit X3,因此,目标是不允许输入字符串中出现80h到FFh之间的字符。我的印象是 使用ascii::char; 我会处理好的。但正如您在示例代码中看到的,它将很高兴地打印解析成功 在下面的Spirit邮件列表帖子中,Joel建议让这些非ascii字符的解析失败。但我不确定他是否继续这样做。 下面是我的示例代码: #包括 #包括 命名空间客户端::解析器 { 名称空间x3=boost::spirit::x3; 名称空间ascii=boost::spirit::x3::ascii; 使用ascii::ch

因此,目标是不允许输入字符串中出现80h到FFh之间的字符。我的印象是

使用ascii::char;
我会处理好的。但正如您在示例代码中看到的,它将很高兴地打印解析成功

在下面的Spirit邮件列表帖子中,Joel建议让这些非ascii字符的解析失败。但我不确定他是否继续这样做。

下面是我的示例代码:

#包括
#包括
命名空间客户端::解析器
{
名称空间x3=boost::spirit::x3;
名称空间ascii=boost::spirit::x3::ascii;
使用ascii::char;
使用ascii::space;
使用x3::词素;
使用x3::skip;
const auto-quoted_string=lexeme[char_(“”)>>*(char_-“)>>char_(“”)];
const auto entry_point=跳过(空格)[带引号的字符串];
}
int main()
{
for(std::string const输入:{“\”顽皮\x80“bla bla bla\”){
std::字符串输出;
if(解析(input.begin()、input.end()、client::parser::entry\u point、output)){

std::cout您可以通过使用
print
解析器来实现:

#include <iostream>
#include <boost/spirit/home/x3.hpp>

namespace client::parser
{
    namespace x3 = boost::spirit::x3;
    namespace ascii = boost::spirit::x3::ascii;

    using ascii::char_;
    using ascii::print;
    using ascii::space;
    using x3::lexeme;
    using x3::skip;

    const auto quoted_string = lexeme[char_('"') >> *(print - '"') >> char_('"')];
    const auto entry_point = skip(space) [ quoted_string ];
}

int main()
{
    for(std::string const input : { "\"naughty \x80\"", "\"bla bla bla\"" }) {
        std::string output;
        std::cout << "input:  " << input << "\n";
        if (parse(input.begin(), input.end(), client::parser::entry_point, output)) {
            std::cout << "output: " << output << "\n";
            std::cout << "Parsing succeeded\n";
        } else {
            std::cout << "Parsing failed\n";
        }
    }
}


令人惊讶的是,出于某种原因,只有当
sizeof(迭代器字符类型)>sizeof(字符)
时,才会检查
char\uuuuu


这里的文档没什么不好的。它只是一个库错误

其中
任意字符的代码表示:

template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
    return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_));
}
模板
布尔测试(字符、上下文常量和)常量
{

return((sizeof(Char))可以帮助您理解
Char(charset)
变体是如何工作的。这是一个bug。我将其归档。使用
print
并不能真正解决它。测试代码至少应该读取
(print | space)-“
,以匹配用例。(Nitpick,通过拆分它们修改了测试用例。我最初的想法是一样的,但是字符串文本被拆分的唯一原因是因为<代码> \\x80b在C++中作为无效的char逃逸解析)。谢谢!这两种输入字符串都是这样的,因为我遵循了这里的建议:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
#include <boost/core/demangle.hpp>
#include <typeinfo>

namespace x3 = boost::spirit::x3;

template <typename Char>
void test(Char const* str)
{
    std::basic_string<Char> s = str;
    std::cout << boost::core::demangle(typeid(Char).name()) << ":\t";
    Char c;
    auto it = s.begin();
    if (x3::parse(it, s.end(), x3::ascii::char_, c) && it == s.end())
        std::cout << "OK: " << int(c) << "\n";
    else
        std::cout << "Failed\n";
}

int main()
{
    test("\x80");
    test(L"\x80");
    test(u8"\x80");
    test(u"\x80");
    test(U"\x80");
}
char:   OK: -128
wchar_t:    Failed
char8_t:    OK: 128
char16_t:   Failed
char32_t:   Failed
template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
    return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_));
}
template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
    return ((sizeof(Char) <= sizeof(char_type)) && encoding::ischar(ch_));
}
#include <boost/spirit/include/qi.hpp>

int main() {
    namespace qi = boost::spirit::qi;

    char const* input = "\x80";
    assert(!qi::parse(input, input+1, qi::ascii::char_));
}