30 #include "exceptions/WParseError.h"
31 #include "exceptions/WNotFound.h"
33 #include "WPredicateHelper.h"
35 #include "WStructuredTextParser.h"
37 namespace WStructuredTextParser
39 const std::string StructuredValueTree::Separator =
"/";
41 StructuredValueTree::StructuredValueTree(
const FileType& file ):
47 StructuredValueTree::StructuredValueTree()
52 StructuredValueTree::StructuredValueTree(
const std::string& toParse ):
53 m_file( parseFromString( toParse ) )
58 StructuredValueTree::StructuredValueTree(
const boost::filesystem::path& file ):
59 m_file( parseFromFile( file ) )
63 StructuredValueTree::~StructuredValueTree()
68 bool StructuredValueTree::exists( std::string key,
bool valuesOnly )
const
70 return count( key, valuesOnly );
73 size_t StructuredValueTree::count( std::string key,
bool valuesOnly )
const
75 std::vector< ObjectType > rObj;
76 std::vector< KeyValueType > rKV;
79 traverse( m_file, key, rObj, rKV );
87 return rKV.size() + rObj.size();
91 StructuredValueTree StructuredValueTree::getSubTree( std::string key )
const
93 std::vector< StructuredValueTree > r = getSubTrees( key );
102 return StructuredValueTree();
106 std::vector< StructuredValueTree > StructuredValueTree::getSubTrees( std::string key )
const
108 std::vector< ObjectType > rObj;
109 std::vector< KeyValueType > rKV;
110 std::vector< StructuredValueTree > r;
113 traverse( m_file, key, rObj, rKV );
116 for( std::vector< ObjectType >::const_iterator objects = rObj.begin(); objects != rObj.end(); ++objects )
119 r.push_back( StructuredValueTree( ( *objects ).m_nodes ) );
125 void StructuredValueTree::traverse(
FileType current, std::string key,
126 std::vector< ObjectType >& resultObjects,
127 std::vector< KeyValueType >& resultValues )
const
132 if( !keySplit.size() )
138 for( FileType::const_iterator i = current.begin(); i != current.end(); ++i )
140 traverse( *i, keySplit.begin(), keySplit.end(), resultObjects, resultValues );
144 void StructuredValueTree::traverse(
MemberType current, std::vector< std::string >::const_iterator keyIter,
145 std::vector< std::string >::const_iterator keyEnd,
146 std::vector< ObjectType >& resultObjects,
147 std::vector< KeyValueType >& resultValues )
const
150 std::string elementName = boost::apply_visitor( NameQueryVisitor(), current );
151 bool elementIsKeyValuePair = boost::apply_visitor( IsLeafVisitor(), current );
152 bool elementIsComment = boost::apply_visitor( IsCommentVisitor(), current );
157 if( elementIsComment )
163 if( elementName == *keyIter )
166 if( !elementIsKeyValuePair && ( ( keyIter + 1 ) != keyEnd) )
168 ObjectType elementAsObj = boost::get< ObjectType >( current );
169 for( std::vector< MemberType >::const_iterator nodeIter = elementAsObj.
m_nodes.begin();
170 nodeIter != elementAsObj.
m_nodes.end();
173 traverse( *nodeIter, keyIter + 1, keyEnd, resultObjects, resultValues );
176 else if( ( keyIter + 1 ) == keyEnd )
179 if( elementIsKeyValuePair )
182 resultValues.push_back( boost::get< KeyValueType >( current ) );
187 resultObjects.push_back( boost::get< ObjectType >( current ) );
195 FileType parseFromString( std::string input )
197 std::ostringstream error;
198 WStructuredTextParser::Grammar< std::string::const_iterator > parser( error );
202 std::string::const_iterator iter = input.begin();
203 std::string::const_iterator end = input.end();
204 bool r = phrase_parse( iter, end, parser, boost::spirit::ascii::space, ast );
207 if( !( r && iter == end ) )
209 throw WParseError(
"Parse error. Parser message: " + error.str() );
216 FileType parseFromFile( boost::filesystem::path path )
219 std::string input= readFileIntoString( path );
222 std::ostringstream error;
223 WStructuredTextParser::Grammar< std::string::const_iterator > parser( error );
227 std::string::const_iterator iter = input.begin();
228 std::string::const_iterator end = input.end();
229 bool r = phrase_parse( iter, end, parser, boost::spirit::ascii::space, ast );
232 if( !( r && iter == end ) )
234 throw WParseError(
"Parse error. Parser message: " + error.str() );
Indicates invalid input in a parser.
std::vector< std::string > tokenize(const std::string &source, const std::string &delim=WHITESPACE, bool compress=true)
Splits the given string into a vector of strings (so called tokens).
std::vector< MemberType > m_nodes
Object's members.
std::vector< MemberType > FileType
An object representing all objects and comments on file level.
An object is always a name and contains several further nodes.
boost::variant< boost::recursive_wrapper< ObjectType >, KeyValueType, CommentType > MemberType
A node inside the AST is either another object or a key-value pair.