1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright (c) 2001-2010 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This example is the equivalent to the following flex program:
/*
//[wcf_flex_version
%{
#define ID_WORD 1000
#define ID_EOL 1001
#define ID_CHAR 1002
int c = 0, w = 0, l = 0;
%}
%%
[^ \t\n]+ { return ID_WORD; }
\n { return ID_EOL; }
. { return ID_CHAR; }
%%
bool count(int tok)
{
switch (tok) {
case ID_WORD: ++w; c += yyleng; break;
case ID_EOL: ++l; ++c; break;
case ID_CHAR: ++c; break;
default:
return false;
}
return true;
}
void main()
{
int tok = EOF;
do {
tok = yylex();
if (!count(tok))
break;
} while (EOF != tok);
printf("%d %d %d\n", l, w, c);
}
//]
*/
// Its purpose is to do the word count function of the wc command in UNIX. It
// prints the number of lines, words and characters in a file.
//
// This examples shows how to use the tokenize() function together with a
// simple functor, which gets executed whenever a token got matched in the
// input sequence.
// #define BOOST_SPIRIT_LEXERTL_DEBUG
//[wcf_includes
//]
//[wcf_namespaces
;
//]
///////////////////////////////////////////////////////////////////////////////
// Token id definitions
///////////////////////////////////////////////////////////////////////////////
//[wcf_token_ids
;
//]
//[wcf_token_definition
/*` The template `word_count_tokens` defines three different tokens:
`ID_WORD`, `ID_EOL`, and `ID_CHAR`, representing a word (anything except
a whitespace or a newline), a newline character, and any other character
(`ID_WORD`, `ID_EOL`, and `ID_CHAR` are enum values representing the token
ids, but could be anything else convertible to an integer as well).
The direct base class of any token definition class needs to be the
template `lex::lexer<>`, where the corresponding template parameter (here:
`lex::lexertl::lexer<BaseIterator>`) defines which underlying lexer engine has
to be used to provide the required state machine functionality. In this
example we use the Lexertl based lexer engine as the underlying lexer type.
*/
;
//]
//[wcf_functor
/*` In this example the struct 'counter' is used as a functor counting the
characters, words and lines in the analyzed input sequence by identifying
the matched tokens as passed from the /Spirit.Lex/ library.
*/
;
//]
///////////////////////////////////////////////////////////////////////////////
//[wcf_main
/*` The main function simply loads the given file into memory (as a
`std::string`), instantiates an instance of the token definition template
using the correct iterator type (`word_count_tokens<char const*>`),
and finally calls `lex::tokenize`, passing an instance of the counter function
object. The return value of `lex::tokenize()` will be `true` if the
whole input sequence has been successfully tokenized, and `false` otherwise.
*/
int
//]