//#include "stdafx.h" #include #include #include #include #include #include #define PHOENIX_LIMIT 3 #include #include #include #include #include #include #include "disambiguate.h" using namespace boost::spirit; namespace spirit = boost::spirit; using namespace phoenix; struct test : public spirit::grammar { template struct definition { definition(test const& self) : keywords(3) { wibble = as_lower_d[min_unambig_p("hell", keywords)] | as_lower_d[min_unambig_p("hello", keywords)] | as_lower_d[min_unambig_p("help", keywords)] | as_lower_d[min_unambig_p("heaven", keywords)] | as_lower_d[min_unambig_p("george", keywords)] | as_lower_d[min_unambig_p("frank", keywords)] | as_lower_d[min_unambig_p("dep", "osit", keywords)] ; }; rule wibble; Disambiguator keywords; rule const& start() const { return wibble; } }; }; void test_parse(std::string const& s, bool succeed, int length) { boost::spirit::parse_info pi = parse(s.begin(), s.end(), test(), space_p); const int endPos = std::distance(s.begin(), pi.stop); if (pi.hit == succeed && (!succeed || length == endPos)) { std::cout << "test_parse(\"" << s << "\", " << std::boolalpha << succeed << ", " << length << ") succeeded\n"; } else { std::cout << "test_parse(\"" << s << "\", " << std::boolalpha << succeed << ", " << length << ") failed:\n" << " pi.hit = " << std::boolalpha << pi.hit << "\n" << " endPos = " << endPos << "\n"; } } namespace boost { namespace spirit { std::ostream& operator<<(std::ostream& os, DisambiguateItem const& item) { using namespace boost::spirit; os << "(name = " << item.name << ", min disambiguous length = " << item.ambiguity << ")"; return os; } } } int main(int, char**) { Disambiguator dis; dis.AddString("hello"); dis.AddString("hell"); dis.AddString("hellp"); dis.AddString("heaven"); try { const int c1 = dis.Ambiguity("hello"); std::cout << "dis.Ambiguity(\"hello\") = " << c1 << " - succeeded as expected\n"; } catch(std::string& s) { std::cout << "dis.Ambiguity(\"hello\") failed - unexpectedly\n"; } try { const int c2 = dis.Ambiguity("wibble"); std::cout << "dis.Ambiguity(\"wibble\") = " << c2 << " - shouldn\'t have got here\n"; } catch(std::string& s) { std::cout << "dis.Ambiguity(\"wibble\") failed as expected\n"; } std::copy(dis.begin(), dis.end(), std::ostream_iterator(std::cout, "\n")); test_parse("hello", true, 5); test_parse("hell", true, 4); test_parse("hel", false, 0); test_parse("help", true, 4); test_parse("hea ven", true, 4); // Not 3 because the skip parser kicks in after the keyword is // matched, matching the trailing spaces... test_parse("heave", true, 5); test_parse("fra", true, 3); test_parse("fr", false, 0); test_parse("de", false, 0); test_parse("dep", true, 3); test_parse("depo", true, 4); test_parse("depos thing 1203", true, 6); return 0; }