
Dear Boost Spirit experts, I've been using Spirit for a few weeks and it is one of the most impressive things I've seen for a long time. Thanks to everyone who has made this possible. Its main problem, as far as I can see, is that the error messages are almost entirely incomprehensible. This is not unusual for C++; the compiler (gcc in my case) has a share of the blame too. The result, in my case, is not venturing much beyond the structures used in the examples from the (excellent) documentation, and debugging by trial and error. Anyway, I am trying to write a parser that will: - Use a file_iterator to parse a file. - Skip comments using #-to-end-of-line syntax. - Skip whitespace. - Recognise a simple language. I can do the main part of the parser (the language); the problem is with the comment skipper. I think that using file_iterator might be making it more complicated, though I have also failed to get a char* version to compile. Following the suggestions at http://spirit.sourceforge.net/distrib/spirit_1_8_2/libs/spirit/doc/file_iter... I have written the following test program: #include <string> #include <boost/spirit.hpp> #include <boost/spirit/actor.hpp> #include <boost/spirit/iterator/file_iterator.hpp> using namespace std; using namespace boost::spirit; int main(int argc, char* argv[]) { string fn = argv[1]; typedef file_iterator<char> iterator_t; typedef scanner<iterator_t> scanner_t; typedef rule<scanner_t> rule_t; rule_t skip = comment_p("#") | space_p ; rule_t language = * ch_p('X') ; iterator_t first(fn.c_str()); if (!first) { cout << "Unable to open " << fn << endl; exit(1); } iterator_t last = first.make_end(); parse_info<iterator_t> info = parse(first, last, language, skip); } The errors are attached below. Can anyone spot what I need to change? My feeling is that I need a different type for skip, i.e. not rule_t, and I'm pretty sure that I need a definition for scanner_t that mentions skip. I've tried various combinations and got different, equally verbose and incomprehensible, error messages. I'm using Boost 1.32.0 with gcc 3.3.6 on Debian Linux. Many thanks in advance for any suggestions. Phil. $ g++ -Wall -O -o spirit_test spirit_test.cc /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp: In member function ` typename boost::spirit::parser_result<DerivedT, ScannerT>::type boost::spirit::impl::rule_base<DerivedT, EmbedT, T0, T1, T2>::parse_main(const ScannerT&) const [with ScannerT = boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy>, boost::spirit::match_policy, boost::spirit::action_policy> >, DerivedT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, EmbedT = const boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>&, T0 = main(int, char**)::scanner_t, T1 = boost::spirit::nil_t, T2 = boost::spirit::nil_t]': /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp:171: instantiated from `typename boost::spirit::parser_result<DerivedT, ScannerT>::type boost::spirit::impl::rule_base<DerivedT, EmbedT, T0, T1, T2>::parse(const ScannerT&) const [with ScannerT = boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy>, boost::spirit::match_policy, boost::spirit::action_policy> >, DerivedT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, EmbedT = const boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>&, T0 = main(int, char**)::scanner_t, T1 = boost::spirit::nil_t, T2 = boost::spirit::nil_t]' /usr/include/boost/spirit/core/scanner/impl/skipper.ipp:107: instantiated from `static boost::spirit::parse_info<IteratorT> boost::spirit::impl::phrase_parser<SkipT>::parse(const IteratorT&, const IteratorT&, const ParserT&, const SkipT&) [with IteratorT = boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, ParserT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, SkipT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>]' /usr/include/boost/spirit/core/scanner/impl/skipper.ipp:154: instantiated from `boost::spirit::parse_info<IteratorT> boost::spirit::parse(const IteratorT&, const IteratorT&, const boost::spirit::parser<DerivedT>&, const boost::spirit::parser<SkipT>&) [with IteratorT = main(int, char**)::iterator_t, ParserT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, SkipT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>]' spirit_test.cc:29: instantiated from here /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp:189: error: no matching function for call to ` boost::spirit::impl::abstract_parser<main(int, char**)::scanner_t, boost::spirit::nil_t>::do_parse_virtual(const boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy>, boost::spirit::match_policy, boost::spirit::action_policy> >&)' /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp:213: error: candidates are: typename boost::spirit::match_result<MatchPolicyT, T>::type boost::spirit::impl::abstract_parser<ScannerT, AttrT>::do_parse_virtual(const ScannerT&) const [with ScannerT = main(int, char**)::scanner_t, AttrT = boost::spirit::nil_t] /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp: In member function ` typename boost::spirit::parser_result<DerivedT, ScannerT>::type boost::spirit::impl::rule_base<DerivedT, EmbedT, T0, T1, T2>::parse_main(const ScannerT&) const [with ScannerT = boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::no_skipper_iteration_policy<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy> >, boost::spirit::match_policy, boost::spirit::action_policy> >, DerivedT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, EmbedT = const boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>&, T0 = main(int, char**)::scanner_t, T1 = boost::spirit::nil_t, T2 = boost::spirit::nil_t]': /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp:171: instantiated from `typename boost::spirit::parser_result<DerivedT, ScannerT>::type boost::spirit::impl::rule_base<DerivedT, EmbedT, T0, T1, T2>::parse(const ScannerT&) const [with ScannerT = boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::no_skipper_iteration_policy<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy> >, boost::spirit::match_policy, boost::spirit::action_policy> >, DerivedT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, EmbedT = const boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>&, T0 = main(int, char**)::scanner_t, T1 = boost::spirit::nil_t, T2 = boost::spirit::nil_t]' /usr/include/boost/spirit/core/scanner/impl/skipper.ipp:42: instantiated from `void boost::spirit::impl::skipper_skip(const ST&, const ScannerT&, const boost::spirit::skipper_iteration_policy<BaseT>&) [with ST = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, ScannerT = boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy>, boost::spirit::match_policy, boost::spirit::action_policy> >, BaseT = boost::spirit::iteration_policy]' /usr/include/boost/spirit/core/scanner/skipper.hpp:114: instantiated from `void boost::spirit::skip_parser_iteration_policy<ParserT, BaseT>::skip(const ScannerT&) const [with ScannerT = boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy>, boost::spirit::match_policy, boost::spirit::action_policy> >, ParserT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, BaseT = boost::spirit::iteration_policy]' /usr/include/boost/spirit/core/scanner/impl/skipper.ipp:108: instantiated from `static boost::spirit::parse_info<IteratorT> boost::spirit::impl::phrase_parser<SkipT>::parse(const IteratorT&, const IteratorT&, const ParserT&, const SkipT&) [with IteratorT = boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, ParserT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, SkipT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>]' /usr/include/boost/spirit/core/scanner/impl/skipper.ipp:154: instantiated from `boost::spirit::parse_info<IteratorT> boost::spirit::parse(const IteratorT&, const IteratorT&, const boost::spirit::parser<DerivedT>&, const boost::spirit::parser<SkipT>&) [with IteratorT = main(int, char**)::iterator_t, ParserT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, SkipT = boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>]' spirit_test.cc:29: instantiated from here /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp:189: error: no matching function for call to ` boost::spirit::impl::abstract_parser<main(int, char**)::scanner_t, boost::spirit::nil_t>::do_parse_virtual(const boost::spirit::scanner<boost::spirit::file_iterator<char, boost::spirit::fileiter_impl::std_file_iterator<char> >, boost::spirit::scanner_policies<boost::spirit::no_skipper_iteration_policy<boost::spirit::skip_parser_iteration_policy<boost::spirit::rule<main(int, char**)::scanner_t, boost::spirit::nil_t, boost::spirit::nil_t>, boost::spirit::iteration_policy> >, boost::spirit::match_policy, boost::spirit::action_policy> >&)' /usr/include/boost/spirit/core/non_terminal/impl/rule.ipp:213: error: candidates are: typename boost::spirit::match_result<MatchPolicyT, T>::type boost::spirit::impl::abstract_parser<ScannerT, AttrT>::do_parse_virtual(const ScannerT&) const [with ScannerT = main(int, char**)::scanner_t, AttrT = boost::spirit::nil_t]