I am newbie in C++, althouth I need to parser a SQL-like expression: country='USA' AND state='CA' AND price >= 100.0, it is just a fake example, but it's feasible.
So, I tried to solve using spirit QI. Each column has a specific type: float, integer, double, char and string. I wanna create a reusable grammar to support those column types with template or/and trait, but I'm blocked.
I want something like that:
template <typename Iterator, typename ColumnType, typename Skipper>
struct test : qi::grammar<Iterator, ColumnType, Skipper>
{
test() : test::base_type(expression)
{
expression = MyTrait<ColumnType>::type >> "AND" >> MyTrait<ColumnType>::type;
}
qi::rule<Iterator, ColumnType, Skipper> expression;
};
I tried to use the Signature template parameter, but didn't work.
MyTrait.h: using namespace boost::spirit::qi;
template< typename T >
struct MyTrait
{
typedef T type;
};
template<> struct MyTrait< double >
{
typedef double_type type;
};
template<> struct MyTrait< float >
{
typedef float_type type;
};
The basic idea in MyTrait is just to convert primitive types (double, float...) to spirit QI types, in order to use them in the grammar. Note that MyTrait<\double>::type results in double_type from QI, but in the grammar must be double_.
main.cpp:
int main() {
std::string input("99.0 AND 2.0");
std::string::const_iterator iter = input.begin();
std::string::const_iterator end = input.end();
test<std::string::const_iterator, double, qi::space_type> test_parser;
double result;
bool r = phrase_parse(iter, end, test_parser, qi::space, result);
return 0;
}
Am I on the right track?
Follow compiler error messages as required by Chris Beck:
g++-4.8 -I/usr/include/boost -O0 -g3 -Wall -c -fmessage-length=0 --std=c++11 -fpermissive -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.cpp"
../src/main.cpp: In instantiation of ‘test<Iterator, ColumnType, Skipper>::test() [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >; ColumnType = double; Skipper = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>]’:
../src/main.cpp:91:60: required from here
../src/main.cpp:76:57: error: dependent-name ‘MyTrait<ColumnType>::type’ is parsed as a non-type, but instantiation yields a type
expression = MyTrait<ColumnType>::type >> "AND" >> MyTrait<ColumnType>::type;
^
../src/main.cpp:76:57: note: say ‘typename MyTrait<ColumnType>::type’ if a type is meant
../src/main.cpp:76:48: error: dependent-name ‘MyTrait<ColumnType>::type’ is parsed as a non-type, but instantiation yields a type
expression = MyTrait<ColumnType>::type >> "AND" >> MyTrait<ColumnType>::type;
^
../src/main.cpp:76:48: note: say ‘typename MyTrait<ColumnType>::type’ if a type is meant