From 41957b202c3f7099b789de11aecb1f865db666fa Mon Sep 17 00:00:00 2001 From: Adam Wardynski <award@.(win7-laptop)> Date: Fri, 22 Apr 2011 13:24:15 +0200 Subject: [PATCH] Factor MatchOperator into ApplyOperator to prevent confusion. 1) MatchOperator was essentially a wrapper for "match" section of "apply" operator 2) Other operators like Repeat actually used ConjConditions directly, without using MatchOperator - so ApplyOperator could too! 3) The confusion was about "match" referring both to part that is matching sentence against match conditions, and the results of this matching process. That led e.g. to "match_operator" rule in grammar, which was unlike "strset_operator" rule and the like. "match_operator" was about the "match" section in "apply" and now it is more straightforward. Next step should rename "match_fit" to be actual "match_operator", consistent with "XXX_operator" for other XXX types. --- libwccl/CMakeLists.txt | 1 - libwccl/ops/match/applyoperator.cpp | 75 ++++++++++++++++------------- libwccl/ops/match/applyoperator.h | 24 +++++---- libwccl/ops/match/matchoperator.cpp | 29 ----------- libwccl/ops/match/matchoperator.h | 57 ---------------------- libwccl/parser/grammar.g | 22 ++------- 6 files changed, 56 insertions(+), 152 deletions(-) delete mode 100644 libwccl/ops/match/matchoperator.cpp delete mode 100644 libwccl/ops/match/matchoperator.h diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt index eff2894..ecf74df 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 9a5a987..9e9816a 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 d90aadc..f685c72 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 26a46e0..0000000 --- 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 000c38c..0000000 --- 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 5ce65c4..d06ac7f 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] -- GitLab