/*============================================================================= Copyright (c) 2003 Giovanni Bajo Copyright (c) 2003 Joel de Guzman Copyright (c) 2003 Vaclav Vesely http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include #include #include using namespace boost; using namespace BOOST_SPIRIT_CLASSIC_NS; /////////////////////////////////////////////////////////////////////////////// // // bug_001 // // access_node_d[] and access_match_d[] iterator bug // http://sf.net/mailarchive/forum.php?thread_id=1963157&forum_id=1595 // http://sf.net/mailarchive/forum.php?thread_id=1966224&forum_id=1595 // /////////////////////////////////////////////////////////////////////////////// #include struct my_action { template void operator()(TreeT& /*t*/, IterT begin, IterT end) const { BOOST_TEST(*begin == '1'); BOOST_TEST(*end == '2'); } }; void bug_001() { const char* text = "123"; ast_parse(text, text+3, access_node_d[chlit<>('1')][my_action()]); ast_parse(text, text+3, access_match_d[chlit<>('1')][my_action()]); } /////////////////////////////////////////////////////////////////////////////// // // bug_001 // // mismatch closure return type bug // http://article.gmane.org/gmane.comp.parsers.spirit.general/3678 // /////////////////////////////////////////////////////////////////////////////// #include #include typedef std::string member_type; struct my_closure: closure { member1 val; }; void bug_002() { rule, my_closure::context_t> my_rule = real_p; BOOST_TEST(parse("1", my_rule).full); } /////////////////////////////////////////////////////////////////////////////// // // bug_003 // // impl::detach_clear bug // http://sourceforge.net/mailarchive/forum.php?thread_id=2008510&forum_id=25901 // /////////////////////////////////////////////////////////////////////////////// #include void bug_003() { chset<> set; set = 'a'; } /////////////////////////////////////////////////////////////////////////////// // // bug_004 // // chset<>::operator~(range<>) bug // operator&(chset<>, range<>) bug // operator&(range<>, chset<>) bug // /////////////////////////////////////////////////////////////////////////////// #include #include void bug_004() { const char min = (std::numeric_limits::min)(); const char max = (std::numeric_limits::max)(); { chset<> set(~range<>(min, max)); BOOST_TEST(set.test(min) == false); BOOST_TEST(set.test(min) == false); } { chset<> set(chset<>(anychar_p) & range<>(min, max)); BOOST_TEST(set.test(min) == true); BOOST_TEST(set.test(min) == true); } { chset<> set(range<>(min, max) & chset<>(anychar_p)); BOOST_TEST(set.test(min) == true); BOOST_TEST(set.test(min) == true); } } /////////////////////////////////////////////////////////////////////////////// // // bug_005 // // Most trailing space bug // http://article.gmane.org/gmane.comp.parsers.spirit.general/4029 // JDG: Oct 18, 2005. We shall revert to the previous behavior where // Post skips are not allowed. The reason is that // there is a valid use case where input is obtained // from cin and multi_pass which results in an infinite // loop while the post skipper waits for a whitespace. // For examples like below, the grammar must explicitly // include the post whitespace. One possible way is to // place an end_p at the end of the grammar. The end_p // will trigger the post-skip. // /////////////////////////////////////////////////////////////////////////////// #include using namespace boost; using namespace spirit; void bug_005() { BOOST_TEST( parse(" aaaaaaaaa ", *ch_p('a') >> end_p, space_p).full ); BOOST_TEST( parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, space_p).full ); #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) // not sure why Code Warrior 9.5 does not recognize ch_p(' ') as the // same as space_p (see above) when the inputs are spaces. The // tests below are redundant anyway. #else BOOST_TEST( parse(" aaaaaaaaa ", *ch_p('a') >> end_p, ch_p(' ')).full ); BOOST_TEST( parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, ch_p(' ')).full ); #endif } /////////////////////////////////////////////////////////////////////////////// // // bug_006 // // confix bug // /////////////////////////////////////////////////////////////////////////////// #include #include void bug_006() { BOOST_TEST(parse("#some comment", comment_p('#')).full); } /////////////////////////////////////////////////////////////////////////////// // // bug_007 // // handling of trailing whitespace bug (ast_parse/pt_parse related) // JDG: Oct 18, 2005. We shall revert to the previous behavior where // Post skips are not allowed. The reason is that // there is a valid use case where input is obtained // from cin and multi_pass which results in an infinite // loop while the post skipper waits for a whitespace. // For examples like below, the grammar must explicitly // include the post whitespace. One possible way is to // place an end_p at the end of the grammar. The end_p // will trigger the post-skip. // /////////////////////////////////////////////////////////////////////////////// #include #include void bug_007() { BOOST_TEST(parse("test ", str_p("test") >> end_p, space_p).full); BOOST_TEST(pt_parse("test ", str_p("test") >> end_p, space_p).full); BOOST_TEST(ast_parse("test ", str_p("test") >> end_p, space_p).full); } /////////////////////////////////////////////////////////////////////////////// // // sf_bug_718903 // // see https://sourceforge.net/tracker/index.php // ?func=detail&aid=718903&group_id=28447&atid=393386 // /////////////////////////////////////////////////////////////////////////////// #include #include void sf_bug_718903() { empty_match_parser > e(epsilon_p(chset_p("abc"))); } /////////////////////////////////////////////////////////////////////////////// // // sf_bug_719322 // range_run bug // // see http://sourceforge.net/tracker/index.php // ?func=detail&aid=719322&group_id=28447&atid=393386 // /////////////////////////////////////////////////////////////////////////////// #include void sf_bug_719322() { basic_chset s; s.set(3, 3); s.set(1, 5); BOOST_TEST(s.test(5)); } /////////////////////////////////////////////////////////////////////////////// // // sf_bug_742038 // // see http://sf.net/tracker/ // ?func=detail&atid=393386&aid=742038&group_id=28447 // /////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include template void test_assign(IterT b, IterT e) { typedef scanner scanner_t; #if (defined(__GNUC__) && defined(__MINGW32__)) \ || (defined(__GNUC__) && (__GNUC_MINOR__ < 20)) // There's a bug in g++3.x on MinGW that makes basic_string assert // when assigning from IterT [f, l) where IterT is a position_iterator. // This issue is discussed here: // // http://gcc.gnu.org/ml/libstdc++/2002-03/msg00196.html // // Aparently, this bug is only present on MinGW. I'm clueless as // to why this is so. Regressions on linux seem to be OK! :( // // With, g++3.1, assigning to basic_string from IterT [f, l) is a // compile error (a g++3.1 bug). // // In both cases above, we use a vector instead of a string. typedef std::vector store; #else typedef std::string store; #endif store dst; rule r = (*alpha_p)[assign_a(dst)]; parse(b, e, r); store::iterator d = dst.begin(); while (b != e) { if (*d != *b) BOOST_TEST(*d == *b); ++b; ++d; } } void sf_bug_742038() { std::string src = "abcdef"; const char* tmpfilename = "sf_bug_742038.tmp"; test_assign(src.begin(), src.end()); position_iterator b(src.begin(), src.end(), ""); position_iterator e; test_assign(b, e); { std::fstream f(tmpfilename, std::ios::out); f << src; f.close(); file_iterator<> b1(tmpfilename); file_iterator<> e1(b1.make_end()); test_assign(b1, e1); } std::remove(tmpfilename); } /////////////////////////////////////////////////////////////////////////////// // // bug_009 // // limit_d bug // http://article.gmane.org/gmane.comp.parsers.spirit.devel/1891/ // /////////////////////////////////////////////////////////////////////////////// void bug_009() { parse( "test" , limit_d(1U, 10U)[uint_p] | str_p("test")); } int main() { bug_001(); bug_002(); bug_003(); bug_004(); bug_005(); bug_006(); bug_007(); bug_009(); sf_bug_718903(); sf_bug_719322(); sf_bug_742038(); return boost::report_errors(); }