1 /*============================================================================= 2 Copyright (c) 2003 Pavel Baranov 3 http://spirit.sourceforge.net/ 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 /////////////////////////////////////////////////////////////////////////////// 10 // 11 // An alternate error-handling scheme where the parser will 12 // complain (but not stop) if input doesn't match. 13 // 14 // [ Pavel Baranov 8/27/2003 ] 15 // 16 /////////////////////////////////////////////////////////////////////////////// 17 #include <boost/spirit/include/classic_core.hpp> 18 #include <boost/spirit/include/classic_functor_parser.hpp> 19 #include <iostream> 20 #include <string> 21 22 /////////////////////////////////////////////////////////////////////////////// 23 using namespace std; 24 using namespace BOOST_SPIRIT_CLASSIC_NS; 25 26 static short errcount = 0; 27 28 /////////////////////////////////////////////////////////////////////////////// 29 // 30 // Error reporting parser 31 // 32 /////////////////////////////////////////////////////////////////////////////// 33 struct error_report_parser { 34 error_report_parsererror_report_parser35 error_report_parser(const char *msg) : _msg(msg) {} 36 37 typedef nil_t result_t; 38 39 template <typename ScannerT> operator ()error_report_parser40 int operator()(ScannerT const& scan, result_t& /*result*/) const 41 { 42 errcount++; 43 cerr << _msg << endl; 44 return 0; 45 } 46 47 private: 48 string _msg; 49 }; 50 51 typedef functor_parser<error_report_parser> error_report_p; 52 53 /////////////////////////////////////////////////////////////////////////////// 54 // 55 // My grammar 56 // 57 /////////////////////////////////////////////////////////////////////////////// 58 struct my_grammar : public grammar<my_grammar> 59 { 60 static error_report_p error_missing_semicolon; 61 static error_report_p error_missing_letter; 62 63 template <typename ScannerT> 64 struct definition 65 { definitionmy_grammar::definition66 definition(my_grammar const& self) : 67 SEMICOLON(';') 68 { 69 my_rule 70 = *(eps_p(alpha_p|SEMICOLON) >> 71 (alpha_p|error_missing_letter) >> 72 (SEMICOLON|error_missing_semicolon)) 73 ; 74 } 75 76 chlit<> 77 SEMICOLON; 78 79 rule<ScannerT> my_rule; 80 81 rule<ScannerT> const& startmy_grammar::definition82 start() const { return my_rule; } 83 }; 84 }; 85 86 error_report_p my_grammar::error_missing_semicolon("missing semicolon"); 87 error_report_p my_grammar::error_missing_letter("missing letter"); 88 89 /////////////////////////////////////////////////////////////////////////////// 90 // 91 // Main program 92 // 93 /////////////////////////////////////////////////////////////////////////////// 94 int main()95main() 96 { 97 cout << "/////////////////////////////////////////////////////////\n\n"; 98 cout << " Error handling demo\n\n"; 99 cout << " The parser expects a sequence of letter/semicolon pairs\n"; 100 cout << " and will complain (but not stop) if input doesn't match.\n\n"; 101 cout << "/////////////////////////////////////////////////////////\n\n"; 102 103 my_grammar g; 104 105 string str( "a;;b;cd;e;fg;" ); 106 cout << "input: " << str << "\n\n"; 107 108 if( parse(str.c_str(), g, space_p).full && !errcount ) 109 cout << "\nparsing succeeded\n"; 110 else 111 cout << "\nparsing failed\n"; 112 113 return 0; 114 } 115