Skip to content
Snippets Groups Projects
Commit 17c65289 authored by Adam Wardynski's avatar Adam Wardynski
Browse files

ApplyOperator, the main operator behind match rules.

parent d2956550
Branches
No related merge requests found
......@@ -55,6 +55,7 @@ SET(libwccl_STAT_SRC
ops/functions/tset/getsymbols.cpp
ops/functions/tset/getsymbolsinrange.cpp
ops/match/conditions/tokencondition.cpp
ops/match/applyoperator.cpp
ops/match/matchoperator.cpp
ops/rulesequence.cpp
ops/tagaction.cpp
......
#include <libwccl/ops/match/applyoperator.h>
#include <libpwrutils/foreach.h>
namespace Wccl {
ApplyOperator::ApplyOperator(
const VariableAccessor<Position>& cur_iter_pos,
const VariableAccessor<Match>& matches,
const boost::shared_ptr<const MatchOperator>& match_op,
const std::vector<boost::shared_ptr<const MatchAction> >& actions,
const std::vector<boost::shared_ptr<const Function<Bool> > >& conditions)
: _cur_iter_pos(cur_iter_pos),
_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<Position> iter_pos = context.variables()->get_fast(_cur_iter_pos);
boost::shared_ptr<MatchVector> matches =
boost::dynamic_pointer_cast<MatchVector>(context.variables()->get_fast(_matches));
while(context.sentence_context().is_current_inside()) {
// Set initial values of $_ and $m:_M variables for this iteration and launch the match:
iter_pos->set_value(0);
matches->clear();
boost::shared_ptr<Match> match = _match_op->apply(iter_pos, 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);
foreach (const boost::shared_ptr<const MatchAction>& action, _actions) {
action->execute(context);
}
}
// Inner operators (match and its conditions) are responsible for properly
// advancing $_ variable.
// After an iteration, we increase current sentence position by the value of $_
// and repeat until current sentence position goes outside.
BOOST_ASSERT(iter_pos->get_value() > 0);
context.sentence_context().set_position(
context.sentence_context().get_position() + iter_pos->get_value());
}
}
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 */
#ifndef LIBWCCL_OPS_MATCH_APPLYOPERATOR_H
#define LIBWCCL_OPS_MATCH_APPLYOPERATOR_H
#include <libwccl/ops/function.h>
#include <libwccl/ops/match/matchoperator.h>
#include <libwccl/ops/match/matchaction.h>
namespace Wccl {
/**
* Operator that realizes "apply" functionality for match rules
*/
class ApplyOperator : public Expression
{
public:
/**
* @param cur_iter_pos Accessor to the "$_" variable
* @param matches Accessor to the "$m:_M" variable
* @param match_op "match" operator for apply
* @param actions "actions" section of apply, should not be empty
* @param conditions "cond" section of apply, empty by default
*/
ApplyOperator(
const VariableAccessor<Position>& cur_iter_pos,
const VariableAccessor<Match>& matches,
const boost::shared_ptr<const MatchOperator>& match_op,
const std::vector<boost::shared_ptr<const MatchAction> >& actions,
const std::vector<boost::shared_ptr<const Function<Bool> > >& conditions = (std::vector<boost::shared_ptr<const Function<Bool> > >()));
/**
* @returns Name of the operator.
*/
std::string name() const {
return "apply";
}
/**
* @returns String representation of the Action
*/
std::string to_string(const Corpus2::Tagset& tagset) const;
protected:
/**
* Writes string representation of the operator to
* an output stream.
* @returns Stream written to.
* @note May be incomplete and/or containt internal info.
*/
std::ostream& write_to(std::ostream& ostream) const;
/**
* Executes the apply operator on given context.
* It iterates current sentence position applying match operator
* and if match is found and conditions are met, executes actions.
*/
virtual void execute(const ActionExecContext &context) const;
private:
const VariableAccessor<Position> _cur_iter_pos;
const VariableAccessor<Match> _matches;
const boost::shared_ptr<const MatchOperator> _match_op;
const std::vector<boost::shared_ptr<const MatchAction> > _actions;
const std::vector<boost::shared_ptr<const Function<Bool> > > _conditions;
};
} /* end ns Wccl */
#endif // LIBWCCL_OPS_MATCH_APPLYOPERATOR_H
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment