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
7#include <boost/spirit/include/lex_lexertl.hpp>
8
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
15#include <boost/core/lightweight_test.hpp>
16#include <boost/phoenix/operator/self.hpp>
17#include <string>
18#include <iostream>
19#include <sstream>
20
21namespace lex = boost::spirit::lex;
22namespace qi = boost::spirit::qi;
23namespace mpl = boost::mpl;
24
25template <typename Lexer>
26struct my_lexer : lex::lexer<Lexer>
27{
28 my_lexer()
29 {
30 delimiter = "BEGIN|END";
31 identifier = "[a-zA-Z][_\\.a-zA-Z0-9]*";
32 ws = "[ \\t\\n]+";
33 real = "([0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?)|([-+]?[1-9]+\\.?([eE][-+]?[0-9]+))";
34 integer = "[0-9]+";
35
36 this->self += ws[lex::_pass = lex::pass_flags::pass_ignore];
37 this->self += delimiter;
38 this->self += identifier;
39 this->self += real;
40 this->self += integer;
41 this->self += '=';
42 this->self += ';';
43 }
44
45 lex::token_def<> ws;
46 lex::token_def<std::string> identifier;
47 lex::token_def<int> integer;
48 lex::token_def<double> real;
49 lex::token_def<> delimiter;
50};
51
52template <typename Iterator>
53struct my_grammar : qi::grammar<Iterator>
54{
55 template <typename TokenDef>
56 my_grammar( TokenDef const& tok )
57 : my_grammar::base_type(statement)
58 {
59 statement
60 = qi::eoi
61 | *(delimiter | declaration)
62 ;
63
64 delimiter = tok.delimiter >> tok.identifier;
65 declaration = tok.identifier >> option >> ';';
66 option = *(tok.identifier >> '=' >> (tok.real | tok.integer));
67 }
68
69 qi::rule<Iterator> statement, delimiter, declaration, option;
70};
71
72typedef lex::lexertl::token<char const*
73 , mpl::vector<std::string, double, int> > token_type;
74typedef lex::lexertl::actor_lexer<token_type> lexer_type;
75typedef my_lexer<lexer_type>::iterator_type iterator_type;
76
77int main()
78{
79 std::string test_string ("BEGIN section\n");
80 // we introduce a syntax error: ";;" instead of ";" as a terminator.
81 test_string += "Identity;;\n"; // this will make the parser fail
82 test_string += "END section\n" ;
83
84 char const* first = &test_string[0];
85 char const* last = &first[test_string.size()];
86
87 my_lexer<lexer_type> lexer;
88 my_grammar<iterator_type> grammar(lexer);
89
90 BOOST_TEST(lex::tokenize_and_parse(first, last, lexer, grammar));
91 BOOST_TEST(first != last);
92
93 return boost::report_errors();
94}
95
96
97

source code of boost/libs/spirit/test/lex/regression_syntax_error.cpp