nabialek.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*=============================================================================
  2. Copyright (c) 2003 Sam Nabialek
  3. Copyright (c) 2001-2010 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. ///////////////////////////////////////////////////////////////////////////////
  8. //
  9. // The Nabialek trick.
  10. //
  11. // [ Sam Nabialek; Somewhere, sometime in 2003... ] spirit1
  12. // [ JDG November 17, 2009 ] spirit2
  13. // [ JDG January 10, 2010 ] Updated to use rule pointers
  14. // for efficiency.
  15. //
  16. ///////////////////////////////////////////////////////////////////////////////
  17. #include <boost/config/warning_disable.hpp>
  18. #include <boost/spirit/include/qi.hpp>
  19. #include <boost/spirit/include/phoenix_operator.hpp>
  20. #include <iostream>
  21. #include <string>
  22. namespace client
  23. {
  24. namespace qi = boost::spirit::qi;
  25. namespace ascii = boost::spirit::ascii;
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // Our nabialek_trick grammar
  28. ///////////////////////////////////////////////////////////////////////////////
  29. template <typename Iterator>
  30. struct nabialek_trick : qi::grammar<
  31. Iterator, ascii::space_type, qi::locals<qi::rule<Iterator, ascii::space_type>*> >
  32. {
  33. nabialek_trick() : nabialek_trick::base_type(start)
  34. {
  35. using ascii::alnum;
  36. using qi::lexeme;
  37. using qi::lazy;
  38. using qi::_a;
  39. using qi::_1;
  40. id = lexeme[*(ascii::alnum | '_')];
  41. one = id;
  42. two = id >> ',' >> id;
  43. keyword.add
  44. ("one", &one)
  45. ("two", &two)
  46. ;
  47. start = *(keyword[_a = _1] >> lazy(*_a));
  48. }
  49. qi::rule<Iterator, ascii::space_type> id, one, two;
  50. qi::rule<Iterator, ascii::space_type, qi::locals<qi::rule<Iterator, ascii::space_type>*> > start;
  51. qi::symbols<char, qi::rule<Iterator, ascii::space_type>*> keyword;
  52. };
  53. }
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // Main program
  56. ///////////////////////////////////////////////////////////////////////////////
  57. int
  58. main()
  59. {
  60. using boost::spirit::ascii::space;
  61. typedef std::string::const_iterator iterator_type;
  62. typedef client::nabialek_trick<iterator_type> nabialek_trick;
  63. nabialek_trick g; // Our grammar
  64. std::string str = "one only\none again\ntwo first,second";
  65. std::string::const_iterator iter = str.begin();
  66. std::string::const_iterator end = str.end();
  67. bool r = phrase_parse(iter, end, g, space);
  68. if (r && iter == end)
  69. {
  70. std::cout << "-------------------------\n";
  71. std::cout << "Parsing succeeded\n";
  72. std::cout << "-------------------------\n";
  73. }
  74. else
  75. {
  76. std::string rest(iter, end);
  77. std::cout << "-------------------------\n";
  78. std::cout << "Parsing failed\n";
  79. std::cout << "stopped at: \": " << rest << "\"\n";
  80. std::cout << "-------------------------\n";
  81. }
  82. return 0;
  83. }