#include <libwccl/ops/match/applyoperator.h> #include <libwccl/values/matchvector.h> #include <libpwrutils/foreach.h> namespace Wccl { ApplyOperator::ApplyOperator( const VariableAccessor<Match>& matches, const boost::shared_ptr<const MatchOperator>& match_op, const boost::shared_ptr<const std::vector<boost::shared_ptr<MatchAction> > >& actions, const boost::shared_ptr<const std::vector<boost::shared_ptr<Function<Bool> > > >& conditions) : _matches(matches), _match_op(match_op), _actions(actions), _conditions(conditions) { BOOST_ASSERT(_match_op); BOOST_ASSERT(actions->size() > 0); } void ApplyOperator::execute(const ActionExecContext &context) const { boost::shared_ptr<MatchVector> matches = boost::dynamic_pointer_cast<MatchVector>(context.variables()->get_fast(_matches)); context.sentence_context().goto_start(); while(context.sentence_context().is_current_inside()) { int orig_pos = context.sentence_context().get_position(); // Set initial value for $m:_M variable for this iteration and launch the match: matches->clear(); boost::shared_ptr<Match> match = _match_op->apply(context); // Execute the actions only if match isn't empty and all post-conditions are met: bool should_act = !match->empty(); for(size_t i = 0; should_act && i < _conditions->size(); ++i) { should_act = (*_conditions)[i]->apply(context)->get_value(); } if (should_act) { matches->append(match); // the match goes to $m:_M[0] foreach (const boost::shared_ptr<MatchAction>& action, *_actions) { action->execute(context); } } // Inner operators (match and its conditions) are responsible for properly // advancing current sentence position. BOOST_ASSERT(context.sentence_context().get_position() > orig_pos); } } std::string ApplyOperator::to_string(const Corpus2::Tagset& tagset) const { std::ostringstream ostream; ostream << name() << "(" << _match_op->to_string(tagset) << ", "; if (!_conditions->empty()) { ostream << "cond("; for(size_t i = 0; i < _conditions->size(); ++i) { if (i != 0) { ostream << ", "; } ostream << (*_conditions)[i]->to_string(tagset); } ostream << "), "; } ostream << "actions("; for(size_t i = 0; i < _actions->size(); ++i) { if (i != 0) { ostream << ", "; } ostream << (*_actions)[i]->to_string(tagset); } ostream << "))"; return ostream.str(); } std::ostream& ApplyOperator::write_to(std::ostream &ostream) const { ostream << name() << "(" << *_match_op << ", "; if (!_conditions->empty()) { ostream << "cond("; for(size_t i = 0; i < _conditions->size(); ++i) { if (i != 0) { ostream << ", "; } ostream << *(*_conditions)[i]; } ostream << "), "; } ostream << "actions("; for(size_t i = 0; i < (*_actions).size(); ++i) { if (i != 0) { ostream << ", "; } ostream << *(*_actions)[i]; } ostream << "))"; return ostream; } } /* end ns Wccl */