error_reporting.cpp 3.4 KB

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