134 lines
5.0 KiB
C++
134 lines
5.0 KiB
C++
/* ----------------------------------------------------------------------------
|
|
|
|
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
|
* Atlanta, Georgia 30332-0415
|
|
* All Rights Reserved
|
|
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
|
|
|
* See LICENSE for the license information
|
|
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* @file testSpirit.cpp
|
|
* @brief 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 <boost/spirit/include/classic_confix.hpp>
|
|
#include <CppUnitLite/TestHarness.h>
|
|
#include <wrap/utilities.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
|
|
EXPECT(parse("8.99", real_p, space_p).full);
|
|
// make sure parsing fails on this one
|
|
EXPECT(!parse("zztop", real_p, space_p).full);
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
TEST( spirit, string ) {
|
|
// check if we can parse a string
|
|
EXPECT(parse("double", str_p("double"), space_p).full);
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
TEST( spirit, sequence ) {
|
|
// check that we skip white space
|
|
EXPECT(parse("int int", str_p("int") >> *str_p("int"), space_p).full);
|
|
EXPECT(parse("int --- - -- -", str_p("int") >> *ch_p('-'), space_p).full);
|
|
EXPECT(parse("const \t string", str_p("const") >> str_p("string"), space_p).full);
|
|
|
|
// note that (see spirit FAQ) the vanilla rule<> does not deal with whitespace
|
|
rule<>vanilla_p = str_p("const") >> str_p("string");
|
|
EXPECT(!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");
|
|
EXPECT(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 ) {
|
|
EXPECT(!parse("Point3", basisType_p, space_p).full);
|
|
EXPECT(parse("string", basisType_p, space_p).full);
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
TEST( spirit, className_p ) {
|
|
EXPECT(parse("Point3", className_p, space_p).full);
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
TEST( spirit, classRef_p ) {
|
|
EXPECT(parse("Point3 &", classRef_p, space_p).full);
|
|
EXPECT(parse("Point3&", classRef_p, space_p).full);
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
TEST( spirit, constMethod_p ) {
|
|
EXPECT(parse("double norm() const;", constMethod_p, space_p).full);
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
TEST( spirit, comments ) {
|
|
// Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
|
//
|
|
// Rule argument_p =
|
|
// ((basisType_p[assign_a(arg.type)] | eigenType | classPtr_p | classRef_p) >> name_p[assign_a(arg.name)])
|
|
// [push_back_a(args, arg)]
|
|
// [assign_a(arg,arg0)];
|
|
//
|
|
// Rule void_p = str_p("void")[assign_a(method.returns_)];
|
|
|
|
vector<string> all_strings;
|
|
string actual;
|
|
// Rule slash_comment_p = str_p("//");
|
|
// Rule comments_p = anychar_p[assign_a(actual)]
|
|
// Rule comments_p = lexeme_d[*(anychar_p)[assign_a(actual)]
|
|
|
|
// Rule line_p = (*anychar_p - comment_p("//"))[assign_a(actual)] >> !(comment_p("//") >> *anychar_p); // FAIL: matches everything
|
|
// Rule line_p = *anychar_p[assign_a(actual)] >> !(comment_p("//") >> *anychar_p); // FAIL: matches last letter
|
|
// Rule line_p = (*anychar_p - comment_p("//"))[assign_a(actual)] >> !(comment_p("//") >> *anychar_p);
|
|
//
|
|
// EXPECT(parse("not commentq // comment", line_p, eol_p).full);
|
|
// EXPECT(assert_equal(string("not comments "), actual));
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
|
/* ************************************************************************* */
|