diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt index c3e53ec55e352ce4c0f8bad5cfa9ffadcf075284..2b63e4b476862ad188009f6ab6c2eff759b9122d 100644 --- a/libwccl/CMakeLists.txt +++ b/libwccl/CMakeLists.txt @@ -54,6 +54,7 @@ SET(libwccl_STAT_SRC ops/functions/tset/catfilter.cpp ops/functions/tset/getsymbols.cpp ops/functions/tset/getsymbolsinrange.cpp + ops/match/conditions/conjconditions.cpp ops/match/conditions/tokencondition.cpp ops/match/applyoperator.cpp ops/match/matchoperator.cpp diff --git a/libwccl/ops/match/conditions/conjconditions.cpp b/libwccl/ops/match/conditions/conjconditions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7dd80eb211107e65e8d026c832b77a6c6f98f66d --- /dev/null +++ b/libwccl/ops/match/conditions/conjconditions.cpp @@ -0,0 +1,58 @@ +#include <libwccl/ops/match/conditions/conjconditions.h> +#include <libwccl/values/matchvector.h> +#include <libpwrutils/foreach.h> +#include <sstream> + +namespace Wccl { + +ConjConditions::ConjConditions(const std::vector< boost::shared_ptr<const MatchCondition> >& conditions) + : _conditions(conditions) +{ + BOOST_ASSERT(_conditions.size() > 0); +} + +MatchResult ConjConditions::apply(boost::shared_ptr<Position> iter_pos, const FunExecContext& context) const +{ + boost::shared_ptr<MatchVector> matches(new MatchVector()); + int orig_iter_pos = iter_pos->get_value(); + + foreach (const boost::shared_ptr<const MatchCondition>& cond, _conditions) { + MatchResult res = cond->apply(iter_pos, context); + if(res.matched()) { + matches->append(res.get_match()); + } else { + iter_pos->set_value(orig_iter_pos); + return MatchResult(); + } + } + return MatchResult(matches); +} + +std::string ConjConditions::to_string(const Corpus2::Tagset& tagset) const +{ + std::ostringstream ostream; + ostream << "("; + for(size_t i = 0; i < _conditions.size(); ++i) { + if (i != 0) { + ostream << ", "; + } + ostream << _conditions[i]->to_string(tagset); + } + ostream << ")"; + return ostream.str(); +} + +std::ostream& ConjConditions::write_to(std::ostream &ostream) const +{ + ostream << "("; + for(size_t i = 0; i < _conditions.size(); ++i) { + if (i != 0) { + ostream << ", "; + } + ostream << *_conditions[i]; + } + ostream << ")"; + return ostream; +} + +} /* end ns Wccl */ diff --git a/libwccl/ops/match/conditions/conjconditions.h b/libwccl/ops/match/conditions/conjconditions.h new file mode 100644 index 0000000000000000000000000000000000000000..38d0a145aebcef6f9aa1682dddc46e83a1f9106e --- /dev/null +++ b/libwccl/ops/match/conditions/conjconditions.h @@ -0,0 +1,49 @@ +#ifndef LIBWCCL_OPS_MATCH_CONDITIONS_CONJCONDITIONS_H +#define LIBWCCL_OPS_MATCH_CONDITIONS_CONJCONDITIONS_H + +#include <libwccl/ops/match/matchcondition.h> + +namespace Wccl { + +/** + * Class that wraps a vector of match conditions to act as + * single condition that matches if all inner conditions match. + */ +class ConjConditions : public MatchCondition +{ +public: + ConjConditions(const std::vector< boost::shared_ptr<const MatchCondition> >& conditions); + + /** + * @returns Name of the condition. + */ + std::string name() const { + return "and"; // string repr actually doesn't include this + } + /** + * Applies the condition to the given execution context. + * If match is found, the current iter Position "$_" is increased + * by one (the size of token match, which is always one). + */ + MatchResult apply(boost::shared_ptr<Position> iter_pos, const FunExecContext& context) const; + + /** + * @returns String representation of the MatchCondition + */ + std::string to_string(const Corpus2::Tagset& tagset) const; + +protected: + /** + * Writes string representation of the MatchCondition 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 std::vector<boost::shared_ptr<const MatchCondition> > _conditions; +}; + +} /* end ns Wccl */ + +#endif // LIBWCCL_OPS_MATCH_CONDITIONS_CONJCONDITIONS_H