From 6f4e5b27b47b1e352b6fedad7fdde41768554c0a Mon Sep 17 00:00:00 2001
From: Adam Wardynski <award@.(B-4.4.46a)>
Date: Fri, 18 Mar 2011 18:14:31 +0100
Subject: [PATCH] OptionalMatch - "optional" match condition.

---
 libwccl/CMakeLists.txt                        |  1 +
 .../ops/match/conditions/optionalmatch.cpp    | 36 +++++++++++++
 libwccl/ops/match/conditions/optionalmatch.h  | 52 +++++++++++++++++++
 3 files changed, 89 insertions(+)
 create mode 100644 libwccl/ops/match/conditions/optionalmatch.cpp
 create mode 100644 libwccl/ops/match/conditions/optionalmatch.h

diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt
index a48ace2..75bcc15 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/conjconditions.cpp
+	ops/match/conditions/optionalmatch.cpp
 	ops/match/conditions/repeatedmatch.cpp
 	ops/match/conditions/tokencondition.cpp
 	ops/match/applyoperator.cpp
diff --git a/libwccl/ops/match/conditions/optionalmatch.cpp b/libwccl/ops/match/conditions/optionalmatch.cpp
new file mode 100644
index 0000000..bbc99ae
--- /dev/null
+++ b/libwccl/ops/match/conditions/optionalmatch.cpp
@@ -0,0 +1,36 @@
+#include <libwccl/ops/match/conditions/optionalmatch.h>
+#include <libwccl/values/matchvector.h>
+#include <sstream>
+
+namespace Wccl {
+
+OptionalMatch::OptionalMatch(const boost::shared_ptr<ConjConditions>& conditions)
+	: _conditions(conditions)
+{
+	BOOST_ASSERT(_conditions);
+}
+
+MatchResult OptionalMatch::apply(boost::shared_ptr<Position> iter_pos, const FunExecContext& context) const
+{
+	int orig_pos = iter_pos->get_value();
+	MatchResult res = _conditions->apply(iter_pos, context);
+	if (res.matched()) {
+		return res;
+	}
+	iter_pos->set_value(orig_pos);
+	return MatchResult(boost::make_shared<Match>());
+}
+
+std::string OptionalMatch::to_string(const Corpus2::Tagset& tagset) const
+{
+	std::ostringstream ostream;
+	ostream << name() << _conditions->to_string(tagset);
+	return ostream.str();
+}
+
+std::ostream& OptionalMatch::write_to(std::ostream& ostream) const
+{
+	return ostream << name() << *_conditions;
+}
+
+} /* end ns Wccl */
diff --git a/libwccl/ops/match/conditions/optionalmatch.h b/libwccl/ops/match/conditions/optionalmatch.h
new file mode 100644
index 0000000..d9f3c1d
--- /dev/null
+++ b/libwccl/ops/match/conditions/optionalmatch.h
@@ -0,0 +1,52 @@
+#ifndef LIBWCCL_OPS_MATCH_CONDITIONS_OPTIONALMATCH_H
+#define LIBWCCL_OPS_MATCH_CONDITIONS_OPTIONALMATCH_H
+
+#include <libwccl/ops/match/conditions/conjconditions.h>
+
+namespace Wccl {
+
+/**
+ * Class for "optional" condition of match
+ */
+class OptionalMatch : public MatchCondition
+{
+public:
+	OptionalMatch(const boost::shared_ptr<ConjConditions>& conditions);
+
+	/**
+	 * @returns Name of the condition.
+	 */
+	std::string name() const {
+		return "optional";
+	}
+	/**
+	 * Applies the condition to the given execution context.
+	 * Inner conditions are executed once.
+	 * If the match, was successfull the result consists of "true"
+	 * and the match.
+	 * If there was no match, "true" is returned anyway, but with a default Match.
+	 * If match is found, the current iter Position "$_" is increased
+	 * as to point one token after all the matched tokens, otherwise
+	 * it stays unchanged.
+	 */
+	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 boost::shared_ptr<ConjConditions> _conditions;
+};
+} /* end ns Wccl */
+
+#endif // LIBWCCL_OPS_MATCH_CONDITIONS_OPTIONALMATCH_H
-- 
GitLab