diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt index eff2894c194703220ab51d2a5ffd455f517b84bc..ecf74dfecea0e4b2e8b7e4c79f1c6168f231efe3 100644 --- a/libwccl/CMakeLists.txt +++ b/libwccl/CMakeLists.txt @@ -70,7 +70,6 @@ SET(libwccl_STAT_SRC ops/match/conditions/optionalmatch.cpp ops/match/conditions/repeatedmatch.cpp ops/match/conditions/tokencondition.cpp - ops/match/matchoperator.cpp ops/matchrule.cpp ops/rulesequence.cpp ops/tagaction.cpp diff --git a/libwccl/ops/match/applyoperator.cpp b/libwccl/ops/match/applyoperator.cpp index 9a5a9878b185a8ea5a4e254539354779d8fc70c2..9e9816ad85dfe0c9b1aa937f22a6bacfcc918c45 100644 --- a/libwccl/ops/match/applyoperator.cpp +++ b/libwccl/ops/match/applyoperator.cpp @@ -1,48 +1,55 @@ #include <libwccl/ops/match/applyoperator.h> -#include <libwccl/values/matchvector.h> +#include <libwccl/values/match.h> +#include <libwccl/ops/match/conditions/conjconditions.h> +#include <libwccl/ops/match/matchaction.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 ConjConditions>& match_conditions, 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) + const boost::shared_ptr<const std::vector<boost::shared_ptr<Function<Bool> > > >& apply_conditions) + : matches_(matches), + match_conditions_(match_conditions), + actions_(actions), + apply_conditions_(apply_conditions) { - BOOST_ASSERT(_match_op); - BOOST_ASSERT(actions->size() > 0); + BOOST_ASSERT(match_conditions_); + BOOST_ASSERT(actions_->size() > 0); } void ApplyOperator::execute(const ActionExecContext &context) const { MatchVector* matches = dynamic_cast<MatchVector*>( - &context.variables()->get_fast(_matches)->get_value()); + &context.variables()->get_fast(matches_)->get_value()); BOOST_ASSERT(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); + MatchResult match = match_conditions_->apply(context); + // Execute the actions only if there was a match and all post-conditions are met: + if (!match.matched()) { + // no match - advance current position by 1. + context.sentence_context().set_position(orig_pos + 1); + } else { + // there was a match - check conditions of apply + bool should_act = true; + for(size_t i = 0; should_act && i < apply_conditions_->size(); ++i) { + should_act = (*apply_conditions_)[i]->apply(context)->get_value(); + } + if (should_act) { + matches->append(match.get_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. + // Inner operators are responsible for properly advancing current sentence position. BOOST_ASSERT(context.sentence_context().get_position() > orig_pos); } } @@ -50,23 +57,23 @@ void ApplyOperator::execute(const ActionExecContext &context) const std::string ApplyOperator::to_string(const Corpus2::Tagset& tagset) const { std::ostringstream ostream; - ostream << name() << "(" << _match_op->to_string(tagset) << ", "; - if (!_conditions->empty()) { + ostream << name() << "(match" << match_conditions_->to_string(tagset) << ", "; + if (!apply_conditions_->empty()) { ostream << "cond("; - for(size_t i = 0; i < _conditions->size(); ++i) { + for(size_t i = 0; i < apply_conditions_->size(); ++i) { if (i != 0) { ostream << ", "; } - ostream << (*_conditions)[i]->to_string(tagset); + ostream << (*apply_conditions_)[i]->to_string(tagset); } ostream << "), "; } ostream << "actions("; - for(size_t i = 0; i < _actions->size(); ++i) { + for(size_t i = 0; i < actions_->size(); ++i) { if (i != 0) { ostream << ", "; } - ostream << (*_actions)[i]->to_string(tagset); + ostream << (*actions_)[i]->to_string(tagset); } ostream << "))"; return ostream.str(); @@ -74,23 +81,23 @@ std::string ApplyOperator::to_string(const Corpus2::Tagset& tagset) const std::ostream& ApplyOperator::write_to(std::ostream &ostream) const { - ostream << name() << "(" << *_match_op << ", "; - if (!_conditions->empty()) { + ostream << name() << "(match" << *match_conditions_ << ", "; + if (!apply_conditions_->empty()) { ostream << "cond("; - for(size_t i = 0; i < _conditions->size(); ++i) { + for(size_t i = 0; i < apply_conditions_->size(); ++i) { if (i != 0) { ostream << ", "; } - ostream << *(*_conditions)[i]; + ostream << *(*apply_conditions_)[i]; } ostream << "), "; } ostream << "actions("; - for(size_t i = 0; i < (*_actions).size(); ++i) { + for(size_t i = 0; i < (*actions_).size(); ++i) { if (i != 0) { ostream << ", "; } - ostream << *(*_actions)[i]; + ostream << *(*actions_)[i]; } ostream << "))"; return ostream; diff --git a/libwccl/ops/match/applyoperator.h b/libwccl/ops/match/applyoperator.h index d90aadc20dbc981bda82ba878f65acc7ebef6443..f685c72a023f49d278afc73b2ff2c518cf3ca944 100644 --- a/libwccl/ops/match/applyoperator.h +++ b/libwccl/ops/match/applyoperator.h @@ -3,12 +3,10 @@ #include <libwccl/ops/functions/bool/predicates/logicalpredicate.h> -#include <libwccl/ops/match/matchoperator.h> -#include <libwccl/ops/match/matchaction.h> - - namespace Wccl { +class ConjConditions; +class MatchAction; /** * Operator that realizes "apply" functionality for match rules */ @@ -18,15 +16,15 @@ public: typedef LogicalPredicate::BoolFunctionPtrVector BoolFunctionPtrVector; /** * @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 + * @param match_conditions "match" sections of apply; conditions for finding matches + * @param actions "actions" section of apply, should not be empty; actions to apply on matches + * @param conditions "cond" section of apply, empty by default; conditions for applying the actions */ ApplyOperator( const VariableAccessor<Match>& matches, - const boost::shared_ptr<const MatchOperator>& match_op, + const boost::shared_ptr<const ConjConditions>& match_conditions, const boost::shared_ptr<const std::vector<boost::shared_ptr<MatchAction> > >& actions, - const boost::shared_ptr<const BoolFunctionPtrVector>& conditions + const boost::shared_ptr<const BoolFunctionPtrVector>& apply_conditions = boost::shared_ptr<const BoolFunctionPtrVector>(new BoolFunctionPtrVector())); /** @@ -58,10 +56,10 @@ protected: std::ostream& write_to(std::ostream& ostream) const; private: - 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; + const VariableAccessor<Match> matches_; + const boost::shared_ptr<const ConjConditions> match_conditions_; + const boost::shared_ptr<const std::vector<boost::shared_ptr<MatchAction> > > actions_; + const boost::shared_ptr<const std::vector<boost::shared_ptr<Function<Bool> > > > apply_conditions_; }; } /* end ns Wccl */ diff --git a/libwccl/ops/match/matchoperator.cpp b/libwccl/ops/match/matchoperator.cpp deleted file mode 100644 index 26a46e047f40563008818d31d37cc786887d0c94..0000000000000000000000000000000000000000 --- a/libwccl/ops/match/matchoperator.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <libwccl/ops/match/matchoperator.h> -#include <sstream> - -namespace Wccl { - -boost::shared_ptr<Match> MatchOperator::apply(const ActionExecContext& context) const -{ - int orig_pos = context.sentence_context().get_position(); - MatchResult res = _conditions->apply(context); - if(res.matched()) { - return res.get_match(); - } - context.sentence_context().set_position(orig_pos + 1); - return boost::make_shared<Match>(); -} - -std::string MatchOperator::to_string(const Corpus2::Tagset& tagset) const -{ - std::ostringstream ostream; - ostream << name() << _conditions->to_string(tagset); - return ostream.str(); -} - -std::ostream& MatchOperator::write_to(std::ostream &ostream) const -{ - return ostream << name() << *_conditions; -} - -} /* end ns Wccl */ diff --git a/libwccl/ops/match/matchoperator.h b/libwccl/ops/match/matchoperator.h deleted file mode 100644 index 000c38c89c81447378d204c461ec3b08c95bce23..0000000000000000000000000000000000000000 --- a/libwccl/ops/match/matchoperator.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef LIBWCCL_OPS_MATCH_MATCHOPERATOR_H -#define LIBWCCL_OPS_MATCH_MATCHOPERATOR_H - -#include <libwccl/ops/match/conditions/conjconditions.h> - -namespace Wccl { - -/** - * Operator that realizes "match" functionality for match rules - */ -class MatchOperator : public Expression -{ -public: - MatchOperator(const boost::shared_ptr<ConjConditions>& conditions) - : _conditions(conditions) { - BOOST_ASSERT(_conditions); - } - - /** - * @returns Name of the operator. - */ - std::string name() const { - return "match"; - } - - /** - * @returns String representation of the Action - */ - std::string to_string(const Corpus2::Tagset& tagset) const; - - /** - * Applies the operator to the given context. - * @returns Vector of matches corresponding to match conditions, - * if all conditions were met. In such case current sentence position - * points to one position ahead of matched tokens. - * Empty MatchVector is returned if any of the conditions was not met. - * In such case current Position in sentence is advanced by 1. - * @param context Execution context - current sentence and Variables to operate on - */ - boost::shared_ptr<Match> apply(const ActionExecContext& context) 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; - -private: - const boost::shared_ptr<ConjConditions> _conditions; -}; - -} /* end ns Wccl */ - -#endif // LIBWCCL_OPS_MATCH_MATCHOPERATOR_H diff --git a/libwccl/parser/grammar.g b/libwccl/parser/grammar.g index 5ce65c46b90c91cf2ef44016bb29f5885473bbe0..d06ac7f16a48bfd6c97185ba0da039670d43bd66 100644 --- a/libwccl/parser/grammar.g +++ b/libwccl/parser/grammar.g @@ -2008,42 +2008,28 @@ match_apply_operator returns [boost::shared_ptr<ApplyOperator> ret_op] { VariableAccessor<Match> matches = vars.create_accessor<Match>("_M");; - boost::shared_ptr<const MatchOperator> match_op; + boost::shared_ptr<ConjConditions> match_cond; boost::shared_ptr<std::vector<boost::shared_ptr<MatchAction> > > actions; boost::shared_ptr<std::vector<boost::shared_ptr<Function<Bool> > > > conditions; - } : "apply" LPAREN - match_op = match_operator[tagset, vars] COMMA + "match" LPAREN match_cond = match_condition [tagset,vars] RPAREN COMMA ("cond" LPAREN conditions = bool_operator_comma_sep [tagset, vars] RPAREN COMMA)? "actions" LPAREN actions = match_action_comma_sep [tagset, vars] RPAREN RPAREN { if (conditions) { ret_op.reset( - new ApplyOperator(matches, match_op, actions, conditions) + new ApplyOperator(matches, match_cond, actions, conditions) ); } else { ret_op.reset( - new ApplyOperator(matches, match_op, actions) + new ApplyOperator(matches, match_cond, actions) ); } } ; -// Match operator: match(match_conditions) -// Returns boost::shared_ptr<MatchOperator> -match_operator - [const Corpus2::Tagset& tagset, Variables& vars] - returns [boost::shared_ptr<MatchOperator> op] -{ - boost::shared_ptr<ConjConditions> match_cond; -} - : "match" LPAREN match_cond = match_condition [tagset,vars] RPAREN { - op.reset(new MatchOperator(match_cond)); - } -; - // Match conditions. Wrapper for vector of the match conditions match_condition [const Corpus2::Tagset& tagset, Variables& vars]