I would like to split up my rules (productions) into separate classes. I can't find any example in Boost::Spirit::Qi for doing this.
The Boost examples all show the rules in one grammar class.
Here is my grammar:
<start> ::= @ ( <event_bool_no_param> )
<event_bool_no_param> ::= RAMPING_COMPLETED | STATE_TIMEOUT
Here is my grammar class:
template <typename Iterator, typename Skipper>
struct Event_Grammar
: boost::spirit::qi::grammar<Iterator, Skipper>
{
Event_Grammar() : Event_Grammar::base_type(start)
{
using boost::spirit::ascii::char_;
using boost::spirit::qi::eps;
start =
(
char_('@') >> char_('(') >> Event_Bool_No_Param<Iterator>() >> char_(')')
)
;
}
boost::spirit::qi::rule<Iterator, Skipper> start;
};
Here is my other grammar class:
template <typename Iterator>
struct Event_Bool_No_Param
: qi::grammar<Iterator>
{
Event_Bool_No_Param ()
: Event_Bool_No_Param::base_type(start)
{
using qi::lexeme;
using qi::lit;
start =
lit("STATE_TIMEOUT") | lit("RAMPING_COMPLETED") | lit("PASSIVE_MEAS_COMPLETED")
;
}
qi::rule<Iterator> start;
};
I'm getting an unhandled exception error with the text "@ ( STATE_TIMEOUT )
".
Here's the top (recent) stack trace:
Event_Grammar.exe!boost::spirit::qi::sequence_base<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >::parse_impl<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> >,boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> >,boost::spirit::unused_type>(std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & first, const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & last, boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > & context, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> > & skipper, boost::spirit::unused_type & attr_, boost::mpl::bool_<0> __formal) Line 88 + 0x55 bytes C++
Event_Grammar.exe!boost::spirit::qi::sequence_base<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >::parse<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> >,boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> >,boost::spirit::unused_type>(std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & first, const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & last, boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > & context, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> > & skipper, boost::spirit::unused_type & attr_) Line 125 C++
Event_Grammar.exe!boost::spirit::qi::detail::parser_binder<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >,boost::mpl::bool_<0> >::call<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> >,boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > >(std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & first, const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & last, boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > & context, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> > & skipper, boost::mpl::bool_<0> __formal) Line 44 C++
Here's the code location where the exception takes place, function_template.hpp#761 :
result_type operator()(BOOST_FUNCTION_PARMS) const
{
if (this->empty())
boost::throw_exception(bad_function_call());
return get_vtable()->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
}
So, my questions are:
- Do all rules need to be in the single grammar class?
- How do I reference a grammar class in a rule?
- Where is my mistake in my classes above?
I am using:
- Boost 1.57.0
- Visual Studio 2010
- Windows 7