state_switcher.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/detail/lightweight_test.hpp>
  6. #include <boost/spirit/include/lex_lexertl.hpp>
  7. #include <boost/spirit/include/qi_parse.hpp>
  8. #include <boost/spirit/include/qi_operator.hpp>
  9. #include "test_parser.hpp"
  10. ///////////////////////////////////////////////////////////////////////////////
  11. // Token definition
  12. ///////////////////////////////////////////////////////////////////////////////
  13. template <typename Lexer>
  14. struct switch_state_tokens : boost::spirit::lex::lexer<Lexer>
  15. {
  16. switch_state_tokens()
  17. {
  18. // define tokens and associate them with the lexer
  19. identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
  20. this->self = identifier;
  21. // any token definition to be used as the skip parser during parsing
  22. // has to be associated with a separate lexer state (here 'WS')
  23. white_space = "[ \\t\\n]+";
  24. this->self("WS") = white_space;
  25. separators = "[,;]";
  26. this->self("SEP") = separators;
  27. }
  28. boost::spirit::lex::token_def<> identifier, white_space, separators;
  29. };
  30. ///////////////////////////////////////////////////////////////////////////////
  31. int main()
  32. {
  33. using namespace boost::spirit;
  34. using namespace boost::spirit::qi;
  35. using namespace spirit_test;
  36. typedef std::string::iterator base_iterator_type;
  37. typedef boost::spirit::lex::lexertl::token<base_iterator_type> token_type;
  38. typedef boost::spirit::lex::lexertl::lexer<token_type> lexer_type;
  39. {
  40. // the tokens class will be initialized inside the test_parser function
  41. switch_state_tokens<lexer_type> lex;
  42. BOOST_TEST(test_parser("ident", lex.identifier, lex));
  43. BOOST_TEST(!test_parser("ident", set_state("WS") >> lex.identifier, lex));
  44. BOOST_TEST(!test_parser("ident", in_state("WS")[lex.identifier], lex));
  45. BOOST_TEST(test_parser("\t \n", set_state("WS") >> lex.white_space, lex));
  46. BOOST_TEST(test_parser("\t \n", in_state("WS")[lex.white_space], lex));
  47. BOOST_TEST(!test_parser("\t \n", lex.white_space, lex));
  48. }
  49. {
  50. // the tokens class will be initialized inside the test_parser function
  51. switch_state_tokens<lexer_type> lex;
  52. BOOST_TEST(test_parser(",ident", lex.identifier, lex,
  53. in_state("SEP")[lex.separators]));
  54. BOOST_TEST(!test_parser(";ident", set_state("WS") >> lex.identifier,
  55. lex, in_state("SEP")[lex.separators]));
  56. BOOST_TEST(!test_parser(",ident", in_state("WS")[lex.identifier],
  57. lex, in_state("SEP")[lex.separators]));
  58. BOOST_TEST(test_parser(",\t \n", set_state("WS") >> lex.white_space,
  59. lex, in_state("SEP")[lex.separators]));
  60. BOOST_TEST(test_parser(";\t \n", in_state("WS")[lex.white_space],
  61. lex, in_state("SEP")[lex.separators]));
  62. BOOST_TEST(!test_parser(",\t \n", lex.white_space, lex,
  63. in_state("SEP")[lex.separators]));
  64. }
  65. {
  66. // the tokens class will be initialized inside the test_parser function
  67. switch_state_tokens<lexer_type> lex;
  68. BOOST_TEST(test_parser("ident\t \n",
  69. lex.identifier >> set_state("WS") >> lex.white_space, lex));
  70. BOOST_TEST(test_parser("\t \nident",
  71. in_state("WS")[lex.white_space] >> lex.identifier, lex));
  72. }
  73. return boost::report_errors();
  74. }