rule_parser_1_1.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*==============================================================================
  2. Copyright (c) 2006 Tobias Schwinger
  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. // This example uses typeof to build a nonrecursive grammar.
  10. // See boost/spirit/include/rule_parser.hpp for details.
  11. //------------------------------------------------------------------------------
  12. #include <string>
  13. #include <iostream>
  14. #include <boost/typeof/typeof.hpp>
  15. #include <boost/spirit/include/classic_core.hpp>
  16. #include <boost/spirit/include/classic_typeof.hpp>
  17. #include <boost/spirit/include/classic_confix.hpp>
  18. #include <boost/spirit/include/classic_typeof.hpp>
  19. #include <boost/spirit/include/classic_rule_parser.hpp>
  20. // It's important to create an own registration group, even if there are no
  21. // manual Typeof registrations like in this case.
  22. #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
  23. namespace my_project { namespace my_module {
  24. using namespace BOOST_SPIRIT_CLASSIC_NS;
  25. // A semantic action.
  26. void echo_uint(unsigned i) { std::cout << "- " << i << std::endl; }
  27. #define BOOST_SPIRIT__NAMESPACE (2,(my_project,my_module))
  28. // C/C++ comment and whitespace skip parser..
  29. BOOST_SPIRIT_RULE_PARSER(skipper,
  30. -,-,-,
  31. ( confix_p("//",*anychar_p,eol_p)
  32. | confix_p("/*",*anychar_p,"*/")
  33. | space_p
  34. )
  35. )
  36. // Parser for unsigned decimal, hexadecimal and binary literals.
  37. BOOST_SPIRIT_RULE_PARSER(uint_literal,
  38. -,-,-,
  39. "0x" >> hex_p[ & echo_uint ]
  40. | "0b" >> bin_p[ & echo_uint ]
  41. | uint_p[ & echo_uint ]
  42. )
  43. // A generic list parser (in some ways similar to Spirit's list_p utility or
  44. // the % operator) with two parameters.
  45. BOOST_SPIRIT_RULE_PARSER(enumeration_parser,
  46. (2,( element_parser, delimiter_parser )),-,-,
  47. element_parser >> *(delimiter_parser >> element_parser)
  48. )
  49. // Parse an optional, comma separated list of uints with explicit post-skip.
  50. BOOST_SPIRIT_RULE_PARSER(line,
  51. -,-,-,
  52. ! enumeration_parser(uint_literal,',')
  53. >> lexeme_d[ !skipper ]
  54. )
  55. bool parse_line(char const * str)
  56. {
  57. return BOOST_SPIRIT_CLASSIC_NS::parse(str,line,skipper).full;
  58. }
  59. #undef BOOST_SPIRIT__NAMESPACE
  60. } } // namespace ::my_project::my_module
  61. int main()
  62. {
  63. std::string str;
  64. while (std::getline(std::cin, str))
  65. {
  66. if (str.empty())
  67. break;
  68. str += '\n';
  69. if (my_project::my_module::parse_line(str.c_str()))
  70. std::cout << "\nOK." << std::endl;
  71. else
  72. std::cout << "\nERROR." << std::endl;
  73. }
  74. return 0;
  75. }