From 17c6528932d553cb51cdc582bc654b2f098f205c Mon Sep 17 00:00:00 2001 From: Adam Wardynski <award@.(B-4.4.46a)> Date: Fri, 11 Mar 2011 19:52:04 +0100 Subject: [PATCH] ApplyOperator, the main operator behind match rules. --- libwccl/CMakeLists.txt | 1 + libwccl/ops/match/applyoperator.cpp | 102 ++++++++++++++++++++++++++++ libwccl/ops/match/applyoperator.h | 70 +++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 libwccl/ops/match/applyoperator.cpp create mode 100644 libwccl/ops/match/applyoperator.h diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt index f868a40..c3e53ec 100644 --- a/libwccl/CMakeLists.txt +++ b/libwccl/CMakeLists.txt @@ -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 diff --git a/libwccl/ops/match/applyoperator.cpp b/libwccl/ops/match/applyoperator.cpp new file mode 100644 index 0000000..cdac967 --- /dev/null +++ b/libwccl/ops/match/applyoperator.cpp @@ -0,0 +1,102 @@ +#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 */ diff --git a/libwccl/ops/match/applyoperator.h b/libwccl/ops/match/applyoperator.h new file mode 100644 index 0000000..e160a40 --- /dev/null +++ b/libwccl/ops/match/applyoperator.h @@ -0,0 +1,70 @@ +#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 -- GitLab