diff --git a/libwccl/values/matchvector.cpp b/libwccl/values/matchvector.cpp index bf801362229a0a41bb9f6ac54dcf5921c2eae6e0..6415ed0d4ac4bd2a7b1d19b928868ffa3c9ce62b 100644 --- a/libwccl/values/matchvector.cpp +++ b/libwccl/values/matchvector.cpp @@ -27,12 +27,21 @@ Position MatchVector::first_token(const boost::shared_ptr<Corpus2::AnnotatedSent if (matches_.empty()) { return Position(Position::Nowhere); } else { + // Negative positions are invalid, including specials like Nowhere, + // so we can't just find minimum value but minimum *non-negative* value. + // Note: yes, the code assumes the special values like Nowhere are indeed negative. Position p = matches_.front()->first_token(s); - for (size_t i = 1; i < matches_.size(); ++i) { + size_t i = 1; + while ((p.get_value() < 0) && (i < matches_.size())) { + p = matches_[i]->first_token(s); + ++i; + } + while (i < matches_.size()) { Position c = matches_[i]->first_token(s); - if (c.get_value() < p.get_value()) { + if ((c.get_value() >= 0) && (c.get_value() < p.get_value())) { p = c; } + ++i; } return p; } diff --git a/tests/match.cpp b/tests/match.cpp index 72ea47dc5956ee28f32db6e7a07de118718b2f0f..9b3ab09ee9b8da47a745fc1f0dbb23bfde605e2d 100644 --- a/tests/match.cpp +++ b/tests/match.cpp @@ -98,6 +98,18 @@ BOOST_AUTO_TEST_CASE(matchvector_first_last) m1->append(boost::make_shared<TokenMatch>(1)); BOOST_CHECK_EQUAL(m2.first_token(ptr).get_value(), 1); BOOST_CHECK_EQUAL(m2.last_token(ptr).get_value(), 7); + Wccl::MatchVector m3; + BOOST_CHECK_EQUAL(m3.to_raw_string(), "MATCH()"); + BOOST_CHECK_EQUAL(m3.first_token(ptr).get_value(), Wccl::Position::Nowhere); + BOOST_CHECK_EQUAL(m3.last_token(ptr).get_value(), Wccl::Position::Nowhere); + m3.append(boost::make_shared<MatchVector>()); + BOOST_CHECK_EQUAL(m3.to_raw_string(), "MATCH(MATCH())"); + BOOST_CHECK_EQUAL(m3.first_token(ptr).get_value(), Wccl::Position::Nowhere); + BOOST_CHECK_EQUAL(m3.last_token(ptr).get_value(), Wccl::Position::Nowhere); + m3.append(boost::make_shared<TokenMatch>(1)); + BOOST_CHECK_EQUAL(m3.to_raw_string(), "MATCH(MATCH(),TOK[1])"); + BOOST_CHECK_EQUAL(m3.first_token(ptr).get_value(), 1); + BOOST_CHECK_EQUAL(m3.last_token(ptr).get_value(), 1); } BOOST_AUTO_TEST_CASE(varmatch)