Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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++ Boost跳过解析器是正确的方法吗?_C++_Parsing_Boost - Fatal编程技术网

C++ Boost跳过解析器是正确的方法吗?

C++ Boost跳过解析器是正确的方法吗?,c++,parsing,boost,C++,Parsing,Boost,经过一些延迟之后,我现在再次尝试解析一些ASCII文本文件 被一些二进制字符包围 然而,我现在很难确定跳过解析器是否是正确的方法 该文件(它是一个JEDEC文件)的语法非常简单: 文件中的每个数据字段以单个字母开头,以星号结尾。数据字段可以包含空格和回车符。 星号后面的空格和回车符也可能在 下一个字段标识符 这就是我用来为这样一个文件构建解析器的方法: phrase_parse(first, last, // First char in File

经过一些延迟之后,我现在再次尝试解析一些ASCII文本文件 被一些二进制字符包围

然而,我现在很难确定跳过解析器是否是正确的方法

该文件(它是一个JEDEC文件)的语法非常简单:


文件中的每个数据字段以单个字母开头,以星号结尾。数据字段可以包含空格和回车符。 星号后面的空格和回车符也可能在 下一个字段标识符

这就是我用来为这样一个文件构建解析器的方法:

phrase_parse(first, last, 
             // First char in File
             char_('\x02') >>

             // Data field
             *((print[cout << _1] | graph[cout << _1]) - char_('*')) >>

             // End of data followed by 4 digit hexnumber. How to limit?
             char_('\x03') >> *xdigit,

             // Skip asterisks
             char_('*') );

我建议您只在顶级规则中使用skipper。并使用它跳过不重要的空白

您不需要为星号使用跳过符,因为您不想忽略星号。如果他们被忽视,你的规则就不能执行

此外,内部规则不应使用空格跳跃器,原因很简单,即空格和换行符在JEDEC中是有效的字段数据

因此,所有这些的结果将是:

value = *(ascii::char_("\x20-\x7e\r\n") - '*') >> '*';
field = ascii::graph >> value;
start = STX >> value >> *field >> ETX >> xmit_checksum; 
如果将与各船长一起宣布规则:

qi::uint_parser<uint16_t, 16, 4, 4>           xmit_checksum;
qi::rule<It, ascii::space_type> start;
qi::rule<It>             field, value; // no skippers - they are lexemes
外卖:每年看两次牙医


“数据字段可以包含空格和回车符”。好。告诉我们这是重要的还是应该跳过。来吧,你是要我们告诉你跳绳是不是个好主意。你应该知道你想要实现什么…好的。我想跳过星号,所以我想这是正确的方法。但是考虑到我的方法没有输出任何东西,如果有更好的方法来解决这个问题,我是不安全的?你没有描述“问题”。甚至是“目标”。而且,你不想跳过星号(它是重要的结构信息)。跳绳!=不捕获你应该给出输入的样本,以及目标/预期输出。你还应该发布你的
打印
图形
规则。哇!首先:非常感谢。我对你的帮助之大感到非常惊讶。这一条对我很有帮助,因为你的解释很有根据。现在,我将更深入地研究它,并希望通过这个示例更好地了解boost解析器框架的一般用法。改进了输出以更好地匹配预期的输出
value = *(ascii::char_("\x20-\x7e\r\n") - '*') >> '*';
field = ascii::graph >> value;
start = STX >> value >> *field >> ETX >> xmit_checksum; 
qi::uint_parser<uint16_t, 16, 4, 4>           xmit_checksum;
qi::rule<It, ascii::space_type> start;
qi::rule<It>             field, value; // no skippers - they are lexemes
struct JEDEC {
    std::string caption;
    struct field { 
        char id;
        std::string value;
    };
    std::vector<field> fields;
    uint16_t checksum;
};
qi::rule<It, ast::JEDEC(), ascii::space_type> start;
qi::rule<It, ast::JEDEC::field()>             field;
qi::rule<It, std::string()>                   value;
qi::uint_parser<uint16_t, 16, 4, 4>           xmit_checksum;
inline static std::ostream& operator<<(std::ostream& os, JEDEC const& jedec) {
    os << "Start: " << jedec.caption << "\n";
    for(auto& f : jedec.fields)
        os << f.id << ": " << f.value << "\n";

    auto saved = os.rdstate();
    os << "End: " << std::hex << std::setw(4) << std::setfill('0') << jedec.checksum;
    os.setstate(saved);

    return os;
}
//#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iomanip>

namespace qi = boost::spirit::qi;
namespace ascii = qi::ascii;

namespace ast {
    struct JEDEC {
        std::string caption;
        struct field { 
            char id;
            std::string value;
        };
        std::vector<field> fields;
        uint16_t checksum;
    };

    inline static std::ostream& operator<<(std::ostream& os, JEDEC const& jedec) {
        os << "Start: " << jedec.caption << "\n";
        for(auto& f : jedec.fields)
            os << f.id << ": " << f.value << "\n";

        auto saved = os.rdstate();
        os << "End: " << std::hex << std::setw(4) << std::setfill('0') << std::uppercase << jedec.checksum;
        os.setstate(saved);

        return os;
    }
}

BOOST_FUSION_ADAPT_STRUCT(ast::JEDEC::field,
        (char, id)(std::string, value))
BOOST_FUSION_ADAPT_STRUCT(ast::JEDEC,
        (std::string, caption)
        (std::vector<ast::JEDEC::field>, fields)
        (uint16_t, checksum))

template <typename It> 
struct JedecGrammar : qi::grammar<It, ast::JEDEC(), ascii::space_type>
{
    JedecGrammar() : JedecGrammar::base_type(start) {
        const char STX = '\x02';
        const char ETX = '\x03';

        value = *(ascii::char_("\x20-\x7e\r\n") - '*') >> '*';
        field = ascii::graph >> value;
        start = STX >> value >> *field >> ETX >> xmit_checksum; 

        BOOST_SPIRIT_DEBUG_NODES((start)(field)(value))
    }
  private:
    qi::rule<It, ast::JEDEC(), ascii::space_type> start;
    qi::rule<It, ast::JEDEC::field()>             field;
    qi::rule<It, std::string()>                   value;
    qi::uint_parser<uint16_t, 16, 4, 4>           xmit_checksum;
};

int main() {
    typedef boost::spirit::istream_iterator It;
    It first(std::cin>>std::noskipws), last;

    JedecGrammar<It> g;

    ast::JEDEC jedec;
    bool ok = phrase_parse(first, last, g, ascii::space, jedec);

    if (ok)
    {
        std::cout << "Parse success\n";
        std::cout << jedec;
    }
    else
        std::cout << "Parse failed\n";

    if (first != last)
        std::cout << "Remaining input unparsed: '" << std::string(first, last) << "'\n";
}
Start: JEDEC file generated by John Doe
D: M SIGNETICS(PHILIPS)
D: D GAL16R8
Q: P20
Q: V0
G: 0
F: 0
L: 00000 1110101111100110111101101110111100111111
C: DEAD
End: BEEF