44 template <
typename R >
50 template <
typename R >
58 template <
typename R ,
typename T >
65 template <
typename R ,
typename T >
68 return ( mT ) ( aNode );
72 template <
typename R ,
typename T >
79 template <
typename R ,
typename T >
82 return ( *
mT ) ( aNode );
88 template <
typename R >
91 mRequiredHash ( 0x0000000000000000 ),
92 mForbiddenHash ( 0x0000000000000000 ),
98 template <
typename R >
109 template <
typename R >
112 if ( mForbidden.find ( aStr ) != mForbidden.end() )
114 exception::ContradictoryParserRule lExc;
115 log ( lExc ,
"Contradictory rule for attribute ",
Quote ( aStr ) );
119 mRequired.insert ( aStr );
124 template <
typename R >
127 if ( mRequired.find ( aStr ) != mRequired.end() )
129 exception::ContradictoryParserRule lExc;
130 log ( lExc ,
"Contradictory rule for attribute ",
Quote ( aStr ) );
134 mForbidden.insert ( aStr );
139 template <
typename R >
142 mOptional.insert ( aStr );
147 template <
typename R >
150 std::set<std::string>::const_iterator lIt;
151 std::stringstream lStr;
152 lStr <<
"Rule " << mRuleId ;
153 lIt = mRequired.begin();
155 if ( lIt != mRequired.end() )
157 lStr <<
" {Require : ";
163 if ( ( ++lIt ) == mRequired.end() )
174 lIt = mForbidden.begin();
176 if ( lIt != mForbidden.end() )
178 lStr <<
" {Forbid : ";
184 if ( ( ++lIt ) == mForbidden.end() )
195 lIt = mOptional.begin();
197 if ( lIt != mOptional.end() )
199 lStr <<
" {Optional : ";
205 if ( ( ++lIt ) == mOptional.end() )
220 template <
typename R >
225 return ( *mFuncPtr ) ( aNode );
229 exception::NoActionSpecified lExc;
230 log ( lExc ,
"No action specified!" );
238 template <
typename R >
240 mNextHash ( 0x0000000000000001 ),
247 template <
typename R >
253 template <
typename R >
254 template <
typename T >
257 mRules.push_back ( aRule );
258 Rule<R>& lRule ( mRules.back() );
260 for ( std::set<std::string>::iterator lIt = lRule.
mRequired.begin() ; lIt != lRule.
mRequired.end() ; ++lIt )
262 boost::unordered_map< std::string , uint64_t >::iterator lIt2 ( mHashes.find ( *lIt ) );
264 if ( lIt2 == mHashes.end() )
266 if ( mNextHash == 0x0000000000000000 )
268 exception::TooManyAttributes lExc;
269 log ( lExc ,
"Too many attributes" );
274 mHashes.insert ( std::make_pair ( *lIt , mNextHash ) );
283 for ( std::set<std::string>::iterator lIt = lRule.
mForbidden.begin() ; lIt != lRule.
mForbidden.end() ; ++lIt )
285 boost::unordered_map< std::string , uint64_t >::iterator lIt2 ( mHashes.find ( *lIt ) );
287 if ( lIt2 == mHashes.end() )
289 if ( mNextHash == 0x0000000000000000 )
291 exception::TooManyAttributes lExc;
292 log ( lExc ,
"Too many attributes" );
297 mHashes.insert ( std::make_pair ( *lIt , mNextHash ) );
306 for ( std::set<std::string>::iterator lIt = lRule.
mOptional.begin() ; lIt != lRule.
mOptional.end() ; ++lIt )
308 boost::unordered_map< std::string , uint64_t >::iterator lIt2 ( mHashes.find ( *lIt ) );
310 if ( lIt2 == mHashes.end() )
312 if ( mNextHash == 0x0000000000000000 )
314 exception::TooManyAttributes lExc;
315 log ( lExc ,
"Too many attributes" );
319 mHashes.insert ( std::make_pair ( *lIt , mNextHash ) );
324 lRule.
mRuleId = ++mRuleCounter;
329 template <
typename R >
332 uint64_t lHash ( 0x0000000000000000 );
336 boost::unordered_map< std::string , uint64_t >::iterator lIt2 ( mHashes.find ( lAttr.name() ) );
338 if ( lIt2 == mHashes.end() )
340 exception::UnknownAttribute lExc;
341 log ( lExc ,
"Parser failed because of unknown attribute ",
Quote ( lAttr.name() ) );
345 lHash |= lIt2->second;
348 std::deque< Rule<R>* > lPassed;
349 std::deque< Rule<R>* > lFailedRequired;
350 std::deque< Rule<R>* > lFailedForbidden;
353 for (
typename std::deque<
Rule<R> >::iterator lIt = mRules.begin() ; lIt != mRules.end() ; ++lIt, ++i )
355 if ( lIt->mForbiddenHash & lHash )
357 lFailedForbidden.push_back ( & ( *lIt ) );
359 else if ( lIt->mRequiredHash & ~lHash )
361 lFailedRequired.push_back ( & ( *lIt ) );
366 lPassed.push_back ( & ( *lIt ) );
370 if ( lPassed.size() == 1 )
372 return ( *lPassed.front() ) ( aNode );
375 if ( lPassed.size() > 1 )
377 log (
Warning() ,
"Ambiguity! " ,
Integer ( lPassed.size() ) ,
" rules passed. Attempting to find the rule with the most stringent requirements." );
378 Rule<R>* lMostStringent ( NULL );
379 uint32_t lCounter ( 0 );
381 for (
typename std::deque<
Rule<R>* >::iterator lIt = lPassed.begin(); lIt != lPassed.end(); ++lIt )
383 if ( lCounter < ( **lIt ).mRequired.size() )
385 lMostStringent = ( *lIt );
388 else if ( lCounter == ( **lIt ).mRequired.size() )
390 lMostStringent = NULL;
394 if ( !lMostStringent )
396 exception::AmbiguousParserRules lExc;
397 log ( lExc ,
"Ambiguity remains! Multiple rules passed " ,
Integer ( lCounter ) ,
" requirements." );
402 return ( *lMostStringent ) ( aNode );
405 std::stringstream lStr;
409 lStr << lAttr.name() <<
"=\"" << lAttr.value() <<
"\", ";
412 std::string lString ( lStr.str() );
413 lString.resize ( lString.size() - 2 );
414 exception::NoRulesPassed lExc;
415 log ( lExc ,
"Node with attributes : " , lString ,
" failed all parser rules because : " );
417 for (
typename std::deque<
Rule<R>* >::iterator lIt = lFailedRequired.begin() ; lIt != lFailedRequired.end(); ++lIt )
419 std::stringstream lStr;
420 uint64_t lTemp ( ( **lIt ).mRequiredHash & ~lHash );
422 for ( boost::unordered_map< std::string , uint64_t >::iterator lIt2 = mHashes.begin() ; lIt2 != mHashes.end() ; ++lIt2 )
424 if ( ( lIt2->second ) & lTemp )
426 lStr <<
"\"" << lIt2->first <<
"\", ";
430 std::string lString ( lStr.str() );
431 lString.resize ( lString.size() - 2 );
432 log ( lExc ,
"Rule " ,
Integer ( ( **lIt ).mRuleId ) ,
" requires attributes : " , lString );
435 for (
typename std::deque<
Rule<R>* >::iterator lIt = lFailedForbidden.begin() ; lIt != lFailedForbidden.end(); ++lIt )
437 std::stringstream lStr;
438 uint64_t lTemp ( ( **lIt ).mForbiddenHash & lHash );
440 for ( boost::unordered_map< std::string , uint64_t >::iterator lIt2 = mHashes.begin() ; lIt2 != mHashes.end() ; ++lIt2 )
442 if ( ( lIt2->second ) & lTemp )
444 lStr <<
"\"" << lIt2->first <<
"\", ";
448 std::string lString ( lStr.str() );
449 lString.resize ( lString.size() - 2 );
450 log ( lExc ,
"Rule " ,
Integer ( ( **lIt ).mRuleId ) ,
" forbids attributes : " , lString );