1// Copyright (c) 2001-2010 Hartmut Kaiser
2// Copyright (c) 2010 Mathias Gaunard
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// This test makes sure that the BOL state (begin of line) is properly reset
8// if a token matched at the beginning of a line is discarded using
9// lex::pass_fail.
10
11// #define BOOST_SPIRIT_LEXERTL_DEBUG 1
12
13#include <boost/config/warning_disable.hpp>
14#include <boost/detail/lightweight_test.hpp>
15
16#include <boost/spirit/include/support_multi_pass.hpp>
17#include <boost/spirit/include/classic_position_iterator.hpp>
18#include <boost/spirit/include/lex_lexertl.hpp>
19
20#include <boost/spirit/include/phoenix.hpp>
21
22namespace spirit = boost::spirit;
23namespace lex = spirit::lex;
24namespace phoenix = boost::phoenix;
25
26typedef spirit::classic::position_iterator2<
27 spirit::multi_pass<std::istreambuf_iterator<char> >
28> file_iterator;
29
30inline file_iterator
31make_file_iterator(std::istream& input, const std::string& filename)
32{
33 return file_iterator(
34 spirit::make_default_multi_pass(
35 i: std::istreambuf_iterator<char>(input)),
36 spirit::multi_pass<std::istreambuf_iterator<char> >(),
37 filename);
38}
39
40typedef lex::lexertl::token<file_iterator> token_type;
41
42struct lexer
43 : lex::lexer<lex::lexertl::actor_lexer<token_type> >
44{
45 lexer() : word("^[a-zA-Z0-9]+$", 1)
46 {
47 self = word [
48 lex::_state = "O"
49 ]
50 | lex::token_def<>("!.*$") [
51 lex::_state = "O"
52 , lex::_pass = lex::pass_flags::pass_ignore
53 ]
54 | lex::token_def<>('\n', 2) [
55 lex::_state = "O"
56 ]
57 ;
58
59 self("O") =
60 lex::token_def<>(".") [
61 lex::_state = "INITIAL"
62 , lex::_pass = lex::pass_flags::pass_fail
63 ]
64 ;
65 }
66
67 lex::token_def<> word;
68};
69
70typedef lexer::iterator_type token_iterator;
71
72int main()
73{
74 std::stringstream ss;
75 ss << "!foo\nbar\n!baz";
76
77 file_iterator begin = make_file_iterator(input&: ss, filename: "SS");
78 file_iterator end;
79
80 lexer l;
81 token_iterator begin2 = l.begin(first&: begin, last: end);
82 token_iterator end2 = l.end();
83
84 std::size_t test_data[] = { 2, 1, 2 };
85 std::size_t const test_data_size = sizeof(test_data)/sizeof(test_data[0]);
86
87 token_iterator it = begin2;
88 std::size_t i = 0;
89 for (/**/; it != end2 && i < test_data_size; ++it, ++i)
90 {
91 BOOST_TEST(it->id() == test_data[i]);
92 }
93 BOOST_TEST(it == end2);
94 BOOST_TEST(i == test_data_size);
95
96 return boost::report_errors();
97}
98

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