TinyJSONを改造してみた

ousttrue2009-01-13

{
  // comment
  key: 99,
  HOGE: /* comment */ "FUGA"
}

というような2種類のコメントとクォートされていないkeyを許すように緩めた。
JSONの純粋性は損なわれたが実用性重視で。

以下改造

diff --git a/include/tinyjson/tinyjson.hpp b/include/tinyjson/tinyjson.hpp
index 9cdb4c3..e11c44e 100755
--- a/include/tinyjson/tinyjson.hpp
+++ b/include/tinyjson/tinyjson.hpp
@@ -28,6 +28,7 @@
 #include	<boost/shared_ptr.hpp>
 #include	<boost/any.hpp>
 #include	<boost/spirit/core.hpp>
+#include	<boost/spirit/utility.hpp>
 #include	<boost/spirit/utility/loops.hpp>
 #include	<boost/lexical_cast.hpp>
 
@@ -205,6 +206,20 @@ namespace json
 			}
 		};
 
+		// ---[ SEMANTIC ACTION: PUSH A UNQUOTED STRING ON THE STACK (ONLY ASCII WORD) ]-------------------------------
+		struct push_key
+		{
+			stack & m_stack;
+			push_key(stack & stack) : m_stack(stack) { }
+
+			template <typename Iterator>
+				void operator() (Iterator szStart, Iterator szEnd) const
+				{
+					m_stack.push(variant(new boost::any(
+									std::basic_string< typename Iterator::value_type >(szStart, szEnd)
+									)));
+				}
+		};
 
 		// ---[ SEMANTIC ACTION: PUSH A REAL ON THE STACK ]-------------------------------------------------------
 
@@ -443,6 +458,8 @@ namespace json
 			boost::spirit::rule< SCANNER > m_number;
 			boost::spirit::rule< SCANNER > m_boolean;
 			boost::spirit::rule< SCANNER > m_null;
+			// unquoted string
+			boost::spirit::rule< SCANNER > m_key;
 
 		public:
 
@@ -471,7 +488,7 @@ namespace json
 				// 3: a pair is given by a name and a value...
 
 				m_pair
-					= ( m_string >> ch_p(':') >> m_value )
+					= ( (m_key | m_string) >> ch_p(':') >> m_value )
 					  [ create_pair(self.m_stack) ]
 					;
 
@@ -510,6 +527,9 @@ namespace json
 						]
 					;
 
+				// 5': unquoted string as key of pair.(only ascii word start with alphabet)
+				m_key=(alpha_p >> *alnum_p)[ push_key(self.m_stack) ];
+
 				// 6: a number is very much like a C or java number...
 
 				m_number
@@ -549,7 +569,8 @@ namespace json
 		json::grammar< typename Iterator::value_type >::stack st;
 		json::grammar< typename Iterator::value_type > gr(st);
 
-		boost::spirit::parse_info<Iterator> pi = boost::spirit::parse(szFirst, szEnd, gr, boost::spirit::space_p);
+		boost::spirit::parse_info<Iterator> pi = boost::spirit::parse(szFirst, szEnd, gr, 
+				boost::spirit::space_p | boost::spirit::comment_p("//") | boost::spirit::comment_p("/*", "*/"));
 
 		// 2: skip any spaces at the end of the parsed section...