• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()95 main()
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