Compiling a Simple Grammar of a Forced Spirit

I'm having trouble preparing a small boost :: spirit grammar. This is a small part of the larger grammar that I'm having problems with, and I'm trying to check the smaller parts to find my problem. Basically, what this grammar should do is to analyze the double meaning that any number of leading / finite spaces has. However, when I try to compile, I get a whole list of problems that I don’t understand. Any help is appreciated! Code: grammar.h

#ifndef GRAMMAR_H #define GRAMMAR_H #include <boost/spirit/include/qi.hpp> template <typename Iterator> struct point_double_grammar : boost::spirit::qi::grammar<Iterator, double()> { /** * Constructor used to create the grammar. * @param is_point boolean indicating if the point is used as decimal. * @author Luc Kleeven **/ point_double_grammar() : point_double_grammar::base_type(d) { d = *boost::spirit::qi::lit(' ') >> boost::spirit::qi::double_ >> *boost::spirit::qi::lit(' '); } boost::spirit::qi::rule<Iterator, double()> d; }; #endif // GRAMMAR_H 

main.cpp

 #include "grammar.h" int main(int argc, char *argv[]) { point_double_grammar<std::string::iterator> point_grammar(); bool result = false; double d = 0.0; std::string p1 = "575040.3400"; std::string p2 = "117380.1200"; std::string p3 = "-001.22916765"; std::string p4 = "063.39171738"; std::string p5 = "2.5"; std::string::iterator it; std::string::iterator last; it = p1.begin(); last = p1.end(); result = (boost::spirit::qi::parse(it, last, point_grammar, d) && it == last); if(result) { std::cout << p1 << " == " << d << std::endl; } else { std::cout << "Parsing failed!" << std::endl; } it = p2.begin(); last = p2.end(); result = (boost::spirit::qi::parse(it, last, point_grammar, d) && it == last); if(result) { std::cout << p2 << " == " << d << std::endl; } else { std::cout << "Parsing failed!" << std::endl; } it = p3.begin(); last = p3.end(); result = (boost::spirit::qi::parse(it, last, point_grammar, d) && it == last); if(result) { std::cout << p3 << " == " << d << std::endl; } else { std::cout << "Parsing failed!" << std::endl; } it = p4.begin(); last = p4.end(); result = (boost::spirit::qi::parse(it, last, point_grammar, d) && it == last); if(result) { std::cout << p4 << " == " << d << std::endl; } else { std::cout << "Parsing failed!" << std::endl; } it = p5.begin(); last = p5.end(); result = (boost::spirit::qi::parse(it, last, point_grammar, d) && it == last); if(result) { std::cout << p5 << " == " << d << std::endl; } else { std::cout << "Parsing failed!" << std::endl; } return EXIT_SUCCESS; } 

