25 #ifndef WSTRUCTUREDTEXTPARSER_H
26 #define WSTRUCTUREDTEXTPARSER_H
36 #include <boost/config/warning_disable.hpp>
39 #include <boost/spirit/include/qi.hpp>
42 #include <boost/spirit/include/phoenix_core.hpp>
45 #include <boost/spirit/include/phoenix_operator.hpp>
48 #include <boost/spirit/include/phoenix_fusion.hpp>
51 #include <boost/spirit/include/phoenix_stl.hpp>
54 #include <boost/spirit/include/phoenix_object.hpp>
57 #include <boost/fusion/include/adapt_struct.hpp>
60 #include <boost/variant/recursive_variant.hpp>
63 #include <boost/fusion/include/io.hpp>
66 #include <boost/filesystem/path.hpp>
69 #include "WStringUtils.h"
70 #include "exceptions/WTypeMismatch.h"
71 #include "exceptions/WNotFound.h"
80 namespace qi = boost::spirit::qi;
83 namespace fusion = boost::fusion;
86 namespace ascii = boost::spirit::ascii;
89 namespace phoenix = boost::phoenix;
92 namespace spirit = boost::spirit;
134 boost::recursive_wrapper< ObjectType >,
168 BOOST_FUSION_ADAPT_STRUCT(
170 ( std::string, m_name )
171 ( std::vector< WStructuredTextParser::MemberType >, m_nodes )
177 BOOST_FUSION_ADAPT_STRUCT(
179 (
std::
string, m_name )
180 (
std::
string, m_value )
200 template <
typename Iterator>
201 struct Grammar: qi::grammar<Iterator, FileType(), ascii::space_type >
208 explicit Grammar( std::ostream& error ):
Grammar::base_type(
file,
"WStructuredTextParser::Grammar" )
211 key %= qi::char_(
"a-zA-Z_" ) >> *qi::char_(
"a-zA-Z_0-9" );
213 value %=
'"' >> *( ~qi::char_(
"\"" ) | qi::char_(
" " ) ) >>
'"';
218 comment %= qi::lexeme[ qi::char_(
"/" ) >> qi::char_(
"/" ) >> *qi::char_(
"a-zA-Z_0-9!\"#$%&'()*,:;<>?@\\^`{|}~/ .@=[]ยง!+-" ) ];
225 object.name(
"object" );
226 kvpair.name(
"key-value pair" );
228 value.name(
"value" );
234 qi::on_error< qi::fail >(
object, error << phoenix::val(
"Error: " ) << qi::_4 );
235 qi::on_error< qi::fail >(
kvpair, error << phoenix::val(
"Error: " ) << qi::_4 );
236 qi::on_error< qi::fail >(
key, error << phoenix::val(
"Error: " ) << qi::_4 );
237 qi::on_error< qi::fail >(
value, error << phoenix::val(
"Error: " ) << qi::_4 );
238 qi::on_error< qi::fail >(
comment, error << phoenix::val(
"Error: " ) << qi::_4 );
239 qi::on_error< qi::fail >(
file, error << phoenix::val(
"Error: " ) << qi::_4 );
247 qi::rule< Iterator, ObjectType(), ascii::space_type >
object;
252 qi::rule< Iterator, FileType(), ascii::space_type >
file;
257 qi::rule< Iterator, CommentType(), ascii::space_type >
comment;
262 qi::rule< Iterator, KeyValueType(), ascii::space_type >
kvpair;
267 qi::rule< Iterator, KeyType() >
key;
272 qi::rule< Iterator, ValueType() >
value;
339 bool exists( std::string key,
bool valuesOnly =
false )
const;
349 size_t count( std::string key,
bool valuesOnly =
false )
const;
364 template<
typename T >
365 T
getValue( std::string key,
const T& defaultValue )
const;
380 template<
typename T >
381 std::vector< T >
getValues( std::string key,
const std::vector< T >& defaults )
const;
395 template<
typename T >
396 std::vector< T >
getValues( std::string key )
const;
409 template<
typename T >
432 std::vector< StructuredValueTree >
getSubTrees( std::string key )
const;
451 void traverse( MemberType current, std::vector< std::string >::const_iterator keyIter,
452 std::vector< std::string >::const_iterator keyEnd,
453 std::vector< ObjectType >& resultObjects,
454 std::vector< KeyValueType >& resultValues )
const;
465 void traverse( FileType current, std::string key,
466 std::vector< ObjectType >& resultObjects,
467 std::vector< KeyValueType >& resultValues )
const;
479 FileType parseFromString( std::string input );
491 FileType parseFromFile( boost::filesystem::path path );
493 template<
typename T >
497 return *getValues< T >( key, std::vector< T >( 1, defaultValue ) ).begin();
500 template<
typename T >
503 std::vector< T > r = getValues< T >( key );
514 template<
typename T >
517 std::vector< T > r = getValues< T >( key );
524 throw WNotFound(
"The key \"" + key +
"\" was not found." );
550 template<
typename T >
579 template<
typename T >
610 template<
typename T >
613 return element.m_name;
617 template<
typename T >
621 std::vector< ObjectType > rObj;
622 std::vector< KeyValueType > rKV;
629 for( std::vector< KeyValueType >::const_iterator i = rKV.begin(); i != rKV.end(); ++i )
633 r.push_back( string_utils::fromString< T >( ( *i ).m_value ) );
638 throw WTypeMismatch(
"Cannot convert element \"" + key +
"\" to desired type." );
647 #endif // WSTRUCTUREDTEXTPARSER_H
std::string m_name
Name string.
std::string m_value
Value string.
Indicates invalid type of something.
qi::rule< Iterator, ValueType() > value
Value rule.
Indicates invalid value which could not be found.
size_t count(std::string key, bool valuesOnly=false) const
It is possible that there are multiple values matching a key.
std::vector< T > getValues(std::string key, const std::vector< T > &defaults) const
Queries the list of values matching the given path.
StructuredValueTree getSubTree(std::string key) const
Gets a subtree.
bool exists(std::string key, bool valuesOnly=false) const
Checks whether the given value or object exists.
FileType m_file
The named values.
std::string operator()(const T &element) const
Returns the m_name member of the specified object or key-valuev pair.
T operator[](std::string key) const
Queries the value with the given name.
StructuredValueTree()
Creates an empty tree.
std::string KeyType
we use these quite often, so define some short alias for them:
Visitor to identify whether the given variant of type WStructuredTextParser::MemberType is a object o...
std::string ValueType
The type used for values.
namespace WStructuredTextParser { /** The grammar describing the structured format.
qi::rule< Iterator, KeyValueType(), ascii::space_type > kvpair
Key-value pair rule.
This namespace contains the WStructuredTextParser data types and the parser.
void traverse(MemberType current, std::vector< std::string >::const_iterator keyIter, std::vector< std::string >::const_iterator keyEnd, std::vector< ObjectType > &resultObjects, std::vector< KeyValueType > &resultValues) const
Recursively fills a result vector using a given path iterator.
qi::rule< Iterator, ObjectType(), ascii::space_type > object
Rule for objects.
std::string CommentType
The type used for comments.
std::vector< MemberType > m_nodes
Object's members.
std::vector< MemberType > FileType
An object representing all objects and comments on file level.
static const std::string Separator
This char is used as separator for identifying values in the tree.
qi::rule< Iterator, FileType(), ascii::space_type > file
Rule for files.
Grammar(std::ostream &error)
Constructor and grammar description.
bool operator()(const T &) const
Returns always false as it is only called for objects.
KeyValueType - a tuple containing name and value.
An object is always a name and contains several further nodes.
std::string operator()(const CommentType &) const
Comments have no name.
Visitor to query the m_name member of WStructuredTextParser::ObjectType and WStructuredTextParser::Ke...
std::vector< StructuredValueTree > getSubTrees(std::string key) const
Gets all matching subtrees.
boost::variant< boost::recursive_wrapper< ObjectType >, KeyValueType, CommentType > MemberType
A node inside the AST is either another object or a key-value pair.
This simplifies working with a tree in a WStructuredTextParser::FileType instance.
virtual ~StructuredValueTree()
Cleanup.
T getValue(std::string key, const T &defaultValue) const
Queries the value with the given name.
Test parsing and query functionality.
bool operator()(const KeyValueType &) const
Returns always true as it is only called for key-value pairs.
std::string m_name
Name of the object.
qi::rule< Iterator, KeyType() > key
Key rule.
qi::rule< Iterator, CommentType(), ascii::space_type > comment
Rule for comments.