このような目的でboost::spirit::qiを使用する方法の小さな例を次に示します。
Boostは確かにサードパーティのライブラリであることに注意してください!
JSONファイルを受け取り、次の内容でjson-example.txtに保存したと仮定します。
{{
"結果": "1"、
"gs": "0"、
"ga": "0"、
"la": "0"、
"lb": "0"、
"lc": "0"、
"ld": "0"、
"ex": "0"、
"gd": "0"
}
ここで、 key:file方式ですべてのアイテムを受け取りたいと仮定します。これを行う方法は次のとおりです。
#include <vector>
#include <string>
#include <fstream>
#include <map>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
namespace qi = boost::spirit::qi;
template<typename Iterator>
struct jsonparser : qi::grammar<Iterator, std::map<std::string, int>()>
{
jsonparser() : jsonparser::base_type(query, "JSON-parser")
{
using qi::char_;
using qi::int_;
using qi::blank;
using qi::eol;
using qi::omit;
query = omit[-(char_('{') >> eol)] >> pair % (eol | (',' >> eol)) >> '}';
pair = key >> -(':' >> value);
key = omit[*blank] >> '"' >> char_("a-zA-Z_") >> *char_("a-zA-Z_0-9") >> '"';
value = '"' >> int_ >> '"';
};
qi::rule<Iterator, std::map<std::string, int>()> query;
qi::rule<Iterator, std::pair<std::string, int>()> pair;
qi::rule<Iterator, std::string()> key;
qi::rule<Iterator, int()> value;
};
void main(int argc, char** argv)
{
// Copy json-example.txt right in the std::string
std::string jsonstr
(
(
std::istreambuf_iterator<char>
(
*(std::auto_ptr<std::ifstream>(new std::ifstream("json-example.txt"))).get()
)
),
std::istreambuf_iterator<char>()
);
typedef std::string::iterator StrIterator;
StrIterator iter_beg = jsonstr.begin();
StrIterator iter_end = jsonstr.end();
jsonparser<StrIterator> grammar;
std::map<std::string,int> output;
// Parse the given json file
qi::parse(iter_beg, iter_end, grammatic, output);
// Output the result
std::for_each(output.begin(), output.end(),
[](const std::pair<std::string, int> &item) -> void
{
std::cout << item.first << ":" << item.second << std::endl;
});
}
出力:
結果:1
gs:0
ga:0
la:0
lb:0
lc:0
ld:0
ex:0
gd:0