regression_syntax_error.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. // Copyright (c) 2009 Jean-Francois Ostiguy
  3. //
  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. #include <boost/detail/lightweight_test.hpp>
  7. #include <boost/config/warning_disable.hpp>
  8. #include <boost/spirit/include/lex_lexertl.hpp>
  9. #include <boost/spirit/include/qi_parse.hpp>
  10. #include <boost/spirit/include/qi_operator.hpp>
  11. #include <boost/spirit/include/qi_char.hpp>
  12. #include <boost/spirit/include/qi_grammar.hpp>
  13. #include <boost/spirit/include/qi_eoi.hpp>
  14. #include <string>
  15. #include <iostream>
  16. #include <sstream>
  17. namespace lex = boost::spirit::lex;
  18. namespace qi = boost::spirit::qi;
  19. namespace mpl = boost::mpl;
  20. template <typename Lexer>
  21. struct my_lexer : lex::lexer<Lexer>
  22. {
  23. my_lexer()
  24. {
  25. delimiter = "BEGIN|END";
  26. identifier = "[a-zA-Z][_\\.a-zA-Z0-9]*";
  27. ws = "[ \\t\\n]+";
  28. real = "([0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?)|([-+]?[1-9]+\\.?([eE][-+]?[0-9]+))";
  29. integer = "[0-9]+";
  30. this->self += ws[lex::_pass = lex::pass_flags::pass_ignore];
  31. this->self += delimiter;
  32. this->self += identifier;
  33. this->self += real;
  34. this->self += integer;
  35. this->self += '=';
  36. this->self += ';';
  37. }
  38. lex::token_def<> ws;
  39. lex::token_def<std::string> identifier;
  40. lex::token_def<int> integer;
  41. lex::token_def<double> real;
  42. lex::token_def<> delimiter;
  43. };
  44. template <typename Iterator>
  45. struct my_grammar : qi::grammar<Iterator>
  46. {
  47. template <typename TokenDef>
  48. my_grammar( TokenDef const& tok )
  49. : my_grammar::base_type(statement)
  50. {
  51. statement
  52. = qi::eoi
  53. | *(delimiter | declaration)
  54. ;
  55. delimiter = tok.delimiter >> tok.identifier;
  56. declaration = tok.identifier >> option >> ';';
  57. option = *(tok.identifier >> '=' >> (tok.real | tok.integer));
  58. }
  59. qi::rule<Iterator> statement, delimiter, declaration, option;
  60. };
  61. typedef lex::lexertl::token<char const*
  62. , mpl::vector<std::string, double, int> > token_type;
  63. typedef lex::lexertl::actor_lexer<token_type> lexer_type;
  64. typedef my_lexer<lexer_type>::iterator_type iterator_type;
  65. int main()
  66. {
  67. std::string test_string ("BEGIN section\n");
  68. // we introduce a syntax error: ";;" instead of ";" as a terminator.
  69. test_string += "Identity;;\n"; // this will make the parser fail
  70. test_string += "END section\n" ;
  71. char const* first = &test_string[0];
  72. char const* last = &first[test_string.size()];
  73. my_lexer<lexer_type> lexer;
  74. my_grammar<iterator_type> grammar(lexer);
  75. BOOST_TEST(lex::tokenize_and_parse(first, last, lexer, grammar));
  76. BOOST_TEST(first != last);
  77. return boost::report_errors();
  78. }