95 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
		
		
			
		
	
	
			95 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
|  | /**
 | ||
|  |  * Unit test for Boost's awesome Spirit parser | ||
|  |  * Author: Frank Dellaert | ||
|  |  **/ | ||
|  | 
 | ||
|  | #include <boost/spirit/include/classic_core.hpp>
 | ||
|  | #include <boost/spirit/include/classic_push_back_actor.hpp>
 | ||
|  | #include <CppUnitLite/TestHarness.h>
 | ||
|  | 
 | ||
|  | using namespace std; | ||
|  | using namespace BOOST_SPIRIT_CLASSIC_NS; | ||
|  | 
 | ||
|  | typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> Rule; | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | // lexeme_d turns off white space skipping
 | ||
|  | // http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html
 | ||
|  | Rule name_p       = lexeme_d[alpha_p >> *(alnum_p | '_')]; | ||
|  | Rule className_p  = lexeme_d[upper_p >> *(alnum_p | '_')]; | ||
|  | Rule methodName_p = lexeme_d[lower_p >> *(alnum_p | '_')]; | ||
|  | 
 | ||
|  | Rule basisType_p = (str_p("string") | "bool" | "size_t" | "int" | "double" | "Vector" | "Matrix"); | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | TEST( spirit, real ) { | ||
|  |   // check if we can parse 8.99 as a real
 | ||
|  |   CHECK(parse("8.99", real_p, space_p).full); | ||
|  |   // make sure parsing fails on this one
 | ||
|  |   CHECK(!parse("zztop", real_p, space_p).full); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | TEST( spirit, string ) { | ||
|  |   // check if we can parse a string
 | ||
|  |   CHECK(parse("double", str_p("double"), space_p).full); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | TEST( spirit, sequence ) { | ||
|  |   // check that we skip white space
 | ||
|  |   CHECK(parse("int int", str_p("int") >> *str_p("int"), space_p).full); | ||
|  |   CHECK(parse("int --- - -- -", str_p("int") >> *ch_p('-'), space_p).full); | ||
|  |   CHECK(parse("const \t string", str_p("const") >> str_p("string"), space_p).full); | ||
|  | 
 | ||
|  |   // not that (see spirit FAQ) the vanilla rule<> does not deal with whitespace
 | ||
|  |   rule<>vanilla_p = str_p("const") >> str_p("string"); | ||
|  |   CHECK(!parse("const \t string", vanilla_p, space_p).full); | ||
|  | 
 | ||
|  |   // to fix it, we need to use <phrase_scanner_t>
 | ||
|  |   rule<phrase_scanner_t>phrase_level_p = str_p("const") >> str_p("string"); | ||
|  |   CHECK(parse("const \t string", phrase_level_p, space_p).full); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | // parser for interface files
 | ||
|  | 
 | ||
|  | // const string reference reference
 | ||
|  | Rule constStringRef_p =  | ||
|  |   str_p("const") >> "string" >> '&'; | ||
|  | 
 | ||
|  | // class reference
 | ||
|  | Rule classRef_p = className_p >> '&'; | ||
|  | 
 | ||
|  | // const class reference
 | ||
|  | Rule constClassRef_p = str_p("const") >> classRef_p; | ||
|  | 
 | ||
|  | // method parsers
 | ||
|  | Rule constMethod_p = basisType_p >> methodName_p >> '(' >> ')' >> "const" >> ';'; | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | TEST( spirit, basisType_p ) { | ||
|  |   CHECK(!parse("Point3", basisType_p, space_p).full); | ||
|  |   CHECK(parse("string", basisType_p, space_p).full); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | TEST( spirit, className_p ) { | ||
|  |   CHECK(parse("Point3", className_p, space_p).full); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | TEST( spirit, classRef_p ) { | ||
|  |   CHECK(parse("Point3 &", classRef_p, space_p).full); | ||
|  |   CHECK(parse("Point3&", classRef_p, space_p).full); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | TEST( spirit, constMethod_p ) { | ||
|  |   CHECK(parse("double norm() const;", constMethod_p, space_p).full); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | int main() { TestResult tr; TestRegistry::runAllTests(tr); return 0; } | ||
|  | /* ************************************************************************* */ |