From 8b3239c3a45dd905cadb68db98126ccffaa5b434 Mon Sep 17 00:00:00 2001
From: Pawel Orlowicz <porlowicz@gmail.com>
Date: Tue, 24 Jul 2012 10:32:22 +0200
Subject: [PATCH] + action setprop with usage example

---
 examples/prop-match.ccl                    | 47 +++++++++++++
 libwccl/CMakeLists.txt                     |  1 +
 libwccl/ops/match/actions/setpropmatch.cpp | 64 +++++++++++++++++
 libwccl/ops/match/actions/setpropmatch.h   | 80 ++++++++++++++++++++++
 libwccl/parser/grammar.g                   | 23 +++++++
 5 files changed, 215 insertions(+)
 create mode 100644 examples/prop-match.ccl
 create mode 100644 libwccl/ops/match/actions/setpropmatch.cpp
 create mode 100644 libwccl/ops/match/actions/setpropmatch.h

diff --git a/examples/prop-match.ccl b/examples/prop-match.ccl
new file mode 100644
index 0000000..ce8ba1e
--- /dev/null
+++ b/examples/prop-match.ccl
@@ -0,0 +1,47 @@
+
+
+match_rules(
+	apply(
+		match(
+			optional(equal(base[0], "nie")),
+			repeat(
+				inter(class[0], {adj, ppas, pact})
+			)
+		),
+		cond(
+			agr(first(:2), last(M), {nmb,gnd,cas})
+		),
+		actions(
+			mark(M, "AdjP")
+		)
+	);
+ 
+	apply(
+		match(
+			optional(is("AdjP")),
+			inter(class[0], {subst, ger, depr})
+		),
+		cond(
+			or(
+				empty(:1),
+				agrpp(last(:1), first(:2), {nmb,gnd,cas})
+			)
+		),
+		actions(
+			setprop(M, "keyO", "valueO")
+		)
+	);
+	apply(
+		match(
+			optional(is("AdjP")),
+			inter(class[0], {subst, ger, depr})
+		),
+		cond(
+			equal(orth[1], "trudno")
+		),
+		actions(
+			setprop(M, "keyX", "valueX")
+		)
+	)
+)
+
diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt
index 1aaf30c..60088bc 100644
--- a/libwccl/CMakeLists.txt
+++ b/libwccl/CMakeLists.txt
@@ -75,6 +75,7 @@ SET(libwccl_STAT_SRC
 	ops/match/actions/markmatch.cpp
 	ops/match/actions/overwritematch.cpp
 	ops/match/actions/unmarkmatch.cpp
+	ops/match/actions/setpropmatch.cpp
 	ops/match/applyoperator.cpp
 	ops/match/conditions/conjconditions.cpp
 	ops/match/conditions/isannotatedas.cpp
diff --git a/libwccl/ops/match/actions/setpropmatch.cpp b/libwccl/ops/match/actions/setpropmatch.cpp
new file mode 100644
index 0000000..81b0dd0
--- /dev/null
+++ b/libwccl/ops/match/actions/setpropmatch.cpp
@@ -0,0 +1,64 @@
+/*
+    Copyright (C) 2011 Adam Wardyński, Tomasz Śniatowski, Paweł Kędzia,
+    Adam Radziszewski, Bartosz Broda
+    Part of the WCCL project
+
+    This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 3 of the License, or (at your option)
+any later version.
+
+    This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. 
+
+    See the LICENSE, COPYING.LESSER and COPYING files for more details.
+*/
+
+#include <libwccl/values/match.h>
+#include <libwccl/ops/match/actions/setpropmatch.h>
+#include <libcorpus2/ann/annotatedsentence.h>
+
+#include <sstream>
+
+namespace Wccl {
+namespace Matching {
+
+void PropMatch::execute(const ActionExecContext& context) const
+{
+	SentenceContext& sc = context.sentence_context();
+	boost::shared_ptr<Corpus2::AnnotatedSentence> as;
+	as = boost::dynamic_pointer_cast<Corpus2::AnnotatedSentence>(sc.get_sentence_ptr());
+	if (!as) {
+		throw InvalidArgument("context", "Operator needs an annotated sentence.");
+	}
+
+	int abs_pos = match_->apply(context)->first_token(as);
+	if(sc.is_outside(abs_pos)) {
+		throw WcclError("Received starting match that points outside sentence.");
+	}
+
+	Corpus2::Token* token = ((Corpus2::Sentence&) *as)[abs_pos];
+	boost::shared_ptr<Corpus2::TokenMetaData> metadata = token->get_metadata();
+	if(metadata == boost::shared_ptr<Corpus2::TokenMetaData>()){
+		token->create_metadata();
+		metadata = token->get_metadata();
+	}
+	metadata->set_attribute(key_name_, value_name_);
+
+}
+
+std::string PropMatch::to_string(const Corpus2::Tagset& tagset) const
+{
+	std::ostringstream os;
+	os << name() << "(" << match_->to_string(tagset) << ", \"" << key_name_ << ", \"" << value_name_ << "\")";
+	return os.str();
+}
+
+std::ostream& PropMatch::write_to(std::ostream& os) const
+{
+	return os << name() << "(" << *match_ << ", \"" << key_name_ << ", \"" << value_name_ << "\")";
+}
+
+} /* end ns Matching */
+} /* end ns Wccl */
diff --git a/libwccl/ops/match/actions/setpropmatch.h b/libwccl/ops/match/actions/setpropmatch.h
new file mode 100644
index 0000000..c8ba70c
--- /dev/null
+++ b/libwccl/ops/match/actions/setpropmatch.h
@@ -0,0 +1,80 @@
+/*
+    Copyright (C) 2011 Adam Wardyński, Tomasz Śniatowski, Paweł Kędzia,
+    Adam Radziszewski, Bartosz Broda
+    Part of the WCCL project
+
+    This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 3 of the License, or (at your option)
+any later version.
+
+    This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. 
+
+    See the LICENSE, COPYING.LESSER and COPYING files for more details.
+*/
+
+#ifndef LIBWCCL_OPS_MATCH_ACTIONS_SETPROPMATCH_H
+#define LIBWCCL_OPS_MATCH_ACTIONS_SETPROPMATCH_H
+
+#include <libwccl/ops/match/matchaction.h>
+#include <libwccl/ops/function.h>
+
+namespace Wccl {
+namespace Matching {
+
+/**
+ * Action to add properties to tokens.
+ */
+class PropMatch : public MatchAction
+{
+public:
+	PropMatch(
+			const boost::shared_ptr<Function<Match> >& match,
+			const std::string& key_name,
+			const std::string& value_name)
+		: match_(match),
+		  key_name_(key_name),
+		  value_name_(value_name)
+	{
+		BOOST_ASSERT(match_);
+		BOOST_ASSERT(!key_name_.empty());
+		BOOST_ASSERT(!value_name_.empty());
+	}
+
+	/**
+	 * @returns Name of the action.
+	 */
+	std::string name() const {
+		return "setprop";
+	}
+
+	/**
+	 * Executes the action for the given execution context.
+	 */
+	void execute(const ActionExecContext& context) const;
+
+	/**
+	 * @returns String representation of the expression.
+	 */
+	std::string to_string(const Corpus2::Tagset& tagset) const;
+
+protected:
+	/**
+	 * Writes string representation of the MatchAction to
+	 * an output stream.
+	 * @returns Stream written to.
+	 * @note May be incomplete and/or containt internal info.
+	 */
+	virtual std::ostream& write_to(std::ostream& ostream) const;
+private:
+	const boost::shared_ptr<Function<Match> > match_;
+	const std::string key_name_;
+	const std::string value_name_;
+};
+
+} /* end ns Matching */
+} /* end ns Wccl */
+
+#endif // LIBWCCL_OPS_MATCH_ACTIONS_SETPROPMATCH_H
diff --git a/libwccl/parser/grammar.g b/libwccl/parser/grammar.g
index 167e390..688924d 100644
--- a/libwccl/parser/grammar.g
+++ b/libwccl/parser/grammar.g
@@ -99,6 +99,7 @@ header {
 	#include <libwccl/ops/match/conditions/longest.h>
 	#include <libwccl/ops/match/actions/markmatch.h>
 	#include <libwccl/ops/match/actions/unmarkmatch.h>
+	#include <libwccl/ops/match/actions/setpropmatch.h>
 	#include <libwccl/ops/match/actions/overwritematch.h>
 	#include <libwccl/ops/functions/match/submatch.h>
 
@@ -2704,6 +2705,7 @@ match_action
 	: m_act = match_mark_action   [scope]
 	| m_act = match_unmark_action [scope]
 	| m_act = match_remark_action [scope]
+	| m_act = match_setprop_action [scope]
 ;
 
 // Match mark action
@@ -2807,6 +2809,27 @@ match_remark_action
 		}
 ;
 
+// Match prop action
+// Returns boost::shared_ptr<Matching::PropMatch>
+match_setprop_action
+	[ParsingScope& scope]
+	returns [boost::shared_ptr<Matching::PropMatch> m_act]
+{
+	boost::shared_ptr<Function<Match> > match_at;
+}
+	: "setprop" LPAREN
+				match_at = match_operator[scope] COMMA
+				key_name : STRING COMMA
+				value_name : STRING
+			RPAREN {
+				m_act.reset(
+					new Matching::PropMatch(
+							match_at,
+							((antlr::Token*)key_name)->getText(),
+							((antlr::Token*)value_name)->getText()));
+			}
+;
+
 // Match action separated by comma
 // Returns boost::shared_ptr<std::vector<boost::shared_ptr<Matching::MatchAction> > >
 match_action_comma_sep
-- 
GitLab