【问题标题】:Parsing comma separated grammars when unordered无序时解析逗号分隔的语法
【发布时间】:2015-02-10 21:29:40
【问题描述】:

previous post 我找到了一种使用 boost::spirit 解析这种类型的结构的方法:

"parameter" : {
  "name"        : "MyName"       , 
  "type"        : "MyType"       , 
  "unit"        : "MyUnit"       , 
  "cardinality" : "MyCardinality", 
  "value"       : "MyValue"       
}

这是一个带有键值对的简单 JSON。现在我想解析这个结构,而不考虑变量顺序。 IE。我也想将这个结构解析成同一个对象:

"parameter" : {
  "type"        : "MyType"       ,
  "value"       : "MyValue"      ,
  "unit"        : "MyUnit"       , 
  "cardinality" : "MyCardinality",
  "name"        : "MyName"
}

我知道我可以使用^ 运算符以任何顺序解析数据,但我不知道如何处理行尾的逗号,但最后。如何解析这两种结构?

这是上一篇文章中的@sehe 代码。语法在这里定义。

#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

// This is pasted and copied from another header file

namespace StateMachine {
namespace Private {

    struct LuaParameterData {
        std::wstring name;
        std::wstring type;
        std::wstring unit;
        std::wstring cardinality;
        std::wstring value;
    };

} // namespace Private
} // namespace StateMachine

BOOST_FUSION_ADAPT_STRUCT(
  StateMachine::Private::LuaParameterData,
  (std::wstring, name)
  (std::wstring, type)
  (std::wstring, unit)
  (std::wstring, cardinality)
  (std::wstring, value)
)

namespace qi = boost::spirit::qi;

// From here original file continues
namespace StateMachine {
namespace Private {

    template<typename Iterator>
    struct LuaParameterDataParser : qi::grammar<Iterator, LuaParameterData(), qi::ascii::space_type>
    {
        LuaParameterDataParser() : LuaParameterDataParser::base_type(start)
        {
            quotedString = qi::lexeme['"' >> +(qi::ascii::char_ - '"') >> '"'];

            start =
                qi::lit("\"parameter\"")
                >> ':'
                >> '{'
                >> qi::lit("\"name\""       ) >> ':' >> quotedString >> ','
                >> qi::lit("\"type\""       ) >> ':' >> quotedString >> ','
                >> qi::lit("\"unit\""       ) >> ':' >> quotedString >> ','
                >> qi::lit("\"cardinality\"") >> ':' >> quotedString >> ','
                >> qi::lit("\"value\""      ) >> ':' >> quotedString
                >> '}'
                ;

            BOOST_SPIRIT_DEBUG_NODES((start)(quotedString));
        }

        qi::rule<Iterator, std::string(), qi::ascii::space_type> quotedString;
        qi::rule<Iterator, LuaParameterData(), qi::ascii::space_type> start;
    };

} // namespace Private
} // namespace StateMachine

int main() {
    using It = std::string::const_iterator;

    std::string const input = R"(
        "parameter" : {
            "name"        : "name"       , 
            "type"        : "type"       , 
            "unit"        : "unit"       , 
            "cardinality" : "cardinality", 
            "value"       : "value"       
        }
    )";
    It f = input.begin(), 
       l = input.end();

    StateMachine::Private::LuaParameterDataParser<It> p;
    StateMachine::Private::LuaParameterData data;
    bool ok = qi::phrase_parse(f, l, p, qi::ascii::space, data);

    if (ok) {
        std::wcout << L"Parsed: \n";
        std::wcout << L"\tname: " << data.name << L'\n';
        std::wcout << L"\ttype: " << data.type << L'\n';
        std::wcout << L"\tunit: " << data.unit << L'\n';
        std::wcout << L"\tcardinality: " << data.cardinality << L'\n';
        std::wcout << L"\tvalue: " << data.value << L'\n';
    } else {
        std::wcout << L"Parse failure\n";
    }

    if (f!=l)
        std::wcout << L"Remaining unparsed: '" << std::wstring(f,l) << L"'\n";
}

【问题讨论】:

  • 我对该代码不承担任何责任 :)
  • 只指定谁懂精神,谁不知道.....

标签: c++ parsing boost boost-spirit boost-spirit-qi


【解决方案1】:

我将参考一组最近的答案,这些答案我已经非常广泛地讨论过:

切线相关:

【讨论】:

  • 我会照常检查。感谢您的支持。
  • 我正在使用“带有 C++ 和 BOOST 的 JSON 文件”中的示例,它似乎有效。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 2019-08-19
  • 2011-02-20
  • 1970-01-01
相关资源
最近更新 更多