Newer
Older
#include <libwccl/ops/match/applyoperator.h>
#include <libwccl/values/matchvector.h>
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <libpwrutils/foreach.h>
namespace Wccl {
ApplyOperator::ApplyOperator(
const VariableAccessor<Position>& cur_iter_pos,
const VariableAccessor<Match>& matches,
const boost::shared_ptr<const MatchOperator>& match_op,
const std::vector<boost::shared_ptr<const MatchAction> >& actions,
const std::vector<boost::shared_ptr<const Function<Bool> > >& conditions)
: _cur_iter_pos(cur_iter_pos),
_matches(matches),
_match_op(match_op),
_actions(actions),
_conditions(conditions)
{
BOOST_ASSERT(_match_op);
BOOST_ASSERT(actions.size() > 0);
}
void ApplyOperator::execute(const ActionExecContext &context) const
{
boost::shared_ptr<Position> iter_pos = context.variables()->get_fast(_cur_iter_pos);
boost::shared_ptr<MatchVector> matches =
boost::dynamic_pointer_cast<MatchVector>(context.variables()->get_fast(_matches));
while(context.sentence_context().is_current_inside()) {
// Set initial values of $_ and $m:_M variables for this iteration and launch the match:
iter_pos->set_value(0);
matches->clear();
boost::shared_ptr<Match> match = _match_op->apply(iter_pos, 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]
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
foreach (const boost::shared_ptr<const MatchAction>& action, _actions) {
action->execute(context);
}
}
// Inner operators (match and its conditions) are responsible for properly
// advancing $_ variable.
// After an iteration, we increase current sentence position by the value of $_
// and repeat until current sentence position goes outside.
BOOST_ASSERT(iter_pos->get_value() > 0);
context.sentence_context().set_position(
context.sentence_context().get_position() + iter_pos->get_value());
}
}
std::string ApplyOperator::to_string(const Corpus2::Tagset& tagset) const
{
std::ostringstream ostream;
ostream << name() << "(" << _match_op->to_string(tagset) << ", ";
if (!_conditions.empty()) {
ostream << "cond(";
for(size_t i = 0; i < _conditions.size(); ++i) {
if (i != 0) {
ostream << ", ";
}
ostream << _conditions[i]->to_string(tagset);
}
ostream << "), ";
}
ostream << "actions(";
for(size_t i = 0; i < _actions.size(); ++i) {
if (i != 0) {
ostream << ", ";
}
ostream << _actions[i]->to_string(tagset);
}
ostream << "))";
return ostream.str();
}
std::ostream& ApplyOperator::write_to(std::ostream &ostream) const
{
ostream << name() << "(" << *_match_op << ", ";
if (!_conditions.empty()) {
ostream << "cond(";
for(size_t i = 0; i < _conditions.size(); ++i) {
if (i != 0) {
ostream << ", ";
}
ostream << *_conditions[i];
}
ostream << "), ";
}
ostream << "actions(";
for(size_t i = 0; i < _actions.size(); ++i) {
if (i != 0) {
ostream << ", ";
}
ostream << *_actions[i];
}
ostream << "))";
return ostream;
}
} /* end ns Wccl */