Skip to content

Instantly share code, notes, and snippets.

@legnaleurc
Created July 2, 2012 04:24
Show Gist options
  • Save legnaleurc/3031094 to your computer and use it in GitHub Desktop.
Save legnaleurc/3031094 to your computer and use it in GitHub Desktop.
JSON parser with Boost Spirit
#include <boost/any.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <vector>
#include <map>
#include <iostream>
namespace json {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct nullptr_t_ : qi::symbols< char, void * > {
nullptr_t_() {
add( "null", nullptr );
}
} nullptr_;
template< typename Iterator >
struct Grammar : qi::grammar< Iterator, boost::any(), ascii::space_type > {
Grammar(): Grammar::base_type( start ) {
using qi::lexeme;
using qi::double_;
using qi::bool_;
using ascii::char_;
start = value_rule.alias();
object_rule = '{' >> pair_rule % ',' >> '}';
pair_rule = string_rule >> ':' >> value_rule;
value_rule = object_rule | array_rule | string_rule | nullptr_ | double_ | bool_;
array_rule = '[' >> value_rule % ',' >> ']';
string_rule = lexeme[ '\"' >> *( char_ - '\"' ) >> '\"' ];
}
qi::rule< Iterator, boost::any(), ascii::space_type > start;
qi::rule< Iterator, std::map< std::string, boost::any >(), ascii::space_type > object_rule;
qi::rule< Iterator, std::pair< std::string, boost::any >(), ascii::space_type > pair_rule;
qi::rule< Iterator, boost::any(), ascii::space_type > value_rule;
qi::rule< Iterator, std::vector< boost::any >(), ascii::space_type > array_rule;
qi::rule< Iterator, std::string(), ascii::space_type > string_rule;
};
}
int main() {
const std::string source = "[ null ]";
json::Grammar< std::string::const_iterator > g;
boost::any v;
auto bit = source.begin();
auto eit = source.end();
bool r = boost::spirit::qi::phrase_parse( bit, eit, g, boost::spirit::ascii::space, v );
if( r ) {
auto a = boost::any_cast< std::vector< boost::any > >( v );
for( auto it = a.begin(); it != a.end(); ++it ) {
std::cout << boost::any_cast< void * >( *it ) << std::endl;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment