25 #ifndef WSTRUCTUREDTEXTPARSER_H
26 #define WSTRUCTUREDTEXTPARSER_H
35 #include <boost/config/warning_disable.hpp>
36 #include <boost/spirit/include/qi.hpp>
37 #include <boost/spirit/include/phoenix_core.hpp>
38 #include <boost/spirit/include/phoenix_operator.hpp>
39 #include <boost/spirit/include/phoenix_fusion.hpp>
40 #include <boost/spirit/include/phoenix_stl.hpp>
41 #include <boost/spirit/include/phoenix_object.hpp>
42 #include <boost/fusion/include/adapt_struct.hpp>
43 #include <boost/variant/recursive_variant.hpp>
44 #include <boost/fusion/include/io.hpp>
45 #include <boost/filesystem/path.hpp>
47 #include "WStringUtils.h"
48 #include "exceptions/WTypeMismatch.h"
49 #include "exceptions/WNotFound.h"
55 namespace WStructuredTextParser
58 namespace qi = boost::spirit::qi;
61 namespace fusion = boost::fusion;
64 namespace ascii = boost::spirit::ascii;
67 namespace phoenix = boost::phoenix;
70 namespace spirit = boost::spirit;
112 boost::recursive_wrapper< ObjectType >,
146 BOOST_FUSION_ADAPT_STRUCT(
148 ( std::string, m_name )
149 ( std::vector< WStructuredTextParser::MemberType >, m_nodes )
155 BOOST_FUSION_ADAPT_STRUCT(
156 WStructuredTextParser::KeyValueType,
157 ( std::
string, m_name )
158 ( std::
string, m_value )
162 namespace WStructuredTextParser
178 template <
typename Iterator>
179 struct Grammar: qi::grammar<Iterator, FileType(), ascii::space_type >
186 explicit Grammar( std::ostream& error ):
Grammar::base_type( file,
"WStructuredTextParser::Grammar" )
189 key %= qi::char_(
"a-zA-Z_" ) >> *qi::char_(
"a-zA-Z_0-9" );
191 value %=
'"' >> *( ~qi::char_(
"\"" ) | qi::char_(
" " ) ) >>
'"';
194 kvpair %= key >>
'=' >> value >>
';';
196 comment %= qi::lexeme[ qi::char_(
"/" ) >> qi::char_(
"/" ) >> *qi::char_(
"a-zA-Z_0-9!\"#$%&'()*,:;<>?@\\^`{|}~/ .@=[]ยง!+-" ) ];
198 object %= ( key | value ) >>
'{' >> *(
object | kvpair | comment ) >>
'}' >> *qi::char_(
";" );
200 file %= *(
object | kvpair | comment );
203 object.name(
"object" );
204 kvpair.name(
"key-value pair" );
206 value.name(
"value" );
208 comment.name(
"comment" );
212 qi::on_error< qi::fail >( object, error << phoenix::val(
"Error: " ) << qi::_4 );
213 qi::on_error< qi::fail >( kvpair, error << phoenix::val(
"Error: " ) << qi::_4 );
214 qi::on_error< qi::fail >( key, error << phoenix::val(
"Error: " ) << qi::_4 );
215 qi::on_error< qi::fail >( value, error << phoenix::val(
"Error: " ) << qi::_4 );
216 qi::on_error< qi::fail >( comment, error << phoenix::val(
"Error: " ) << qi::_4 );
217 qi::on_error< qi::fail >( file, error << phoenix::val(
"Error: " ) << qi::_4 );
225 qi::rule< Iterator, ObjectType(), ascii::space_type >
object;
230 qi::rule< Iterator, FileType(), ascii::space_type >
file;
235 qi::rule< Iterator, CommentType(), ascii::space_type >
comment;
240 qi::rule< Iterator, KeyValueType(), ascii::space_type >
kvpair;
245 qi::rule< Iterator, KeyType() >
key;
250 qi::rule< Iterator, ValueType() >
value;
316 bool exists( std::string key,
bool valuesOnly =
false )
const;
326 size_t count( std::string key,
bool valuesOnly =
false )
const;
341 template<
typename T >
342 T getValue( std::string key,
const T& defaultValue )
const;
357 template<
typename T >
358 std::vector< T > getValues( std::string key,
const std::vector< T >& defaults )
const;
372 template<
typename T >
373 std::vector< T > getValues( std::string key )
const;
386 template<
typename T >
387 T operator[]( std::string key )
const;
409 std::vector< StructuredValueTree > getSubTrees( std::string key )
const;
428 void traverse(
MemberType current, std::vector< std::string >::const_iterator keyIter,
429 std::vector< std::string >::const_iterator keyEnd,
430 std::vector< ObjectType >& resultObjects,
431 std::vector< KeyValueType >& resultValues )
const;
442 void traverse(
FileType current, std::string key,
443 std::vector< ObjectType >& resultObjects,
444 std::vector< KeyValueType >& resultValues )
const;
470 template<
typename T >
471 T StructuredValueTree::getValue( std::string key,
const T& defaultValue )
const
474 return *getValues< T >( key, std::vector< T >( 1, defaultValue ) ).begin();
477 template<
typename T >
478 std::vector< T > StructuredValueTree::getValues( std::string key,
const std::vector< T >& defaults )
const
480 std::vector< T > r = getValues< T >( key );
491 template<
typename T >
492 T StructuredValueTree::operator[]( std::string key )
const
494 std::vector< T > r = getValues< T >( key );
501 throw WNotFound(
"The key \"" + key +
"\" was not found." );
516 bool operator()(
const KeyValueType& )
const
527 template<
typename T >
528 bool operator()(
const T& )
const
556 template<
typename T >
557 bool operator()(
const T& )
const
587 template<
typename T >
588 std::string operator()(
const T& element )
const
590 return element.m_name;
594 template<
typename T >
595 std::vector< T > StructuredValueTree::getValues( std::string key )
const
598 std::vector< ObjectType > rObj;
599 std::vector< KeyValueType > rKV;
602 traverse( m_file, key, rObj, rKV );
606 for( std::vector< KeyValueType >::const_iterator i = rKV.begin(); i != rKV.end(); ++i )
610 r.push_back( string_utils::fromString< T >( ( *i ).m_value ) );
615 throw WTypeMismatch(
"Cannot convert element \"" + key +
"\" to desired type." );
624 #endif // WSTRUCTUREDTEXTPARSER_H