When I try to compile, I get the following errors:

 In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/detail/parse_auto.hpp:14:0, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/auto.hpp:16, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi.hpp:15, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/include/qi.hpp:16, from ../test/grammar.h:4, from ../test/main.cpp:1: c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/parse.hpp: In function 'bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Expr = point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >(), Attr = double]': ../test/main.cpp:20:63: instantiated from here c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/parse.hpp:83:9: error: no matching function for call to 'assertion_failed(mpl_::failed************ (boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Expr = point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >(), Attr = double]::error_invalid_expression::************)(point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > > (*)()))' c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/parse.hpp:83:9: note: candidate is: c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/mpl/assert.hpp:79:48: note: template<bool C> int mpl_::assertion_failed(typename mpl_::assert<C>::type) In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/proto/detail/expr.hpp:6:0, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/proto/expr.hpp:120, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/proto/core.hpp:17, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/proto/proto.hpp:12, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/support/meta_compiler.hpp:19, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/meta_compiler.hpp:14, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/action/action.hpp:14, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/action.hpp:14, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi.hpp:14, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/include/qi.hpp:16, from ../test/grammar.h:4, from ../test/main.cpp:1: c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/proto/detail/preprocessed/expr.hpp: At global scope: c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/proto/detail/preprocessed/expr.hpp: In instantiation of 'boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >()>, 0l>': c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/utility/enable_if.hpp:59:10: instantiated from 'boost::disable_if<boost::proto::is_expr<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >()>, 0l>, void>, void>' c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/support/meta_compiler.hpp:212:16: instantiated from 'boost::spirit::result_of::compile<boost::spirit::qi::domain, point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >(), boost::spirit::unused_type, void>' c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/parse.hpp:86:82: instantiated from 'bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Expr = point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >(), Attr = double]' ../test/main.cpp:20:63: instantiated from here c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/proto/detail/preprocessed/expr.hpp:50:49: error: field 'boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >()>, 0l>::child0' invalidly declared function type In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/detail/parse_auto.hpp:14:0, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/auto.hpp:16, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi.hpp:15, from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/include/qi.hpp:16, from ../test/grammar.h:4, from ../test/main.cpp:1: c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/parse.hpp: In function 'bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Expr = point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >(), Attr = double]': ../test/main.cpp:20:63: instantiated from here c:\mingw\bin\../lib/gcc/mingw32/4.6.1/../../../../include/boost/spirit/home/qi/parse.hpp:86:82: error: request for member 'parse' in 'boost::spirit::compile [with Domain = boost::spirit::qi::domain, Expr = point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >(), typename boost::spirit::result_of::compile<Domain, Expr, boost::spirit::unused_type>::type = point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > > (&)()]((* & expr))', which is of non-class type 'point_double_grammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >()' 

Please note that I am compiling using boost 1.48.0 and mingw 4.6.1 on a Windows 7 machine.

+4
source share
2 answers

Change this line:

 point_double_grammar<std::string::iterator> point_grammar(); 

To:

 point_double_grammar<std::string::iterator> point_grammar; 

You declared a function with no arguments returning a grammar. Instead, you want to instantiate a grammar.

+7
source

Chart has already answered your question, you must accept this answer, of course.

I wanted to share a few other things, it may be useful to you.

  • as I said: format your code (code for people)
  • Try using a loop instead of duplicating code. You did not make a list of doubles. You took apart one double, 5 times
  • Avoid C-isms (declare and initialize at the top?)
  • Look at Qi Skippers: you manually β€œignored” the spaces. Qi has skippers for this purpose (see Qi :: phrase_parse in the example below).
  • Consider using Boost Karma to generate output. At the very least, use <iomanip> to control the output format (see below std::setprecision ).

Here is a complete example

 #include <boost/spirit/include/qi.hpp> #include <iomanip> namespace qi = boost::spirit::qi; template <typename Iterator, typename Skipper> struct point_double_grammar : qi::grammar<Iterator, double(), Skipper> { point_double_grammar() : point_double_grammar::base_type(d) { d = qi::double_; } qi::rule<Iterator, double(), Skipper> d; }; static const char *const testcases[] = { "575040.3400", "117380.1200", "-001.22916765", "063.39171738", "2.5", NULL }; int main() { typedef std::string::const_iterator It; point_double_grammar<It, qi::space_type> point_grammar; for(const char* const* it=testcases; *it; ++it) { const std::string input(*it); It it = input.begin(), last = input.end(); double d = 0.0; bool result = (qi::phrase_parse(it, last, point_grammar, qi::space, d) && it == last); if(result) std::cout << input << " == " << std::setprecision(10) << d << std::endl; else std::cerr << "Parsing failed!" << std::endl; } } 

With C ++ 11 you will even write:

 for (const std::string input : { "575040.3400", "117380.1200", "-001.22916765", "063.39171738", "2.5" }) { auto it = input.begin(), last = input.end(); 

etc .. For recording output:

 575040.3400 == 575040.34 117380.1200 == 117380.12 -001.22916765 == -1.22916765 063.39171738 == 63.39171738 2.5 == 2.5 

Without std::setprecision(10) output will be, for example. 575040.3400 == 575040 for the first line. Consider using Boost Karma to generate output.

+3
source

Source: https://habr.com/ru/post/1398047/


All Articles