In the boost::spirit documentation, grammars are defined by using struct. For example,
template <typename Iterator>
struct my_grammar
: qi::grammar<Iterator, qi::locals<std::string>, ascii::space_type >
{
my_grammar()
: my_grammar::base_type(start, "start")
{
// using this and that
// rules and action etc.
}
};
I am wondering if I can write it using class (if not then why?). I am doing this.
In header file
template<typename Iterator>
class my_grammar
{
public:
my_grammar();
// rules declaration goes here.
};
and in source file
template<typename Iterator>
my_grammar::my_grammar()
: qi::grammar::base_type(start, "start")
{
// write grammar and actions.
}
Name-space has been shorted using typedefs. I am writing using above method and compiler is giving me too much of errors which are hard to understand. Is it fundamentally ok or I am doing something odd?
Can you point me to some code where someone has used class instead of struct to write grammar?
UPDATE :
I am not able to link now. It says that undefined reference to
dimacs_grammar<__gnu_cxx::__normal_iterator, std::allocator > > >::my_grammar()` . The problem is that while using struct, I was writing
my_grammar()
: my_grammar::base_type(start, "start")
I am not sure how to write equivalent class declaration and definition for this?
Classes & structs are equivalent except for the default visibility of members (public for structs, private for classes).
It looks like you forgot to make your my_grammar
class derive from the qi::grammar<>
base class that you used for your struct. Thus, the base class initializer in your class constructor implementation will look like nonsense to the compiler.
In short, change your class definition to:
template<typename Iterator>
class my_grammar
: public qi::grammar<Iterator, qi::locals<std::string>, ascii::space_type >
{
public:
my_grammar();
// rules declaration goes here.
};
(Note the added public inheritance).
EDIT (re: linker errror):
With templates, generally the implementation should live in the header file rather than a source (.cpp) file (though there are exceptions). In your header file, the constructor definition syntax should be:
template<typename Iterator>
my_grammar<Iterator>::my_grammar()
: qi::grammar::base_type(start, "start")
{
// write grammar and actions.
}
(difference is the <Iterator>
bit as pointed out by Ken Wayne VanderLinde below).