Added Wave V1.1.14 to the Boost CVS.
[SVN r27458]
96
.gitattributes
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
* text=auto !eol svneol=native#text/plain
|
||||
*.gitattributes text svneol=native#text/plain
|
||||
|
||||
# Scriptish formats
|
||||
*.bat text svneol=native#text/plain
|
||||
*.bsh text svneol=native#text/x-beanshell
|
||||
*.cgi text svneol=native#text/plain
|
||||
*.cmd text svneol=native#text/plain
|
||||
*.js text svneol=native#text/javascript
|
||||
*.php text svneol=native#text/x-php
|
||||
*.pl text svneol=native#text/x-perl
|
||||
*.pm text svneol=native#text/x-perl
|
||||
*.py text svneol=native#text/x-python
|
||||
*.sh eol=lf svneol=LF#text/x-sh
|
||||
configure eol=lf svneol=LF#text/x-sh
|
||||
|
||||
# Image formats
|
||||
*.bmp binary svneol=unset#image/bmp
|
||||
*.gif binary svneol=unset#image/gif
|
||||
*.ico binary svneol=unset#image/ico
|
||||
*.jpeg binary svneol=unset#image/jpeg
|
||||
*.jpg binary svneol=unset#image/jpeg
|
||||
*.png binary svneol=unset#image/png
|
||||
*.tif binary svneol=unset#image/tiff
|
||||
*.tiff binary svneol=unset#image/tiff
|
||||
*.svg text svneol=native#image/svg%2Bxml
|
||||
|
||||
# Data formats
|
||||
*.pdf binary svneol=unset#application/pdf
|
||||
*.avi binary svneol=unset#video/avi
|
||||
*.doc binary svneol=unset#application/msword
|
||||
*.dsp text svneol=crlf#text/plain
|
||||
*.dsw text svneol=crlf#text/plain
|
||||
*.eps binary svneol=unset#application/postscript
|
||||
*.gz binary svneol=unset#application/gzip
|
||||
*.mov binary svneol=unset#video/quicktime
|
||||
*.mp3 binary svneol=unset#audio/mpeg
|
||||
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
|
||||
*.ps binary svneol=unset#application/postscript
|
||||
*.psd binary svneol=unset#application/photoshop
|
||||
*.rdf binary svneol=unset#text/rdf
|
||||
*.rss text svneol=unset#text/xml
|
||||
*.rtf binary svneol=unset#text/rtf
|
||||
*.sln text svneol=native#text/plain
|
||||
*.swf binary svneol=unset#application/x-shockwave-flash
|
||||
*.tgz binary svneol=unset#application/gzip
|
||||
*.vcproj text svneol=native#text/xml
|
||||
*.vcxproj text svneol=native#text/xml
|
||||
*.vsprops text svneol=native#text/xml
|
||||
*.wav binary svneol=unset#audio/wav
|
||||
*.xls binary svneol=unset#application/vnd.ms-excel
|
||||
*.zip binary svneol=unset#application/zip
|
||||
|
||||
# Text formats
|
||||
.htaccess text svneol=native#text/plain
|
||||
*.bbk text svneol=native#text/xml
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
*.log text svneol=native#text/plain
|
||||
*.mak text svneol=native#text/plain
|
||||
*.qbk text svneol=native#text/plain
|
||||
*.rst text svneol=native#text/plain
|
||||
*.sql text svneol=native#text/x-sql
|
||||
*.txt text svneol=native#text/plain
|
||||
*.xhtml text svneol=native#text/xhtml%2Bxml
|
||||
*.xml text svneol=native#text/xml
|
||||
*.xsd text svneol=native#text/xml
|
||||
*.xsl text svneol=native#text/xml
|
||||
*.xslt text svneol=native#text/xml
|
||||
*.xul text svneol=native#text/xul
|
||||
*.yml text svneol=native#text/plain
|
||||
boost-no-inspect text svneol=native#text/plain
|
||||
CHANGES text svneol=native#text/plain
|
||||
COPYING text svneol=native#text/plain
|
||||
INSTALL text svneol=native#text/plain
|
||||
Jamfile text svneol=native#text/plain
|
||||
Jamroot text svneol=native#text/plain
|
||||
Jamfile.v2 text svneol=native#text/plain
|
||||
Jamrules text svneol=native#text/plain
|
||||
Makefile* text svneol=native#text/plain
|
||||
README text svneol=native#text/plain
|
||||
TODO text svneol=native#text/plain
|
||||
|
||||
# Code formats
|
||||
*.c text svneol=native#text/plain
|
||||
*.cpp text svneol=native#text/plain
|
||||
*.h text svneol=native#text/plain
|
||||
*.hpp text svneol=native#text/plain
|
||||
*.ipp text svneol=native#text/plain
|
||||
*.tpp text svneol=native#text/plain
|
||||
*.jam text svneol=native#text/plain
|
||||
*.java text svneol=native#text/plain
|
||||
64
build/Jamfile
Normal file
@@ -0,0 +1,64 @@
|
||||
# Wave: A Standard compliant C++ preprocessor library
|
||||
#
|
||||
# Boost Wave Library Build Jamfile
|
||||
#
|
||||
# http://spirit.sourceforge.net/
|
||||
#
|
||||
# Copyright (c) 2001-2005 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)
|
||||
|
||||
subproject libs/wave/build ;
|
||||
|
||||
SOURCES = instantiate_cpp_exprgrammar
|
||||
instantiate_cpp_grammar
|
||||
instantiate_cpp_literalgrammars
|
||||
instantiate_defined_grammar
|
||||
instantiate_predef_macros
|
||||
instantiate_re2c_lexer
|
||||
instantiate_re2c_lexer_string
|
||||
cpplexer/re2clex/aq
|
||||
cpplexer/re2clex/cpp.re
|
||||
;
|
||||
|
||||
lib boost_wave
|
||||
: ../src/$(SOURCES).cpp
|
||||
: # build requirements
|
||||
[ common-names ] # magic for install and auto-link features
|
||||
<include>$(BOOST_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<vc-7_1><*><rtti>off # workaround for compiler bug
|
||||
<no-warn>cpp.re.cpp
|
||||
: debug release # build variants
|
||||
;
|
||||
|
||||
#dll boost_wave
|
||||
# : ../src/$(SOURCES).cpp
|
||||
# : # build requirements
|
||||
# [ common-names ] # magic for install and auto-link features
|
||||
# <define>BOOST_WAVE_DYN_LINK=1 # tell source we're building dll's
|
||||
# <runtime-link>dynamic # build only for dynamic runtimes
|
||||
# <include>$(BOOST_ROOT)
|
||||
# <sysinclude>$(BOOST_ROOT)
|
||||
# : debug release # build variants
|
||||
# ;
|
||||
|
||||
install wave lib
|
||||
: <lib>boost_wave
|
||||
# <dll>boost_wave
|
||||
;
|
||||
|
||||
stage stage/lib : <lib>boost_wave # <dll>boost_wave
|
||||
:
|
||||
# copy to a path rooted at BOOST_ROOT:
|
||||
<locate>$(BOOST_ROOT)
|
||||
# make sure the names of the libraries are correctly named:
|
||||
[ common-names ]
|
||||
# add this target to the "stage" and "all" pseudo-targets:
|
||||
<target>stage
|
||||
<target>all
|
||||
:
|
||||
debug release
|
||||
;
|
||||
|
||||
# end
|
||||
33
build/Jamfile.v2
Normal file
@@ -0,0 +1,33 @@
|
||||
# Wave: A Standard compliant C++ preprocessor library
|
||||
#
|
||||
# Boost Wave Library Build Jamfile
|
||||
#
|
||||
# http://spirit.sourceforge.net/
|
||||
#
|
||||
# Copyright (c) 2001-2005 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)
|
||||
|
||||
project boost/wave
|
||||
: source-location ../src
|
||||
;
|
||||
|
||||
SOURCES = instantiate_cpp_exprgrammar
|
||||
instantiate_cpp_grammar
|
||||
instantiate_cpp_literalgrammars
|
||||
instantiate_defined_grammar
|
||||
instantiate_predef_macros
|
||||
instantiate_re2c_lexer
|
||||
instantiate_re2c_lexer_string
|
||||
cpplexer/re2clex/aq
|
||||
cpplexer/re2clex/cpp.re
|
||||
;
|
||||
|
||||
lib boost_wave
|
||||
: $(SOURCES).cpp
|
||||
$(BOOST_ROOT)/libs/filesystem/build//boost_filesystem
|
||||
:
|
||||
<toolset>msvc-7.1:<rtti>off # workaround for compiler bug
|
||||
# Not supported by V2
|
||||
# <no-warn>cpp.re.cpp
|
||||
;
|
||||
86
doc/acknowledgements.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Acknowledgements</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
</head>
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Acknowledgements</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="wave_driver.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="references.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Special thanks to:</p>
|
||||
<blockquote>
|
||||
<p> <b>Paul Mensonides</b> for his invaluable help while developing the macro
|
||||
expansion engine and his insightful tips. He developed the recursive macro
|
||||
expansion algorithm implemented herein and also contributed most of the small
|
||||
testcases used for testing the correctness of the macro expansion.</p>
|
||||
<p><b>Dan Nuffer</b>, who wrote the initial Re2C based C++ lexer and the Slex
|
||||
(Spirit Lex) scanner generator sample.</p>
|
||||
<p><b>Martin Wille</b> for helping with the port to Linux, testing on Linux and for contributing
|
||||
the automated test scripts.</p>
|
||||
<p><b>Vladimir Prus</b> for helping with the command line and config file options
|
||||
analysis fro the <tt>Wave</tt> driver executable.</p>
|
||||
<p><b>Juan Carlos Arevalo-Baeza</b>, who wrote the Spirit cpp_lexer sample,
|
||||
from which are taken some ideas.</p>
|
||||
<p> <strong>Andrei Alexandrescu</strong> for allowing to use his flex_string class,
|
||||
a policy based std::basic_string<> compatible string implementation.</p>
|
||||
<p><strong>Reece Dunn</strong>, <strong>Vesa Karvonen</strong>, <strong>Faisal Vali</strong>, <strong>Porter Schermerhorn</strong> and <strong>Daniel Fontijne</strong> for
|
||||
reporting several problems and bugs.</p>
|
||||
<p><strong>Tarmo Pikaro</strong> for reporting several bug while compiling specific
|
||||
headers from the Microsoft Windows SDK.</p>
|
||||
<p><strong>Rob Stewart</strong> helped a lot with proof reading the documentation. </p>
|
||||
</blockquote>
|
||||
<p>and last but not least </p>
|
||||
<blockquote>
|
||||
<p><b>Joel de Guzman</b> for nudging me into this adventure and for his work
|
||||
on the <tt>Spirit</tt> parser framework, without which the <tt>Wave</tt> library
|
||||
wouldn't have been possible.</p>
|
||||
</blockquote>
|
||||
<p>The <tt>Wave</tt> library uses the following <tt>Boost</tt> <a href="references.html#boost">[8]</a>
|
||||
libraries:</p>
|
||||
<blockquote>
|
||||
<p><b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"></b> Boost
|
||||
Spirit (LL parser framework that represents parsers directly as EBNF grammars
|
||||
in inlined C++)<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"></b> Boost
|
||||
Iterator Adaptor Library (Adapt a base type into a standard conforming iterator)<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"></b> Boost
|
||||
Filesystem Library (Portable paths, iteration over directories, and other
|
||||
useful filesystem operations)<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"></b> Boost Program
|
||||
options and arguments library</p>
|
||||
</blockquote>
|
||||
<p>and other small parts of different <tt>Boost</tt> libraries. </p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="wave_driver.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="references.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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)
|
||||
</font> </p>
|
||||
<span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Monday, January 17, 2005 16:39<!-- #EndDate -->
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
||||
441
doc/class_reference_context.html
Normal file
@@ -0,0 +1,441 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Context Object</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
</head>
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Context Object</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="quickstart.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p><a href="class_reference_context.html#introduction">Introduction</a><br>
|
||||
<a href="class_reference_context.html#header_synopsis">Header 'wave/context.hpp' synopsis</a><br>
|
||||
<a href="class_reference_context.html#public_typedefs">Public Typedefs</a><br>
|
||||
<a href="class_reference_context.html#template_parameters">Template parameters</a><br>
|
||||
<a href="class_reference_context.html#member_functions">Member functions</a></p>
|
||||
</blockquote>
|
||||
<h2><b><a name="introduction"></a>Introduction</b></h2>
|
||||
<p>The <tt>boost::wave::context<></tt> object is the main user visible object of
|
||||
the <tt>Wave</tt> library. It exists to generate the pair of iterators, which
|
||||
while dereferenced return the preprocessed tokens. Additionally it is used
|
||||
to control other aspects of the preprocessing, such as </p>
|
||||
<blockquote>
|
||||
<p><STRONG><IMG id="IMG1" height="13" src="theme/bullet.gif" width="13"></STRONG> include
|
||||
search pathes, which define, where to search for files to be included with
|
||||
<tt>#include <...></tt> and <tt>#include "..."</tt> directives<br>
|
||||
<STRONG><img src="theme/bullet.gif" width="13" height="13"> </STRONG>which
|
||||
macros to predefine and which of the predefined macros to undefine<br>
|
||||
<STRONG><img src="theme/bullet.gif" width="13" height="13"> </STRONG>several
|
||||
other options as for instance to control, whether to enable several extensions
|
||||
to the C++ Standard (as for instance variadics and placemarkers) or not.</p>
|
||||
</blockquote>
|
||||
<h2><b><a name="header_synopsis"></a>Header <a href="http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost/boost/wave/cpp_context.hpp?view=markup">wave/cpp_context.hpp</a>
|
||||
synopsis</b></h2>
|
||||
<pre><span class="keyword">namespace</span> <span class="identifier">boost</span> {
|
||||
<span class="keyword">namespace</span> <span class="identifier">wave</span> {
|
||||
|
||||
<span class="keyword">template</span> <
|
||||
<span class="keyword">typename</span> IteratorT, <span class="keyword">typename</span> LexIteratorT,
|
||||
<span class="keyword">typename</span> InputPolicyT, <span class="keyword">typename</span> TracePolicyT
|
||||
>
|
||||
<span class="keyword">class</span> context <span class="special">:</span> <span class="keyword">public</span> InputPolicyT
|
||||
{
|
||||
<span class="keyword">public</span>:
|
||||
|
||||
<span class="keyword">typedef</span> pp_iterator<context> iterator_type;
|
||||
<span class="keyword">typedef</span> TokenT token_type;
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> token_type::position_type position_type;
|
||||
|
||||
<span class="comment">// constructor</span>
|
||||
<a href="class_reference_context.html#constructor">context</a>(IteratorT <span class="keyword">const</span> &first_,
|
||||
IteratorT <span class="keyword">const</span> &last_,
|
||||
<span class="keyword">char const</span> *fname = <span class="string">"<Unknown>"</span>,
|
||||
TracePolicyT &trace = TracePolicyT())
|
||||
|
||||
<span class="comment">// iterator interface</span>
|
||||
iterator_type <a href="class_reference_context.html#iterator_interface_begin">begin</a>() <span class="keyword">const</span>;
|
||||
iterator_type <a href="class_reference_context.html#iterator_interface_end">end</a>() <span class="keyword">const</span>;
|
||||
|
||||
<span class="comment">// maintain include paths</span>
|
||||
<span class="keyword">bool</span> <a href="class_reference_context.html#add_include_path">add_include_path</a>(<span class="keyword">char const</span> *path_);
|
||||
<span class="keyword">bool</span> <a href="class_reference_context.html#add_sysinclude_path">add_sysinclude_path</a>(<span class="keyword">char const</span> *path_);
|
||||
<span class="keyword">void</span> <a href="class_reference_context.html#set_sysinclude_delimiter">set_sysinclude_delimiter</a>();
|
||||
|
||||
size_t <a href="class_reference_context.html#get_iteration_depth">get_iteration_depth</a>() <span class="keyword">const</span>;
|
||||
|
||||
<span class="comment">// maintain defined macros</span>
|
||||
<span class="keyword">bool</span> <a href="class_reference_context.html#add_macro_definition">add_macro_definition</a>(<span class="keyword">std::string</span> macrostring,
|
||||
<span class="keyword">bool</span> is_predefined = <span class="keyword">false</span>);
|
||||
<span class="keyword">bool</span> <a href="class_reference_context.html#is_defined_macro">is_defined_macro</a>(<span class="keyword">std::string const</span> &name) <span class="keyword">const</span>;
|
||||
<span class="keyword">bool</span> <a href="class_reference_context.html#remove_macro_definition">remove_macro_definition</a>(<span class="keyword">std::string const</span> &name,
|
||||
<span class="keyword">bool</span> even_predefined = <span class="keyword">false</span>);
|
||||
<span class="keyword">void</span> <a href="class_reference_context.html#reset_macro_definitions">reset_macro_definitions</a>();
|
||||
|
||||
<span class="comment">// other options</span>
|
||||
<span class="keyword">void</span> <a href="class_reference_context.html#language_support">set_language</a>(language_support enable);
|
||||
language_support <a href="class_reference_context.html#language_support">get_language</a>() <span class="keyword">const</span>;<br>
|
||||
<span class="keyword">void</span> <a href="class_reference_context.html#set_max_include_nesting_depth">set_max_include_nesting_depth</a>(size_t new_depth);<br> size_t <a href="class_reference_context.html#set_max_include_nesting_depth">get_max_include_nesting_depth</a>() <span class="keyword">const</span>;<br>
|
||||
<span class="comment">// get the Wave version information </span>
|
||||
<span class="keyword">static std::string</span> <a href="class_reference_context.html#get_version">get_version</a>();
|
||||
<span class="keyword">static std::string</span> <a href="class_reference_context.html#get_version">get_version_string</a>();
|
||||
};
|
||||
|
||||
} <span class="comment">// namespace wave</span>
|
||||
} <span class="comment">// namespace boost</span></pre>
|
||||
<h2><b><a name="template_parameters"></a>Template parameters</b></h2>
|
||||
<p>The <tt>boost::wave::context</tt> object has three template parameters to specify
|
||||
the concrete behaviour of its operation. The following table describes these
|
||||
with more detail.</p>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" class="table_title"><b>Template parameters required for the
|
||||
<tt>boost::wave::context</tt> class </b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="32%" class="table_cells"><code>IteratorT</code></td>
|
||||
<td width="68%" class="table_cells"><p>The type of the underlying iterator,
|
||||
through which the input stream is accessed. <br>
|
||||
This should be at least an <tt>forward_iterator</tt> type iterator.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>LexIteratorT</code></td>
|
||||
<td class="table_cells"><p>The type of the lexer type to be used by the <tt>Wave</tt>
|
||||
library to identify tokens in the input stream.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>InputPolicyT</code></td>
|
||||
<td class="table_cells"><p>The type of the input policy class, which allows
|
||||
to customize the behaviour of the Wave library and the type of the iterators
|
||||
to use, when it comes to including and opening an included file.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>TracePolicyT</code></td>
|
||||
<td class="table_cells"><p>The type of the trace policy class, which allows
|
||||
to customize the trace output generated while expanding macros. </p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>For further information about the lexer type to use, please refer to the <a href="class_reference_lexer.html">The
|
||||
Lexer Interface </a>.</p>
|
||||
<p>If the template parameter <tt>InputPolicyT</tt> is omitted, the template <tt>wave::iteration_context_policies::load_file_to_string</tt>
|
||||
is used. For further information about the input policy, please refer to the
|
||||
topic <a href="class_reference_inputpolicy.html">The Input Policy</a>.</p>
|
||||
<p>If the template parameter TracePolicyT is omitted, the <tt>wave::macro_trace_policies::no_tracing</tt>
|
||||
policy type is used, i.e. by default there is no tracing performed. For further
|
||||
information about the tracing policy, please refer to the topic <a href="class_reference_contextpolicy.html">The
|
||||
Tracing Policy</a>. </p>
|
||||
<h2><a name="public_typedefs"></a>Public Typedefs</h2>
|
||||
<p>The <tt>boost::wave::context</tt> template defines the following public typedefs, which may be useful while using this class:</p>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" class="table_title"><b>Public typedef's defined by the <tt>boost::wave::context</tt> class </b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>iterator_type</code></td>
|
||||
<td class="table_cells"><p>The <tt>IteratorT</tt> template parameter provided, while the <tt>context</tt> class was instantiated. </p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>lex_type</code></td>
|
||||
<td class="table_cells"><p>The <tt>LexIteratorT</tt> template parameter provided, while the <tt>context</tt> class was instantiated. </p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="32%" class="table_cells"><code>token_type</code></td>
|
||||
<td width="68%" class="table_cells"><p>The token type, which is returned by the <tt>context</tt> generated iterators. This type is taken from the <tt>LexIteratorT</tt> template parameter provided, whicle the <tt>context</tt> class was instantiated.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>input_policy_type</code></td>
|
||||
<td class="table_cells"><p>The <tt>InputPolicyT</tt> template parameter provided, while the <tt>context</tt> class was instantiated. </p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>trace_policy_type</code></td>
|
||||
<td class="table_cells"><p>The <tt>TracePolicyT</tt> template parameter provided, while the <tt>context</tt> class was instantiated. </p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>position_type</code></td>
|
||||
<td class="table_cells"><p>The type of the position information contained in every returned token, which describes the point, at which the given token was recognised. </p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><b><a name="member_functions"></a>Member functions</b></h2>
|
||||
<p><b><a name="constructor" id="constructor"></a>Constructor</b></p>
|
||||
<pre> context(IteratorT <span class="keyword">const</span> &first,
|
||||
IteratorT <span class="keyword">const</span> &last,
|
||||
<span class="keyword">char const</span> *filename,
|
||||
TracePolicyT &trace);</pre>
|
||||
<blockquote>
|
||||
<p>Constructs a context object on top of the input stream given by the pair
|
||||
of auxilliary iterators <tt>[first, last)</tt>. The iterators should
|
||||
be at least <tt>forward_iterator</tt> type iterators. The filename parameter
|
||||
is to be supplied for informational purposes only. This string is used for
|
||||
indicating the token positions inside the input stream, it is not validated
|
||||
against the file system. If the filename parameter is not given it defaults
|
||||
to <span class="copyright">"<Unknown>"</span>. If the trace
|
||||
parameter isn't supplied it defaults to a default constructed <tt>TracePolicyT</tt>
|
||||
object. </p>
|
||||
<p>Additionally the macro symbol table is filled with the predefined macros
|
||||
and the current reference directory is set to the path of the given filename.
|
||||
If this filename does not reference valid file system item, the current reference
|
||||
directory is set to the current system directory. (The current reference directory
|
||||
is the file system path, which is used as the target directory during the
|
||||
processing of <tt>#include "..."</tt> directives),</p>
|
||||
</blockquote>
|
||||
<h3>Iterator interface</h3>
|
||||
<p>The pair of iterators returned by the <tt>context::begin</tt> and <tt>context::end</tt>
|
||||
functions is the main interface for accessing the preprocessed tokens from the
|
||||
preprocessor engine. While iterating over the given iterator range <tt>[begin, end)</tt>
|
||||
there are returned the preprocessed C++ tokens, which are generated on the fly
|
||||
from the underlying input stream. The returned iterators are conceptually of
|
||||
<tt>forward_iterator</tt> type.</p>
|
||||
<p><b><a name="iterator_interface_begin"></a></b><b>begin</b></p>
|
||||
<pre> iterator_type begin();</pre>
|
||||
<blockquote>
|
||||
<p>Initializes and returns the starting iterator for the preprocessed token
|
||||
stream.</p>
|
||||
|
||||
</blockquote>
|
||||
<p><b><a name="iterator_interface_end" id="iterator_interface_end"></a></b><b>end</b></p>
|
||||
<pre> iterator_type end() <span class="keyword">const</span>;</pre>
|
||||
<blockquote>
|
||||
<p>Initializes and returns the end of stream iterator to compare with for detecting
|
||||
the end of the preprocessed token stream.</p>
|
||||
</blockquote>
|
||||
<h3>Maintain include paths</h3>
|
||||
<p>The <tt>Wave</tt> library maintains two separate search pathes for include
|
||||
files. A search path for user include files and a search path for system include
|
||||
files. Any directories specified with the <a href="#add_include_path">add_include_path()</a>
|
||||
function before the function <a href="class_reference_context.html#set_sysinclude_delimiter">set_sysinclude_delimiter()</a>
|
||||
is called are searched only for the case of <tt>#include "..."</tt>
|
||||
directives, they are not searched for <tt>#include <file></tt> directives.
|
||||
I.e. these directories are added to the user include search path. </p>
|
||||
<p>If additional directories are specified with the <a href="#add_include_path">add_include_path()</a>
|
||||
function after a call to the function <a href="class_reference_context.html#set_sysinclude_delimiter">set_sysinclude_delimiter()</a>,
|
||||
these directories are searched for all <tt>#include</tt> directives. I.e. these
|
||||
directories are added to the system include search path.</p>
|
||||
<p>In addition, a call to the function <a href="class_reference_context.html#set_sysinclude_delimiter">set_sysinclude_delimiter()</a>
|
||||
inhibits the use of the current reference directory as the first search directory
|
||||
for <tt>#include "..."</tt> directives. Therefore, the current
|
||||
reference directory is searched only, if it is requested explicitly with a call
|
||||
to the function <a href="#add_include_path">add_include_path(".")</a>.
|
||||
</p>
|
||||
<p>Callig both functions, the <a href="class_reference_context.html#set_sysinclude_delimiter">set_sysinclude_delimiter()</a>
|
||||
and <a href="#add_include_path">add_include_path(".")</a> allows you
|
||||
to control precisely, which directories are searched before the current one
|
||||
and which are searched after.</p>
|
||||
<p>These functions are modelled after the command line behaviour implemented by
|
||||
the popular gcc compiler.<br>
|
||||
</p>
|
||||
<p><a name="add_include_path"></a><b>add_include_path</b></p>
|
||||
<pre> <span class="keyword">bool</span> add_include_path(<span class="keyword">char const</span> *path);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>Adds the given file system path to the user include search paths. After a
|
||||
call to the <a href="class_reference_context.html#set_sysinclude_delimiter">set_sysinclude_delimiter()</a>
|
||||
this function adds the given file system path to the system include search
|
||||
paths. Note though, that the given path is validated against the file system.
|
||||
</p>
|
||||
<p>If the given path string does not form a name of a valid file system directory
|
||||
item, the function returns <tt>false</tt>. If the given path was successfully
|
||||
added to the include search paths in question, the function returns <tt>true</tt>.</p>
|
||||
</blockquote>
|
||||
<p><a name="add_sysinclude_path"></a><b>add_sysinclude_path</b></p>
|
||||
<pre> <span class="keyword">bool</span> add_sysinclude_path(<span class="keyword">char const</span> *path);</pre>
|
||||
<blockquote>
|
||||
<p>Adds the given file system path to the system include search paths. This
|
||||
function operates on the system include search path regardless of the mode
|
||||
of operation of the <a href="#add_include_path">add_include_path()</a>. Note
|
||||
though, that the given path is validated against the file system.</p>
|
||||
<p>If the given path string does not form a name of a valid file system directory
|
||||
item, the function returns <tt>false</tt>. If the given path was successfully
|
||||
added to the system include search paths, the function returns <tt>true</tt>.</p>
|
||||
</blockquote>
|
||||
<p><a name="set_sysinclude_delimiter"></a><b>set_sysinclude_delimiter</b></p>
|
||||
<pre> <span class="keyword">void</span> set_sysinclude_delimiter();</pre>
|
||||
<blockquote>
|
||||
<p>Switches the mode, how the <a href="#add_include_path">add_include_path()</a>
|
||||
function operates. By default the given file system path is added to the user
|
||||
include search paths. After calling this function a subsequent call to the
|
||||
<a href="#add_include_path">add_include_path()</a> adds the given file system
|
||||
path to the system include search paths. Additionally it inhibits the the
|
||||
use of the current reference directory as the first search directory for <tt>#include "..."</tt>
|
||||
directives.</p>
|
||||
</blockquote>
|
||||
<p><a name="get_iteration_depth"></a><b>get_iteration_depth</b></p>
|
||||
<pre> size_t get_iteration_depth() <span class="keyword">const</span>;</pre>
|
||||
<blockquote>
|
||||
<p>Returns the actual include iteration depth, i.e. the current number of include
|
||||
levels to be poped from the include iteration context, before the main (topmost)
|
||||
iteration context is reached.</p>
|
||||
</blockquote>
|
||||
<h3>Maintain defined macros</h3>
|
||||
<p><a name="add_macro_definition"></a><b>add_macro_definition</b></p>
|
||||
<pre><span class="keyword"> bool</span> add_macro_definition(
|
||||
<span class="keyword">std::string</span> macrostring,
|
||||
bool is_predefined);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>Adds a new macro definition to the macro symbol table. The parameter <tt>macrostring</tt>
|
||||
should contain the macro to define in the command line format, i.e. something
|
||||
like <tt>MACRO(x)=definition</tt>. The following table describes this format
|
||||
in more detail. The parameter <tt>is_predefined</tt> should be true while
|
||||
defining predefined macros, i.e. macros, which are not undefinable with an
|
||||
<tt>#undef</tt> directive from inside the preprocessed input stream. If this
|
||||
parameter is not given, it defaults to <tt>false</tt>.</p>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" class="table_title"><b>Summary of possible formats for defining
|
||||
macros </b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="32%" class="table_cells"><code>MACRO</code></td>
|
||||
<td width="68%" class="table_cells"><code>define <tt>MACRO</tt> as 1</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>MACRO=</code></td>
|
||||
<td class="table_cells"><code>define <tt>MACRO</tt> as nothing (empty)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>MACRO=definition</code></td>
|
||||
<td class="table_cells"><code>define <tt>MACRO</tt> as <tt>definition</tt></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="32%" class="table_cells"><code>MACRO(x)</code></td>
|
||||
<td width="68%" class="table_cells"><code>define <tt>MACRO(x)</tt> as 1</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>MACRO(x)=</code></td>
|
||||
<td class="table_cells"><code>define <tt>MACRO(x)</tt> as nothing (empty)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>MACRO(x)=definition</code></td>
|
||||
<td class="table_cells"><code>define <tt>MACRO(x)</tt> as <tt>definition</tt></code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>The function returns <tt>false</tt>, if the macro to define already was defined
|
||||
and the new definition is equivalent to the existing one, it returns true,
|
||||
if the new macro was successfully added to the macro symbol table.</p>
|
||||
<p>If the given macro definition resembles a redefinition and the new macro
|
||||
is not identical to the already defined macro (in the sense defined by the
|
||||
C++ Standard), the function throws a corresponding <tt>preprocess_exception</tt>.</p>
|
||||
</blockquote>
|
||||
<p><a name="is_defined_macro"></a><b>is_defined_macro</b></p>
|
||||
<pre><span class="keyword"> bool</span> is_defined_macro(<span class="keyword">std::string const</span> &name) <span class="keyword">const</span>; </pre>
|
||||
<blockquote>
|
||||
<p>Returns, if a macro with the given <tt>name</tt> is defined, i.e. if it is
|
||||
contained in the macro symbol table.</p>
|
||||
</blockquote>
|
||||
<p><a name="remove_macro_definition"></a><b>remove_macro_definition</b></p>
|
||||
<pre><span class="keyword"> bool</span> remove_macro_definition(
|
||||
<span class="keyword">std::string const</span> &name,
|
||||
<span class="keyword">bool</span> even_predefined); </pre>
|
||||
<blockquote>
|
||||
<p>Removes the definition of the macro with the given <tt>name</tt> from the
|
||||
macro symbol table. This operation is equivalent to an <tt>#undef</tt> directive
|
||||
with this <tt>name</tt> executed from within the input stream. If the parameter
|
||||
<tt>even_predefined</tt> is <tt>true</tt>, then the macro is removed from
|
||||
the macro symbol table even, if it is defined as a predefined macro. </p>
|
||||
<p>Note though, that the following macros are <b>not</b> undefinable in any
|
||||
case: <tt>__FILE__</tt>, <tt>__LINE__</tt>, <tt>__DATE__</tt>, <tt>__TIME__</tt>,
|
||||
<tt>__cplusplus</tt>, <tt>__STDC__</tt>. If the parameter <tt>even_predefined</tt>
|
||||
is not given, it defaults to <tt>false</tt>.</p>
|
||||
<p>The function returns <tt>false</tt>, if the macro to undefine was not defined
|
||||
and returns <tt>true</tt> otherwise.</p>
|
||||
<p>If the macro to remove may not be undefined (it is a predefined macro and
|
||||
the parameter <tt>even_predefined</tt> is set to <tt>false</tt> or it is one
|
||||
of the mentioned not undefinable macros above) the function throws a <tt>preprocess_exception</tt>.</p>
|
||||
</blockquote>
|
||||
<p><a name="reset_macro_definitions"></a><b>reset_macro_definitions</b></p>
|
||||
<pre><span class="keyword"> void</span> reset_macro_definitions(); </pre>
|
||||
<blockquote>
|
||||
<p>Resets the macro symbol table to it's initial state, i.e. undefines all user
|
||||
defined macros and inserts the internal predefined macros as described <a href="predefined_macros.html">here</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a name="get_version"></a>Get Version information</h3>
|
||||
<p><b>get_version</b></p>
|
||||
<pre><span class="keyword"> </span><span class="keyword">static std::string</span> get_version(); </pre>
|
||||
<blockquote>
|
||||
<p>Returns a string containing the current Wave version formatted as <span class="string">0xvvrsbbbb</span>
|
||||
(this is a string representation of the equivalent hexadecimal number), where
|
||||
<span class="literal">'vv'</span> is the version number, <span class="literal">'r'</span>
|
||||
the release number, <span class="literal">'s'</span> the subrelease number
|
||||
and <span class="literal">'bbbb'</span> the build number. A possible return
|
||||
value looks like <span class="literal">0x00910454</span>. The returned value
|
||||
is the same as is inserted in the preprocessed token stream, when the predefined
|
||||
macro <tt>__WAVE_VERSION__</tt> is expanded.</p>
|
||||
</blockquote>
|
||||
<p><b>get_version_str</b></p>
|
||||
<pre><span class="keyword"> </span><span class="keyword">static std::string</span> get_version_str(); </pre>
|
||||
<blockquote>
|
||||
<p>Returns a string containing the current Wave version formatted as <span class="string">"v.rr.ss.bbbb"</span>,
|
||||
where <span class="literal">'v'</span> is the version number, <span class="literal">'rr'</span>
|
||||
the release number, <span class="literal">'ss'</span> the subrelease number
|
||||
and <span class="literal">'bbbb'</span> the build number. A possible return
|
||||
value looks like <span class="literal">"0.9.1.454"</span>. The returned
|
||||
value is the same as is inserted in the preprocessed token stream, when the
|
||||
predefined macro <tt>__WAVE_VERSION_STR__</tt> is expanded.</p>
|
||||
</blockquote>
|
||||
<h3>Control extended options</h3>
|
||||
<p><a name="language_support"></a>set_language<br>
|
||||
get_language</p>
|
||||
<pre><span class="keyword"> void</span> set_language(<span class="keyword">language_support</span> language);
|
||||
<span class="keyword">language_support</span> get_language() <span class="keyword">const</span>;</pre>
|
||||
<blockquote>
|
||||
<p>This functions allow to specify the language mode, in which the <tt>Wave</tt>
|
||||
library should work. The possible language modes are defined by the enumerated
|
||||
type <tt>language_support</tt>:</p>
|
||||
<pre> <span class="keyword">enum</span> language_support {
|
||||
<span class="comment">// support flags for C++98</span>
|
||||
support_normal = 0x01,
|
||||
support_cpp = support_normal,
|
||||
|
||||
<span class="comment">// support flags for C99</span>
|
||||
support_variadics = 0x02,
|
||||
support_c99 = support_variadics,
|
||||
};</pre>
|
||||
<p>When used with <tt>support_variadics</tt> the support for variadics, placemarkers
|
||||
and the <tt>operator _Pragma()</tt> is enabled in normal C++ mode. The <tt>support_c99</tt>
|
||||
switch to the C99 language support.</p>
|
||||
</blockquote>
|
||||
<p><a name="set_max_include_nesting_depth" id="set_max_include_nesting_depth"></a>set_max_include_nesting_depth<br>
|
||||
g et_max_include_nesting_depth</p>
|
||||
<pre><span class="keyword"> void</span> set_max_include_nesting_depth(size_t new_depth);
|
||||
size_t get_max_include_nesting_depth() <span class="keyword">const</span>;</pre>
|
||||
<blockquote>
|
||||
<p>This functions allow to set or to get the maximal possible include file nesting
|
||||
depth supported by the <tt>Wave</tt> library. The initial value for this is
|
||||
determined by the preprocessing constant <tt>WAVE_MAX_INCLUDE_LEVEL_DEPTH</tt>
|
||||
(see <a href="compiletime_config.html">here</a>).</p>
|
||||
</blockquote>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="quickstart.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 9:05<!-- #EndDate -->
|
||||
</span>
|
||||
</p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
||||
263
doc/class_reference_contextpolicy.html
Normal file
@@ -0,0 +1,263 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Context Policy</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Context Policy</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_lexer.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p><a href="class_reference_tracepolicy.html#introduction">Introduction</a><br>
|
||||
<a href="class_reference_tracepolicy.html#header_synopsis">Header 'wave/preprocessing_hooks.hpp'
|
||||
synopsis</a><br>
|
||||
<a href="class_reference_tracepolicy.html#member_functions">Member functions</a></p>
|
||||
</blockquote>
|
||||
<h2><b><a name="introduction"></a>Introduction</b></h2>
|
||||
<p>The context policy is used to provide callback hooks, which are called from inside the library into the user code, whenever</p>
|
||||
<ul>
|
||||
<li>a macro get's defined or undefind, </li>
|
||||
<li>a macro is expanded or rescanned,</li>
|
||||
<li>an include file is opened or left, </li>
|
||||
<li> a pragma of the form <tt>'wave option[(value)]'</tt> is recognised. </li>
|
||||
</ul>
|
||||
<p>This policy type is used as a template parameter to the <a href="class_reference_context.html"><tt>wave::context<></tt></a>
|
||||
object, where the default policy provides empty hooks functions only.</p>
|
||||
<h2><a name="header_synopsis"></a>Header <a href="http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost/boost/wave/preprocessing_hooks.hpp?view=markup">wave/preprocessing_hooks.hpp</a>
|
||||
synopsis</h2>
|
||||
<pre>
|
||||
<span class="keyword">namespace</span> boost {
|
||||
<span class="keyword">namespace</span> wave {
|
||||
<span class="keyword">namespace</span> context_policies {
|
||||
|
||||
<span class="keyword">struct</span> default_preprocessing_hooks {
|
||||
|
||||
<span class="comment">// general control function</span>
|
||||
template</span> <<span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#expanding_function_like_macro">expanding_function_like_macro</a>(TokenT <span class="keyword">const</span> &macrodef,
|
||||
<span class="keyword">std::vector</span><TokenT> <span class="keyword">const</span> &formal_args,
|
||||
ContainerT <span class="keyword">const</span> &definition, TokenT <span class="keyword">const</span> &macrocall,
|
||||
<span class="keyword">std::vector</span><ContainerT> <span class="keyword">const</span> &arguments);
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#expanding_object_like_macro">expanding_object_like_macro</a>(TokenT <span class="keyword">const</span> &macro,
|
||||
ContainerT <span class="keyword">const</span> &definition, TokenT <span class="keyword">const</span> &macrocall);
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#expanded_macro">expanded_macro</a>(ContainerT <span class="keyword">const</span> &result);
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#expanded_macro">rescanned_macro</a>(ContainerT <span class="keyword">const</span> &result);
|
||||
|
||||
<span class="comment">// include file tracing functions</span>
|
||||
<span class="keyword">void </span><a href="class_reference_tracepolicy.html#opened_include_file">opened_include_file</a>(std::string <span class="keyword">const</span> &filename,
|
||||
std::size_t include_depth, <span class="keyword">bool</span> is_system_include);
|
||||
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#returning_from_include_file">returning_from_include_file</a>();
|
||||
|
||||
<span class="comment">// interpretation of #pragma's of the form </span>
|
||||
<span class="comment">// 'wave option[(value)]'</span>
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT>
|
||||
bool <a href="class_reference_tracepolicy.html#interpret_pragma">interpret_pragma</a>(ContextT <span class="keyword">const</span> &ctx, ContainerT &pending,
|
||||
<span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &option,
|
||||
ContainerT <span class="keyword">const</span> &values,
|
||||
<span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &pragma_token);
|
||||
|
||||
<span class="comment">// macro definition hooks</span>
|
||||
<span class="keyword">template</span> <
|
||||
<span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ParametersT, <span class="keyword">typename</span> DefinitionT
|
||||
>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#defined_macro">defined_macro</a>(TokenT <span class="keyword">const</span> &name, <span class="keyword">bool</span> is_functionlike,
|
||||
ParametersT <span class="keyword">const</span> &parameters, DefinitionT <span class="keyword">const</span> &definition,
|
||||
<span class="keyword">bool</span> is_predefined);
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> StringT>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#undefined_macro">undefined_macro</a>(StringT <span class="keyword">const</span> &name);
|
||||
};
|
||||
|
||||
}}} <span class="comment">// namespace boost::wave::context_policies</span></pre>
|
||||
<h2><a name="member_functions"></a>Member functions</h2>
|
||||
<h3>Macro expansion tracking functions</h3>
|
||||
<p><a name="expanding_function_like_macro"></a><b>expanding_function_like_macro</b></p>
|
||||
<pre><span class="keyword"> template</span> <<span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> expanding_function_like_macro(TokenT <span class="keyword">const</span> &macrodef,
|
||||
<span class="keyword">std::vector</span><TokenT> <span class="keyword">const</span> &formal_args,
|
||||
ContainerT <span class="keyword">const</span> &definition, TokenT <span class="keyword">const</span> &macrocall,
|
||||
<span class="keyword">std::vector</span><ContainerT> <span class="keyword">const</span> &arguments);</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>expanding_function_like_macro</tt> is called, whenever a
|
||||
function-like macro is to be expanded, i.e. <i>before</i> the actual expansion
|
||||
starts.</p>
|
||||
<p>The <tt>macroname</tt> parameter marks the position where the macro to expand
|
||||
is defined. It contains the token which identifies the macro name used inside
|
||||
the corresponding macro definition.</p>
|
||||
<p>The <tt>formal_args</tt> parameter holds the formal arguments used during
|
||||
the definition of the macro. </p>
|
||||
<p>The <tt>definition</tt> parameter holds the macro definition for the macro
|
||||
to trace. This is a standard STL container which holds the token sequence
|
||||
identified during the macro definition as the macro replacement list.</p>
|
||||
<p>The <tt>macrocall</tt> parameter marks the position where this macro is invoked.
|
||||
It contains the token, which identifies the macro call inside the preprocessed
|
||||
input stream. </p>
|
||||
<p>The <tt>arguments</tt> parameter holds the macro arguments used during the
|
||||
invocation of the macro. This is a vector of standard STL containers which
|
||||
contain the token sequences identified at the position of the macro call as
|
||||
the arguments to be used during the macro expansion. </p>
|
||||
</blockquote>
|
||||
<p><a name="expanding_object_like_macro"></a><b>expanding_object_like_macro</b></p>
|
||||
<pre> <span class="keyword">template</span> <<span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> expanding_object_like_macro(TokenT <span class="keyword">const</span> &macro,
|
||||
ContainerT <span class="keyword">const</span> &definition, TokenT <span class="keyword">const</span> &macrocall);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>expanding_object_like_macro</tt> is called, whenever a object-like
|
||||
macro is to be expanded, i.e. <i>before</i> the actual expansion starts.</p>
|
||||
<p>The <tt>macroname</tt> parameter marks the position where the macro to expand
|
||||
is defined. It contains the token which identifies the macro name used inside
|
||||
the corresponding macro definition.</p>
|
||||
<p> The <tt>definition</tt> parameter holds the macro definition for the macro
|
||||
to trace. This is a standard STL container which holds the token sequence
|
||||
identified during the macro definition as the macro replacement list.</p>
|
||||
<p>The <tt>macrocall</tt> parameter marks the position where this macro is invoked.
|
||||
It contains the token which identifies the macro call inside the preprocessed
|
||||
input stream. </p>
|
||||
</blockquote>
|
||||
<p><a name="expanded_macro"></a><b>expanded_macro</b></p>
|
||||
<pre> <span class="keyword">template</span> <<span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> expanded_macro(ContainerT <span class="keyword">const</span> &result);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>expanded_macro</tt> is called whenever the expansion of
|
||||
a macro is finished, the replacement list is completely scanned and the identified
|
||||
macros herein are replaced by its corresponding expansion results, but <i>before</i>
|
||||
the rescanning process starts.</p>
|
||||
<p>The parameter <tt>result</tt> contains the the result of the macro expansion
|
||||
so far. This is a standard STL container containing the generated token sequence.</p>
|
||||
</blockquote>
|
||||
<p><a name="rescanned_macro"></a><b>rescanned_macro</b></p>
|
||||
<pre> <span class="keyword">template</span> <<span class="keyword">typename</span> ContainerT>
|
||||
<span class="keyword">void</span> rescanned_macro(ContainerT <span class="keyword">const</span> &result);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>rescanned_macro</tt> is called whenever the rescanning
|
||||
of a macro is finished, i.e. the macro expansion is complete.</p>
|
||||
<p>The parameter <tt>result</tt> contains the the result of the whole macro
|
||||
expansion. This is a standard STL container containing the generated token
|
||||
sequence.</p>
|
||||
</blockquote>
|
||||
<h3>Include file tracing functions</h3>
|
||||
<p><a name="opened_include_file" id="opened_include_file"></a><strong>opened_include_file</strong></p>
|
||||
<pre> <span class="keyword">void</span> opened_include_file(std::string <span class="keyword">const</span> &filename,
|
||||
std::size_t include_depth, <span class="keyword">bool</span> is_system_include);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>opened_include_file</tt> is called whenever a file referred
|
||||
by an #include directive was successfully located and opened.</p>
|
||||
<p>The parameter <tt>filename</tt> contains the full file system path of the
|
||||
opened file.</p>
|
||||
<p>The <tt>include_depth</tt> parameter contains the current include file depth.
|
||||
</p>
|
||||
<p>The <tt>is_system_include</tt> parameter denotes, if the given file was found
|
||||
as a result of a <tt>#include <...></tt> directive.</p>
|
||||
</blockquote>
|
||||
<p><a name="returning_from_include_file" id="returning_from_include_file"></a><strong>returning_from_include_file</strong></p>
|
||||
<pre> <span class="keyword">void</span> returning_from_include_file();
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>returning_from_include_file</tt> is called whenever an
|
||||
included file is about to be closed after it's processing is complete.</p>
|
||||
</blockquote>
|
||||
<h3>Interpretation of #pragma's</h3>
|
||||
<p><strong><a name="interpret_pragma"></a>interpret_pragma</strong></p>
|
||||
<pre> <span class="keyword">template</span> <<span class="keyword">typename</span> Context, <span class="keyword">typename</span> ContainerT>
|
||||
bool <a href="class_reference_tracepolicy.html#interpret_pragma">interpret_pragma</a>(ContextT <span class="keyword">const</span> &ctx, ContainerT &pending,
|
||||
<span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &option,
|
||||
ContainerT <span class="keyword">const</span> &values,
|
||||
<span class="keyword">typename</span> ContextT::token_type<span class="keyword"> const</span> &pragma_token);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>interpret_pragma</tt> is called whenever an unrecognized
|
||||
<tt>#pragma wave ...</tt> or operator <tt>_Pragma("wave ...")</tt>
|
||||
is found in the input stream.</p>
|
||||
<p>The <tt>ctx</tt> parameter provides a reference to the <tt>context_type</tt> used during instantiation of the preprocessing iterators by the user. </p>
|
||||
<p>The <tt>pending</tt> parameter may be used to push tokens back into the input
|
||||
stream which are to be used as the replacement text for the whole <tt>#pragma wave()</tt>
|
||||
directive. If this sequence is left empty, no replacement takes place, i.e.
|
||||
the interpreted directive is removed from the generated token stream.</p>
|
||||
<p>The <tt>option</tt> parameter contains the name of the interpreted pragma.</p>
|
||||
<p>The <tt>values</tt> parameter holds the value of the parameter provided to
|
||||
the pragma operator.</p>
|
||||
<p>The <tt>pragma_token</tt> parameter contains the actual #pragma token which
|
||||
may be used for extraction of the location information for some error output.</p>
|
||||
<p>If the return value is 'false', the whole #pragma directive is interpreted
|
||||
as unknown and a corresponding error message is issued. A return value of
|
||||
'true' signs a successful interpretation of the given #pragma.<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
<h3>Macro definition </h3>
|
||||
<p><strong><a name="defined_macro" id="defined_macro"></a>defined_macro</strong></p>
|
||||
<pre> <span class="keyword">template</span> <
|
||||
<span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ParametersT, <span class="keyword">typename</span> DefinitionT
|
||||
>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#defined_macro">defined_macro</a>(TokenT <span class="keyword">const</span> &name, <span class="keyword">bool</span> is_functionlike,
|
||||
ParametersT <span class="keyword">const</span> &parameters, DefinitionT <span class="keyword">const</span> &definition,
|
||||
<span class="keyword">bool</span> is_predefined);
|
||||
</pre>
|
||||
<blockquote> <p>The function <tt>defined_macro</tt> is called whenever a macro was defined successfully.</p>
|
||||
<p>The parameter <tt>name</tt> is a reference to the token holding the macro name.</p>
|
||||
<p>The parameter <tt>is_functionlike</tt> is set to true whenever the newly
|
||||
defined macro is defined as a function like macro.</p>
|
||||
<p>The parameter <tt>parameters</tt> holds the parameter tokens for the macro
|
||||
definition. If the macro has no parameters or if it is a object like
|
||||
macro, then this container is empty.</p>
|
||||
<p>The parameter <tt>definition</tt> contains the token sequence given as the
|
||||
replacement sequence (definition part) of the newly defined macro.</p>
|
||||
<p>The parameter <tt>is_predefined</tt> is set to true for all macros predefined
|
||||
during the initialisation pahase of the library.<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
<p><strong><a name="undefined_macro" id="undefined_macro"></a>undefined_macro</strong></p>
|
||||
<pre> <span class="keyword">template</span> <<span class="keyword">typename</span> StringT>
|
||||
<span class="keyword">void</span> <a href="class_reference_tracepolicy.html#undefined_macro">undefined_macro</a>(StringT <span class="keyword">const</span> &name);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The function <tt>undefined_macro</tt> is called whenever a macro definition
|
||||
was removed successfully.</p>
|
||||
<p>The parameter <tt>name</tt> holds the name of the macro which definition was removed.<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_lexer.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Thursday, February 17, 2005 9:21<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
119
doc/class_reference_fileposition.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The File Position</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
File Position</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="token_ids.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="predefined_macros.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p><a href="class_reference_fileposition.html#introduction">Introduction</a><br>
|
||||
<a href="class_reference_fileposition.html#header_synopsis">Header 'wave/util/file_position.hpp'
|
||||
synopsis</a><br>
|
||||
<a href="class_reference_fileposition.html#template_parameters">Template parameters</a><br>
|
||||
<a href="class_reference_fileposition.html#member_functions">Member functions</a></p>
|
||||
</blockquote>
|
||||
<h2><b><a name="introduction"></a>Introduction</b></h2>
|
||||
<p>The file position template is used to represent a concrete token position inside
|
||||
the underlying input stream. This token position contains the corresponding
|
||||
filename, the line number and the column number, where the token was recognized.</p>
|
||||
<h2><b><a name="header_synopsis"></a>Header <a href="http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost/boost/wave/util/file_position.hpp?view=markup">wave/util/file_position.hpp</a>
|
||||
synopsis</b></h2>
|
||||
<pre><span class="keyword">namespace</span> <span class="identifier">boost</span> {
|
||||
<span class="keyword">namespace</span> <span class="identifier">wave</span> {
|
||||
<span class="keyword">namespace</span> <span class="identifier">util</span> {
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> StringT = <span class="keyword">std::string</span>>
|
||||
<span class="keyword">class</span> file_position {
|
||||
|
||||
<span class="keyword">public</span>:
|
||||
<a href="class_reference_fileposition.html#constructors">file_position</a>();
|
||||
<span class="keyword">explicit</span> <a href="class_reference_fileposition.html#constructors">file_position</a>(StringT const &file,
|
||||
int line_ = 1, int column_ = 1);
|
||||
|
||||
// accessors
|
||||
StringT <span class="keyword">const</span> &<a href="class_reference_fileposition.html#get_accessors">get_file</a>() <span class="keyword">const</span>;
|
||||
<span class="keyword">int</span> <a href="class_reference_fileposition.html#get_accessors">get_line</a>() <span class="keyword">const</span>;
|
||||
<span class="keyword">int</span> <a href="class_reference_fileposition.html#get_accessors">get_column</a>() <span class="keyword">const</span>;
|
||||
|
||||
<span class="keyword">void</span> <a href="class_reference_fileposition.html#set_accessors">set_file</a>(StringT <span class="keyword">const</span> &file);
|
||||
<span class="keyword">void</span> <a href="class_reference_fileposition.html#set_accessors">set_line</a>(<span class="keyword">int</span> line);
|
||||
<span class="keyword">void</span> <a href="class_reference_fileposition.html#set_accessors">set_column</a>(<span class="keyword">int</span> column);
|
||||
};
|
||||
|
||||
} <span class="comment">// namespace util</span>
|
||||
} <span class="comment">// namespace wave</span>
|
||||
} <span class="comment">// namespace boost</span></pre>
|
||||
<h2><a name="template_parameters"></a>Template parameters</h2>
|
||||
<p>The <tt>file_position</tt> template may be instantiatet with one template parameter,
|
||||
which gives the string type to use for storing the file name member of the file
|
||||
position. If this parameter isn't given, it defaults to a <tt>std::string</tt>.
|
||||
Please note, that the type given as the template parameter must be compatible
|
||||
with a <tt>std::string</tt>.</p>
|
||||
<h2><a name="member_functions"></a>Member functions</h2>
|
||||
<h3><a name="constructors"></a>Constructors</h3>
|
||||
<pre> <a href="class_reference_fileposition.html#constructors">file_position</a>();
|
||||
<span class="keyword">explicit</span> <a href="class_reference_fileposition.html#constructors">file_position</a>(StringT const &file,
|
||||
int line_ = 1, int column_ = 1);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The constructors initialize a new instance of a <tt>file_position</tt> in
|
||||
correspondence to the supplied parameters. The parameters default to an empty
|
||||
filename and the line number and column number set to one.</p>
|
||||
</blockquote>
|
||||
<p><a name="get_accessors"></a><b>get_file</b>, <b>get_line</b>, <b>get_column</b></p>
|
||||
<pre> StringT <span class="keyword">const</span> &<a href="class_reference_fileposition.html#get_accessors">get_file</a>() <span class="keyword">const</span>;
|
||||
<span class="keyword">int</span> <a href="class_reference_fileposition.html#get_accessors">get_line</a>() <span class="keyword">const</span>;
|
||||
<span class="keyword">int</span> <a href="class_reference_fileposition.html#get_accessors">get_column</a>() <span class="keyword">const</span>;
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The <tt>get_...</tt> functions are used to access the current values of the
|
||||
file position members: the filename (<tt>get_file</tt>), the line number (<tt>get_line</tt>)
|
||||
and the column number (<tt>get_column</tt>).</p>
|
||||
</blockquote>
|
||||
<p><a name="set_accessors"></a><b>set_file</b>, <b>set_line</b>, <b>set_column</b></p>
|
||||
<pre> <span class="keyword">void</span> <a href="class_reference_fileposition.html#set_accessors">set_file</a>(StringT <span class="keyword">const</span> &file);
|
||||
<span class="keyword">void</span> <a href="class_reference_fileposition.html#set_accessors">set_line</a>(<span class="keyword">int</span> line);
|
||||
<span class="keyword">void</span> <a href="class_reference_fileposition.html#set_accessors">set_column</a>(<span class="keyword">int</span> column);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>The <tt>set_...</tt> functions are used to set new values to the file position
|
||||
members: the filename (<tt>set_file</tt>), the line number (<tt>set_line</tt>)
|
||||
and the column number (<tt>set_column</tt>).</p>
|
||||
</blockquote>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="token_ids.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="predefined_macros.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font s<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 9:51<!-- #EndDate -->g file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 9:49<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
132
doc/class_reference_inputpolicy.html
Normal file
@@ -0,0 +1,132 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Input Policy</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Input Policy</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_context.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_contextpolicy.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p><a href="class_reference_inputpolicy.html#introduction">Introduction</a><br>
|
||||
<a href="class_reference_inputpolicy.html#header_synopsis">Header 'wave/cpp_iteration_context.hpp'
|
||||
synopsis</a><br>
|
||||
<a href="class_reference_inputpolicy.html#template_parameters">Template parameters</a><br>
|
||||
<a href="class_reference_inputpolicy.html#member_functions">Member functions</a></p>
|
||||
</blockquote>
|
||||
<h2><b><a name="introduction"></a>Introduction</b></h2>
|
||||
<p>The input policy type may be specified as a template parameter to the <tt>wave::context</tt>
|
||||
object and is used for customizing the way, how an included file is to be represented
|
||||
by a pair of iterators pointing to the beginning and the end of the resulting
|
||||
input sequence. If this template parameter is not given while instantiating
|
||||
the context object, it defaults to the <tt>iteration_context_policies::load_file_to_string</tt>
|
||||
type. </p>
|
||||
<h2><b><a name="header_synopsis"></a>Header <a href="http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost/boost/wave/util/iteration_context.hpp?view=markup">wave/iteration_context.hpp</a>
|
||||
synopsis</b></h2>
|
||||
<p>The following code listing does not show the required interface only, but for
|
||||
brevity reasons the whole implementation of an input policy, which loads the
|
||||
given file into a string variable and exposes the begin() and end() iterators
|
||||
of this string to the <tt>Wave</tt> library.</p>
|
||||
<pre><span class="keyword">namespace</span> boost {
|
||||
<span class="keyword">namespace</span> wave {
|
||||
<span class="keyword">namespace</span> iteration_context_policies {
|
||||
|
||||
<span class="keyword">struct</span> load_file_to_string {
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> IterContextT>
|
||||
<span class="keyword">class</span> inner {
|
||||
|
||||
<span class="keyword">public</span>:
|
||||
<span class="comment">// expose the begin and end iterators for the</span>
|
||||
<span class="comment">// included file</span>
|
||||
<span class="keyword">template</span> <typename PositionT>
|
||||
<span class="keyword">static</span>
|
||||
<span class="keyword">void</span> <a href="class_reference_inputpolicy.html#init_iterators">init_iterators</a>(IterContextT &iter_ctx,
|
||||
PositionT const &act_pos)
|
||||
{
|
||||
<span class="keyword">typedef typename</span> IterContextT::iterator_type iterator_type;
|
||||
|
||||
<span class="keyword">std::ifstream</span> instream(iter_ctx.filename.c_str());
|
||||
if (!instream.is_open()) {
|
||||
CPP_THROW(preprocess_exception, bad_include_file,
|
||||
iter_ctx.filename, act_pos);
|
||||
}
|
||||
|
||||
iter_ctx.instring = <span class="keyword">std::string</span>(
|
||||
<span class="keyword">std::istreambuf_iterator</span><char>(instream.rdbuf()),
|
||||
<span class="keyword">std::istreambuf_iterator</span><char>());
|
||||
|
||||
iter_ctx.first = iterator_type(iter_ctx.instring.begin(),
|
||||
iter_ctx.instring.end(),
|
||||
PositionT(iter_ctx.filename));
|
||||
iter_ctx.last = iterator_type();
|
||||
}
|
||||
|
||||
<span class="keyword">private</span>:
|
||||
<span class="keyword">std::string</span> instring;
|
||||
};
|
||||
};
|
||||
|
||||
} <span class="comment">// namespace iteration_context_policies</span>
|
||||
} <span class="comment">// namespace wave </span>
|
||||
} <span class="comment">// namespace boost </span> </pre>
|
||||
<p>As you can see, an <tt>input_policy</tt> for the <tt>wave::context</tt> object
|
||||
should implement one function only, the init_iterators function. The policy
|
||||
shown is implemented with the help of an embedded class to avoid the need for
|
||||
template template parameters, which aren't implemented by all systems today.
|
||||
This embedded class should have the name <tt>inner</tt>.</p>
|
||||
<h3><a name="template_parameters"></a>Template Parameters</h3>
|
||||
<p>The <tt>inner</tt> class is instantiated with one template parameter, the iteration
|
||||
context type, from which the policy is a part of. The iterator type <tt>iterator_type</tt>
|
||||
which is used to access the underlying input stream has to be derived through
|
||||
a typedef as shown. The iterator pair to initialize (which is accessible as
|
||||
<tt>iter_ctx.first</tt> and <tt>iter_ctx.last</tt>) has to initialized from
|
||||
an abritrary iterator type, representing the actual input stream.</p>
|
||||
<h3><a name="member_functions"></a>Member Functions</h3>
|
||||
<p><a name="init_iterators"></a><b>init_iterators</b></p>
|
||||
<pre> <span class="keyword">template</span> <<span class="keyword">typename</span> PositionT>
|
||||
<span class="keyword">static void</span> init_iterators(
|
||||
IterContextT iter_ctx,
|
||||
PositionT const &act_pos);</pre>
|
||||
|
||||
<p>directive was found in the input token stream. The main rationale for this
|
||||
function is to initialize the pair of iterators <tt>iter_ctx.first</tt> and
|
||||
<tt>iter_ctx.last</tt>, which are to be used to access the input stream corresponding
|
||||
to the include file to be inserted from inside the preprocessing engine.</p>
|
||||
</blockquote>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_context.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_contextpolicy.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 9:56<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
104
doc/class_reference_lexer.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Lexer Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Lexer Iterator Interface</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_contextpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_tokentype.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p><a href="class_reference_lexer.html#introduction">Introduction</a><br>
|
||||
<a href="class_reference_lexer.html#header_synopsis">Wave Lexer
|
||||
synopsis</a><br>
|
||||
<a href="class_reference_lexer.html#public_typedefs">Public Typedefs</a><br>
|
||||
<a href="class_reference_lexer.html#member_functions">Member functions</a></p>
|
||||
</blockquote>
|
||||
<h2><b><a name="introduction"></a>Introduction</b></h2>
|
||||
<p>Every lexer, which should be used in conjunction with the <tt>Wave</tt> library, has to return tokens formed from the input stream. These tokens should conform to the synopsis described in the topic <a href="class_reference_tokentype.html">The Token Type</a>. The lexer type should expose an interface which conforms at least to a <tt>forward_iterator</tt> (in the sense defined by the the C++ Standard) returning the token type. The code sample below does not show the definition of this forward iterator interface because this is highly implementation defined.</p>
|
||||
<h2><a name="header_synopsis"></a>Wave lexer
|
||||
synopsis (header: <a href="http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost/boost/wave/cpplexer/cpp_lex_interface.hpp?view=markup">wave/cpplexer/cpp_lexer_interface.hpp</a>)</h2>
|
||||
<pre> <span class="keyword">struct</span> lex_iterator
|
||||
{
|
||||
<span class="keyword">typedef</span> boost::wave::lex_token<> <a href="class_reference_lexer.html#public_typedefs">token_type</a>;
|
||||
|
||||
<span class="comment"> // Every lex_iterator should implement at least a complete
|
||||
// forward_iterator interface (not shown here)
|
||||
</span><span class="keyword"> typedef</span> std::forward_iterator_tag iterator_category;
|
||||
|
||||
<span class="comment"> // additional requirements
|
||||
</span> <a href="class_reference_lexer.html#member_functions">lex_iterator</a>();
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> IteratorT>
|
||||
<a href="class_reference_lexer.html#constructor">lex_iterator</a>(IteratorT <span class="keyword">const</span> &first, IteratorT <span class="keyword">const</span> &last
|
||||
<span class="keyword">typename</span> token_type::position_type <span class="keyword">const</span> &pos,
|
||||
boost::wave::language_support language)
|
||||
};
|
||||
|
||||
</pre>
|
||||
<p>Please note, that the <tt>lex_iterator</tt> defined in the library header <a href="http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost/boost/wave/cpplexer/cpp_lex_interface.hpp?view=markup">wave/cpplexer/cpp_lexer_interface.hpp</a> actually is a template class taking the token type to use as its template parameter. This is omitted in the synopsis above because it is an implementation detail of the Re2C lexer provided as part of the Wave library.</p>
|
||||
<p>If you want to use Wave in conjunction with your own lexing component this will have to conform to the interface described above only. </p>
|
||||
<h2><a name="public_typedefs" id="public_typedefs"></a>Public Typedefs</h2>
|
||||
<p>Besides the typedefs mandated for a <tt>forward_iterator</tt> by the C++ standard every lexer to be used with the <tt>Wave</tt> library should define the following typedefs: </p>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" class="table_title"><b>Public typedef's defined by the <tt>boost::wave::context</tt> class </b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="32%" class="table_cells"><code>token_type</code></td>
|
||||
<td width="68%" class="table_cells"><p>The <tt>token</tt> type returned by the lexer. This is type is used as the return value of the main iterators provided by the <tt>boost::wave:.context</tt> object too. </p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a name="member_functions"></a>Member functions</h2>
|
||||
<p>Besides the functions, which should be provided for <tt>forward_iterators</tt> as mandated by the C++ Standard, every lexer must implement the following functions to be used with the <tt>Wave</tt> library: </p>
|
||||
<p><a name="constructor" id="constructor"></a><b>constructor</b></p>
|
||||
<pre> lex_iterator();</pre>
|
||||
<blockquote>
|
||||
<p>The default constructor should construct a lexer iterator, which may be used as the end iterator of the provided iterator range.</p>
|
||||
</blockquote>
|
||||
<pre>
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> IteratorT>
|
||||
lex_iterator(IteratorT <span class="keyword">const</span> &first, IteratorT <span class="keyword">const</span> &last,
|
||||
<span class="keyword">typename</span> token_type::position_type <span class="keyword">const</span> &pos,
|
||||
boost::wave::language_support language);</pre>
|
||||
<blockquote>
|
||||
<p>The second constructor should construct a lexer iterator, which may be used as a iterator traversing over the token sequence, generated by the lexer class.</p>
|
||||
<p>The pair of iterators <tt>first</tt> and <tt>last</tt> should represent the input stream to be tokenized by the given lexer class. </p>
|
||||
<p>The parameter <tt>pos</tt> contains the initial position information to be used for token generation.</p>
|
||||
<p>The parameter <tt>language</tt> controls the reuqired mode with which the lexer should be initialised. </p>
|
||||
</blockquote>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_contextpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_tokentype.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Thursday, February 17, 2005 9:32<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
176
doc/class_reference_tokentype.html
Normal file
@@ -0,0 +1,176 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Token Type</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
</head>
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Token Type</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_lexer.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="token_ids.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p><a href="class_reference_tokentype.html#introduction">Introduction</a><br>
|
||||
<a href="class_reference_tokentype.html#header_synopsis">Header 'wave/context.hpp'
|
||||
synopsis</a><br>
|
||||
<a href="class_reference_tokentype.html#template_parameters">Template parameters</a><br>
|
||||
<a href="class_reference_tokentype.html#member_functions">Member functions</a></p>
|
||||
</blockquote>
|
||||
<h2><a name="Introduction"></a>Introduction</h2>
|
||||
<p>The token type in <tt>Wave</tt> is the main carrier of information. It is returned
|
||||
by dereferencing the iterators exposed by the lexing component and the iterator exposed by the preprocessor component. The tokens are originally generated by the
|
||||
lexer ("An entity that lexically transforms the subject of parsing to a
|
||||
sequence of objects (called tokens) more suitable for subsequent parsing.").
|
||||
The Wave library contains two different, interchangable C++ lexers, which may
|
||||
be used as a starting point during developing your own application. The lexer
|
||||
generated tokens are transformed by the preprocessing engine (macro expansion,
|
||||
include file processing etc.) and after this returned to the user of the <tt>Wave</tt>
|
||||
library.</p>
|
||||
<p>You can use arbitrary token types in conjunction with your own lexer as long
|
||||
as these implement some required interface. The required token type interface
|
||||
is described below and is implemented by the <tt>wave::cpplexer::lex_token</tt>
|
||||
template, the required lexer interface is described <a href="class_reference_lexer.html">here</a>.
|
||||
</p>
|
||||
<p>In the following is described the token type predefined inside the <tt>Wave</tt>
|
||||
library, which is used in conjunction with the two predefined C++ lexers contained
|
||||
in the <tt>Wave</tt> library too. If you need to use your own token type, it
|
||||
is required to implement the interafce described below.</p>
|
||||
<h2><b><a name="header_synopsis"></a>Header <a href="http://cvs.sourceforge.net/viewcvs.py/boost/boost/boost/wave/cpplexer/cpp_lex_token.hpp?view=markup">wave/cpplexer/cpp_lex_token.hpp</a>
|
||||
synopsis</b></h2>
|
||||
<pre><span class="keyword">namespace</span> boost {
|
||||
<span class="keyword">namespace</span> wave {
|
||||
<span class="keyword">namespace</span> cpplexer {
|
||||
|
||||
<span class="keyword">template</span> <<span class="keyword">typename</span> PositionT>
|
||||
<span class="keyword">class</span> lex_token
|
||||
{
|
||||
<span class="keyword">public</span>:
|
||||
<span class="keyword">typedef</span> <span class="keyword">std::basic_string</span><char><char> string_type;
|
||||
<span class="keyword">typedef</span> PositionT position_type;
|
||||
|
||||
<a href="class_reference_tokentype.html#constructor">lex_token</a>();
|
||||
<a href="class_reference_tokentype.html#constructor">lex_token</a>(token_id id, string_type <span class="keyword">const</span> &value,
|
||||
PositionT <span class="keyword">const</span> &pos);
|
||||
|
||||
// accessors
|
||||
<a href="class_reference_tokentype.html#operator_tokenid">operator token_id</a>() <span class="keyword">const</span>;
|
||||
string_type const &<a href="class_reference_tokentype.html#get_value">get_value</a>() <span class="keyword">const</span>;
|
||||
position_type const &<a href="class_reference_tokentype.html#get_position">get_position</a>() <span class="keyword">const</span>;
|
||||
void <a href="class_reference_tokentype.html#set_token_id">set_token_id</a> (token_id id);
|
||||
void <a href="class_reference_tokentype.html#set_value">set_value</a> (string_type <span class="keyword">const</span> &newval);
|
||||
void <a href="class_reference_tokentype.html#set_position">set_position</a> (position_type <span class="keyword">const</span> &pos);
|
||||
};
|
||||
|
||||
} <span class="comment">// namespace cpplexer</span>
|
||||
} <span class="comment">// namespace wave</span>
|
||||
} <span class="comment">// namespace boost</span>
|
||||
</pre>
|
||||
<h2><b><a name="template_parameters" id="template_parameters"></a>Template parameters</b></h2>
|
||||
<p>The predefined token type uses a template parameter <tt>PositionT</tt>, which
|
||||
allows to specify the type to be used to carry the file position information
|
||||
contained inside the generated tokens. This type should contain at least the
|
||||
filename, the line number and the column number of the position, where the token
|
||||
was recognized. It defaults to a simple file_position template class described
|
||||
<a href="class_reference_fileposition.html">here</a>. </p>
|
||||
<h2><b><a name="member_functions"></a>Member functions</b></h2>
|
||||
<p><b><a name="constructor" id="constructor"></a>Constructors</b></p>
|
||||
<pre> lex_token();
|
||||
|
||||
lex_token(token_id id,
|
||||
string_t <span class="keyword">const</span> &value,
|
||||
PositionT <span class="keyword">const</span> &pos);</pre>
|
||||
<blockquote>
|
||||
<p>The first (default) constructor is for generating an end of stream token,
|
||||
which is used for indicating the end of the underlying input stream.</p>
|
||||
<p>The second constructor initializes the newly created token object with its
|
||||
token id (for a list of valid token id's please look <a href="token_ids.html">here</a>),
|
||||
the string representation of its value and the file position, describing the
|
||||
position inside the input stream , where this token was recognized.</p>
|
||||
</blockquote>
|
||||
<h2>Accessor functions</h2>
|
||||
<p><a name="operator_tokenid"></a><b>operator token_id</b></p>
|
||||
<pre> <span class="keyword">operator</span> token_id() <span class="keyword">const</span>;</pre>
|
||||
<blockquote>
|
||||
<p>Allows the access to the token id of the token. This access function is implemented
|
||||
as an implicit conversion function to allow the operation of <tt>Spirit</tt>
|
||||
parsers directly on top
|
||||
|
||||
|
||||
top of a token stream. The possible token id's are described
|
||||
|
||||
<a href="token_ids.html">here</a></a>. </p>
|
||||
<p>This function does not throw in any case.</p>
|
||||
</blockquote>
|
||||
<p><a name="get_value"></a><b>get_value</b></p>
|
||||
<pre> string_t <span class="keyword">const</span> &get_value() <span class="keyword">const</span>;</pre>
|
||||
<blockquote>
|
||||
<p>Returns the value of the token, as it was recognized in the input stream.
|
||||
Even for constant tokens (as keywords or operators etc.) the returned value
|
||||
reflects the character sequence as found in the input stream. </p>
|
||||
<p>This function does not throw in any case.</p>
|
||||
</blockquote>
|
||||
<p><b><a name="get_position"></a>get_position</b></p>
|
||||
<pre> PositionT <span class="keyword">const</span> &get_position() <span class="keyword">const</span>;</pre>
|
||||
<blockquote>
|
||||
<p>Returns the position of the token in the input stream, where it was recognized.
|
||||
The position contains information about the filename, the line number and
|
||||
the column number of the token. By default the <tt>Wave</tt> library uses
|
||||
a file_position template for this purpose, which is described in more detail
|
||||
<a href="class_reference_fileposition.html">here</a>.</p>
|
||||
<p>This function does not throw in any case.</p>
|
||||
</blockquote>
|
||||
<p><a name="set_token_id"></a><b>set_token_id</b></p>
|
||||
<pre> void set_token_id(token_id id);</pre>
|
||||
<blockquote>
|
||||
<p>Changes the token id of the token to the new value. The possible token id's
|
||||
are described <a href="token_ids.html">here</a>. Propably this function is
|
||||
of little value for the library user, but it is required under certain circumstances
|
||||
for correct operation of the preprocessing engine.</p>
|
||||
<p>This function does not throw in any case.</p>
|
||||
</blockquote>
|
||||
<p><a name="set_value"></a><b>set_value</b></p>
|
||||
<pre> void set_value(string_t <span class="keyword">const</span> &newval);</pre>
|
||||
<blockquote>
|
||||
<p>Changes the value stored inside the token to the new value. Propably this
|
||||
function is of little value for the library user, but it is required under
|
||||
certain circumstances for correct operation of the preprocessing engine.</p>
|
||||
</blockquote>
|
||||
<p><a name="set_position"></a><b>set_position</b></p>
|
||||
<pre> void set_position(PositionT <span class="keyword">const</span> &newpos);</pre>
|
||||
<blockquote>
|
||||
<p>Changes the position stored inside the token to the new value. This is used
|
||||
for instance for implementing the functionality required for to implement
|
||||
the <tt>#line</tt> directive.</p>
|
||||
</blockquote>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_lexer.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="token_ids.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Thursday, February 17, 2005 9:34<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
203
doc/compiletime_config.html
Normal file
@@ -0,0 +1,203 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Compile Time Configuration</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Compile
|
||||
Time Configuration</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="supported_pragmas.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="samples.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p><b><a name="compiletime_config"></a>Library compile time configuration</b></p>
|
||||
<P dir="ltr">The C++ preprocessor iterator library may be configured at compile
|
||||
time by specifying different preprocessor constants to include different additional
|
||||
features. The possible preprocessor constants are described in the following
|
||||
table. </P>
|
||||
<table width="100%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" class="table_title"><b>Summary of possible preprocessor constants
|
||||
for<br>
|
||||
library configuration</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="46%" class="table_cells"><code>BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE</code></td>
|
||||
<td width="54%" class="table_cells"> <p>Support the #warning directive</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="46%" class="table_cells"><code><code>BOOST_</code>WAVE_SUPPORT_MS_EXTENSIONS</code></td>
|
||||
<td width="54%" class="table_cells"> <p>Support several MS specific language
|
||||
extensions (i.e. <tt>__int8</tt> et.al.)</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_PREPROCESS_ERROR_MESSAGE_BODY</code></td>
|
||||
<td class="table_cells"><p>Enable the preprocessing of the message bodies
|
||||
of <span class="keyword">#error</span> and <span class="keyword">#warning</span>
|
||||
directives.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_RETURN_PRAGMA_DIRECTIVES</code></td>
|
||||
<td class="table_cells"><p>If defined, then the <span class="keyword">#pragma</span>
|
||||
directives are returned as a token sequence to the caller, if not defined,
|
||||
the whole <span class="keyword">#pragma</span> directive is skipped. </p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_PREPROCESS_PRAGMA_BODY</code></td>
|
||||
<td class="table_cells"><p>Enable the preprocessing of the bodies of <span class="keyword">
|
||||
#pragma</span> directives.<br>
|
||||
Note though, that the body of an <tt>operator _Pragma()</tt> is preprocessed
|
||||
always, as required by the C99 Standard <a href="references.html#iso_c">[2]</a>.
|
||||
</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_ENABLE_COMMANDLINE_MACROS</code></td>
|
||||
<td class="table_cells"><p>Enable the functionality required to define macros
|
||||
with the command line syntax (-DMACRO(x)=definition)</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_STRINGTYPE</code></td>
|
||||
<td class="table_cells"><p>The tokens generated by the <tt>Wave</tt> library
|
||||
contain the token data and the file position, where this token was found
|
||||
in the input stream. <br>
|
||||
This constant may be used to redefine the data type, which is used to
|
||||
hold the token data and the corresponding file name. If this isn't defined
|
||||
it defaults to std::string. (The here defined data type should be compatible
|
||||
to the std::string type)</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_SUPPORT_VARIADICS_PLACEMARKERS</code></td>
|
||||
<td class="table_cells"><p>If defined, then the preprocessor library supports
|
||||
variadics and placemarkers. Note, to support C99 mode, this constant must
|
||||
be defined too.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_MAX_INCLUDE_LEVEL_DEPTH</code></td>
|
||||
<td class="table_cells"><p>If defined, it will determine the initial maximal
|
||||
possible include file nesting depth supported. It defaults to 1024.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code><code>BOOST_</code>WAVE_SUPPORT_PRAGMA_ONCE</code></td>
|
||||
<td class="table_cells"><p>If defined, then the <code>#pragma once</code> directive is supported by <tt>Wave</tt>. This specifies that the file, in which the pragma resides, will be included
|
||||
(opened) only once by the compiler in a build. </p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>BOOST_</code><code>WAVE_SUPPORT_INCLUDE_NEXT</code></td>
|
||||
<td class="table_cells"><p>If defined, then the <code>#include_next</code> directive is supported by <tt>Wave</tt>. This is syntactically equivalent to the <code>#include</code> directives, but may be used to inherit a header file (i.e. to include a file, which is named as the current file containing the <code>#include_next</code>).</p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<P dir="ltr"><b><a name="using_custom_lexer"></a>Using a different token type or lexer type in conjunction with Wave </b></P>
|
||||
<P dir="ltr">It is possible to use the <tt>Wave</tt> library while using your own token and/or lexer types. This may be achieved by providing your lexer type as the second template parameter while instantiating the <tt>boost::wave::context<></tt> object. The token type used by the library is derived from the <tt>token_type</tt> typedef to be provided by the lexer type. If you want to provide your own token type only, you may use the <tt>boost::wave::lex_iterator<></tt> type contained with the library. This type needs to be parametrized with the token type to use. </P>
|
||||
<P dir="ltr">To show, how this may be done, the <tt>Wave</tt> library contains several samples illustrating this possibility. The <tt>cpp_tokens</tt> sample shows the usage of a custom lexer and a custom token types. The lexer type used is functionally fully compatible to the <tt>re2c</tt> <a href="references.html#re2c">[3]</a> based lexer used by default. It is implemented based on the <tt>SLex</tt> <a href="references.html#slex">[5]</a> lexer example written by Dan Nuffer. The used theiring token type is functionally equivalent to the default token type except for an additional <tt>operator<<</tt> used for dumping the information carried bz the token.</P>
|
||||
<P dir="ltr"><b><a name="compilation_models"></a>Separation and inclusion compilation
|
||||
models</b></P>
|
||||
<P dir="ltr">The <tt>Wave</tt> C++ preprocessor iterator library is build almost
|
||||
completely as a header only library (except for the re2c based lexer). If you're
|
||||
trying to include all required files at once you will mention, that the resulting
|
||||
compilation times are very large (up to an hour - depending on your system configuration).
|
||||
This straightforward method we'll call the inclusion compilation model. If you
|
||||
do not pay attention to compilation times, that's the way to go, no special
|
||||
handling is needed.</P>
|
||||
<P dir="ltr">If you're interested in decreasing compilation times, the following
|
||||
method is to be used. This we will call it the separation compilation model.
|
||||
The trick is to separate the different objects such, that they are compilable
|
||||
separately. The function, which instantiates the templated object in question
|
||||
is factored out such, that its definition is visible to only one translation
|
||||
unit. To simplify this further this creation function is packaged into a small
|
||||
generator template structure.</P>
|
||||
<P dir="ltr">There are two levels of separation implemented: the separation of
|
||||
the compilation of the C++ lexer and the separation of the compilation of the
|
||||
different Spirit grammars used. To use these separations you will have to define
|
||||
two preprocessor constants while compiling the whole application and you will
|
||||
have to explicitely instantiate some helper templates. The following tables
|
||||
shows these constants in detail.</P>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" class="table_title"><b>Summary of possible compilation constants
|
||||
required <br>
|
||||
to enable the separation compilation model</b></td>
|
||||
</tr>
|
||||
<tr class="table_title">
|
||||
<td width="25%"><b>Separate</b></td>
|
||||
<td width="75%"><p><code><font face="Verdana, Arial, Helvetica, sans-serif">Preprocessor
|
||||
constant</font></code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" class="table_cells"><code>C++ lexer</code></td>
|
||||
<td width="75%" class="table_cells"> <p><code><code>BOOST_</code>WAVE_SEPARATE_LEXER_INSTANTIATION</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" class="table_cells"><code>Spirit grammars</code></td>
|
||||
<td width="75%" class="table_cells"> <p><code><code>BOOST_</code>WAVE_SEPARATE_GRAMMAR_INSTANTIATION</code></p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<P dir="ltr">The following table shows the explicit template instantiations required,
|
||||
if you want to use the separation compilation model. The <tt>TokenT</tt> placeholder
|
||||
type has to be replaced with your token type to use and the <code><tt>LexIteratorT</tt></code> placeholder type has to be replaced with your lex iterator type you've used while instantiation of the <tt>boost::wave::context<></tt> object. You will achieve the best
|
||||
results, if you place these into separate compilation units each. The <tt>IteratorT</tt>
|
||||
placeholder should be replaced by the iterator type, which was used to instantiate
|
||||
the <tt>boost::wave::context<></tt> object.</P>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" class="table_title"><b>Summary of required explicit template
|
||||
instantiations <br>
|
||||
required when using the separation compilation model</b></td>
|
||||
</tr>
|
||||
<tr class="table_title">
|
||||
<td width="25%"><b>Separate</b></td>
|
||||
<td width="75%"><p><code><font face="Verdana, Arial, Helvetica, sans-serif">Templates
|
||||
to explicitly instantiate</font></code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" class="table_cells"><code>C++ lexer</code></td>
|
||||
<td width="75%" class="table_cells"> <code><span class="keyword">template</span>
|
||||
cpplexer::re2clex::new_lexer_gen<<tt>IteratorT</tt>>;</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" class="table_cells"><code>Spirit grammars</code></td>
|
||||
<td width="75%" class="table_cells"> <p><code><span class="keyword">template</span> wave::grammars::expression_grammar_gen<<tt>TokenT</tt>>;<br>
|
||||
<span class="keyword"> template</span> wave::grammars::intlit_grammar_gen<<tt>TokenT</tt>>;<br>
|
||||
<span class="keyword"> template</span> wave::grammars::chlit_grammar_gen<<tt>TokenT</tt>>;<br>
|
||||
<span class="keyword"> <code>template</code><code></code><code> wave::grammars::cpp_grammar_gen<<tt>LexIteratorT</tt>>;<br>
|
||||
</code>template</span> wave::grammars::predefined_macros_grammar_gen<<tt>LexIteratorT</tt>>;<br>
|
||||
<span class="keyword"> template</span> wave::grammars::defined_grammar_gen<<tt>LexIteratorT</tt>>;</code></p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>To see an example of this you can look at the <tt>Wave</tt> driver program
|
||||
included as an acompanion sample to the C++ preprocessor iterator library. The
|
||||
corresponding files are named obviously <span class="string">"instantiate_...something.cpp"</span>,
|
||||
where the <span class="string">'...somthing'</span> is a hint, which grammars
|
||||
are explicitely instantiated inside. By using the separation model the compilation
|
||||
times required to build the <tt>Wave</tt> example are dropped by up to 90%.</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="supported_pragmas.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="samples.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Monday, January 17, 2005 16:39<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
93
doc/introduction.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Introduction</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Introduction</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="preface.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="quickstart.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<P dir="ltr">The <tt>Wave</tt> C++ preprocessor library is a Standards conformant
|
||||
implementation of the mandated C99/C++ preprocessor functionality packed behind
|
||||
a simple to use interface, which integrates well with the well known idioms
|
||||
of the Standard Template Library (STL).</P>
|
||||
<P dir="ltr">The <tt>Wave</tt> C++ preprocessor is not a monolitic application,
|
||||
it's rather a modular library, which exposes mainly a context object and an
|
||||
iterator interface. The context object helps to configure the actual preprocessing
|
||||
process (as search path's, predefined macros, etc.). The exposed iterators are
|
||||
generated by this context object too. Iterating over the sequence defined by
|
||||
the two iterators will return the preprocessed tokens, which are to be built
|
||||
on the fly from the given input stream. </P>
|
||||
<P dir="ltr"> The C++ preprocessor iterator itself is fed by a C++ lexer iterator,
|
||||
which implements an abstract interface. The C++ lexers packaged with the
|
||||
<tt>Wave</tt> library may be used standalone, too, and are not tied to the C++
|
||||
preprocessor iterator at all. </P>
|
||||
<P dir="ltr">To make the C++ preprocessing library modular, the C++ lexer is held
|
||||
completely separate and independent from the preprocessor. To prove this concept,
|
||||
two different, but functionally identical C++ lexers were
|
||||
implemented. Additionally there is implemented a IDL lexer, which allows to use the preprocessor library as the lexing component of a IDL oriented tool. All these lexers implement the mentioned abstract interface,
|
||||
so that the C++ preprocessor iterator may be used with all of them. The abstraction
|
||||
of the lexer from the preprocessor iterator library was done to allow
|
||||
plugging in different lexers without the need to reimplement the preprocessor.
|
||||
This will allow for benchmarking and specific fine tuning of the process of preprocessing
|
||||
itself.</P>
|
||||
<P dir="ltr">The first of these C++ lexers is implemented with the help of the
|
||||
well known <tt>Re2C</tt> <a href="references.html#re2c">[3]</a> tool, which generates
|
||||
C code from given regular expressions. The lexers generated with <tt>Re2C</tt>
|
||||
are known to be very fast, because they are not table driven but directly code the token building logic
|
||||
(very similar to hand coded lexers).
|
||||
</P>
|
||||
<P dir="ltr">The second of these C++ lexers is built around a table driven lexer,
|
||||
where the DFA tables (discrete finite automaton tables) are generated from regular expressions with the help of
|
||||
a Spirit-based lexer generating framework named <tt>Slex</tt> <a href="references.html#slex">[5]</a>.
|
||||
The <tt>Slex</tt> is fed during runtime with the token definitions (regular
|
||||
expressions) and generates the resulting DFA table. This table is used to combine
|
||||
the input characters into corresponding lexemes (tokens). The generated DFA table
|
||||
can be saved to disk to avoid the generation process at program startup.</P>
|
||||
<P dir="ltr">Wave may be used for preprocessing IDL files too, since the token set needed for the IDL language is very similar to the C++ token set. That's the reason, why the <tt>Wave</tt> preprocessor library contains also an IDL lexer. The IDL lexer is also based on the <tt>Re2C</tt> tool, but recognizes a different set of tokens. So this lexer does not recognize any keywords (except <tt>true</tt> and <tt>false</tt>, which are needed by the preprocessor itself). This is needed because there exist different IDL language flavours, where identifiers of one flavour may be keywords of others - Ok, this requires postponement of keyword identification until after the
|
||||
preprocessing, but allows to use Wave for all of the IDL derivatives. </P>
|
||||
<P dir="ltr">It is possible to build other C++ lexers if needed. Currently there
|
||||
are plans to adapt the <tt>Spirit</tt> C++ lexer example <tt>cpplexer</tt> <a href="references.html#cpplexer">[6]</a>,
|
||||
which is completely based on static <tt>Spirit<a href="references.html#spirit">[4]</a></tt>
|
||||
grammars.</P>
|
||||
<P dir="ltr">Both of the included lexers and the library itself are able
|
||||
to act in a C99 compliant mode. In this mode the lexers reject C++-only tokens
|
||||
(<tt>'::'</tt>, <tt>'->*'</tt>, <tt>'.*'</tt> and the alternate keywords
|
||||
such as <tt>'and'</tt>, etc.). The preprocessor additionally handles placemarkers
|
||||
(empty macro arguments) and variadics (macros with variable parameter counts).
|
||||
As an extension to the C++ Standard, the library can be enabled to handle placemarkers
|
||||
and variadics in C++ mode too.</P>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="preface.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="quickstart.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 12:07<!-- #EndDate -->
|
||||
</span> </p>
|
||||
</body>
|
||||
</html>
|
||||
101
doc/macro_expansion_process.html
Normal file
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Macro Expansion Process</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Macro Expansion Process</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="supported_pragmas.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="compiletime_config.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>The macro expansion process described here was initially developed by <a href="mailto:pmenso57@attbi.com">Paul
|
||||
Mensonides</a> and is implemented in <tt>Wave</tt>. It is much more understandable
|
||||
as the description of the desired macro expansion algorithm provided in the
|
||||
C++ Standard <a href="references.html#iso_cpp">[1]</a>.</p>
|
||||
<p>Macro replacement proceeds left-to-right. </p>
|
||||
<p>If, during scanning (or rescanning) an identifier is found, it is looked up
|
||||
in the symbol table. If the identifier is not found in the symbol table, it
|
||||
is not a macro and scanning continues.</p>
|
||||
<p>If the identifier is found, the value of a flag associated with the identifier
|
||||
is used to determine if the identifier is available for expansion. If it is
|
||||
not, the specific token (i.e. the specific instance of the identifier) is marked
|
||||
as disabled and is not expanded. If the identifier is available for expansion,
|
||||
the value of a different flag associated with the identifier in the symbol table
|
||||
is used to determine if the identifier is an object-like or function-like macro.
|
||||
If it is an object-like macro, it is expanded. If it is a function-like macro,
|
||||
it is only expanded if the next token is an left parenthesis.<br>
|
||||
An identifier is available for expansion if it is not marked as disabled and
|
||||
if the the value of the flag associated with the identifier is not set, which
|
||||
is used to determine if the identifier is available for expansion.</p>
|
||||
<p>(If a macro is an object-like macro, skip past the next two paragraphs.)</p>
|
||||
<p>If a macro to be expanded is a function-like macro, it must have the exact
|
||||
number of actual arguments as the number of formal parameters required by the
|
||||
definition of the macro. Each argument is recursively scanned and expanded.
|
||||
Each parameter name found in the replacement list is replaced by the expanded
|
||||
actual argument after leading and trailing whitespace and all placeholder tokens
|
||||
are removed unless the parameter name immediately follows the stringizing operator
|
||||
(<tt>'#'</tt>) or is adjacent to the token-pasting operator (<tt>'##'</tt>).</p>
|
||||
<p>If the parameter name immediately follows the stringizing operator (<tt>'#'</tt>),
|
||||
a stringized version of the unexpanded actual argument is inserted. If the parameter
|
||||
name is adjacent to the token-pasting operator (<tt>'##'</tt>), the unexpanded
|
||||
actual argument is inserted after all placeholder tokens are removed.</p>
|
||||
<p>All concatenation takes place in the replacement list. (If a single concatenation
|
||||
yields multiple tokens, the behavior is undefined. Moreover, <tt>Wave</tt> in
|
||||
normal C++98 and C99 modes issues an error, if more then one token is produced
|
||||
as the result of the concatenation. In C++0x mode <tt>Wave</tt> treats token-pasting
|
||||
of unrelated tokens as well defined and inserts the reparsed string representation
|
||||
of the concatenated tokens into the replacement list.).</p>
|
||||
<p>The flag in the symbol table entry associated with the name of the macro being
|
||||
expanded is set to indicate the that the macro is not available for expansion.</p>
|
||||
<p>The replacement list is rescanned for further macro expansion. All leading
|
||||
and trailing whitespace tokens in the replacement list are removed (the placeholder
|
||||
tokens are left intact). </p>
|
||||
<p>After rescanning completes, the flag in the symbol table entry associated with
|
||||
the name of macro being expanded is cleared to indicate that the macro is again
|
||||
available for expansion, and the sequence of tokens that constitutes the rescanned
|
||||
replacement list is returned to the point of invocation of the macro.</p>
|
||||
<p>If this sequence of tokens is empty, it is replaced by a placeholder token.
|
||||
If a placeholder is found during scanning (or rescanning) it is ignored. (Also,
|
||||
if the only thing separating a parameter from the stringizing operator or token-pasting
|
||||
operator is placeholder, it is also ignored in that context.)</p>
|
||||
<p>This sequence of tokens is inserted at the original point that the macro was
|
||||
invoked, and scanning continues starting with the last token of the newly inserted
|
||||
sequence of tokens. I.e. scanning looks back a single token (possibly a placeholder
|
||||
token) and continues.<br>
|
||||
</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="supported_pragmas.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="compiletime_config.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Monday, January 17, 2005 16:39<!-- #EndDate -->
|
||||
</span>
|
||||
</p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
||||
154
doc/predefined_macros.html
Normal file
@@ -0,0 +1,154 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Predefined Macros</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Predefined
|
||||
Macros </font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="supported_pragmas.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p dir="ltr">The following table lists the macros, which are predefined by the
|
||||
<tt>Wave</tt> library. Some of these (all except the <code class="keyword">__LINE__</code>,
|
||||
<code class="keyword">__FILE__</code>, <code class="keyword">__BASE_FILE__</code>, <code class="keyword">__DATE__</code>,
|
||||
<code class="keyword">__TIME__</code>, <code class="keyword">__STDC__, __INCLUDE_LEVEL__</code>
|
||||
and <code class="keyword">__cplusplus</code> macros) may be undefined from the command line of the driver executable
|
||||
(<a href="wave_driver.html">see</a> the -U option) or through the function <a href="class_reference_context.html#remove_macro_definition">remove_macro_definition()</a>.</p>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="3" class="table_title"><b>Summary of predefined macros</b></td>
|
||||
</tr>
|
||||
<tr class="table_title">
|
||||
<td width="28%"><b>Name</b></td>
|
||||
<td width="62%"><p><code><font face="Verdana, Arial, Helvetica, sans-serif">Value</font></code></p></td>
|
||||
<td width="10%">Undefinable</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="28%" class="table_cells"><code>__STDC__</code></td>
|
||||
<td width="62%" class="table_cells"><p> 1 (a decimal constant)</p></td>
|
||||
<td width="10%" class="table_cells"><p>yes</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="28%" class="table_cells"><code>__cplusplus</code></td>
|
||||
<td width="62%" class="table_cells"> <p>199711L (a decimal constant), this
|
||||
is defined in C++ mode only (C99 mode is off)<br>
|
||||
In the C++0x mode this decimal constant is guaranteed to be larger than
|
||||
199711L (the concrete value is to be defined by the C++ committee).</p></td>
|
||||
<td width="10%" class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__LINE__</code></td>
|
||||
<td class="table_cells"><p>The line number of the current source line (a decimal
|
||||
constant)</p></td>
|
||||
<td class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__FILE__</code></td>
|
||||
<td class="table_cells"><p>The presumed name of the source file (a character string literal)</p></td>
|
||||
<td class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__BASE_FILE__</code></td>
|
||||
<td class="table_cells"><p> This macro expands to the name of the main input file (a character string literal). This is the source file that was specified during construction of the <a href="class_reference_context.html"><tt>wave::context</tt></a> template.</p></td>
|
||||
<td class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__DATE__</code></td>
|
||||
<td class="table_cells"><p>The date of translation of the source file (a character
|
||||
string literal of the form<br>
|
||||
"Mmm dd yyyy", where the names of the months are the same as
|
||||
those generated by the asctime function, and the first character of dd
|
||||
is a space character if the value is less than 10). </p></td>
|
||||
<td class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__TIME__</code></td>
|
||||
<td class="table_cells"><p>The time of translation of the source file (a character
|
||||
string literal of the form "hh:mm:ss"<br>
|
||||
as in the time generated by the asctime function).</p></td>
|
||||
<td class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__INCLUDE_LEVEL__</code></td>
|
||||
<td class="table_cells"><p>A decimal integer constant that represents the
|
||||
depth of nesting in include <br>
|
||||
files. The value of this macro is incremented on every <tt>#include</tt>
|
||||
directive <br>
|
||||
and decremented at every end of file. </p></td>
|
||||
<td class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__WAVE__</code><br> <code>__SPIRIT_PP__</code></td>
|
||||
<td class="table_cells"><p>The version of the driver program (a hexadecinal
|
||||
constant of the form 0xMmrr, where <span class="literal">'M'</span> is
|
||||
the major version number, <span class="literal">'m'</span> the minor version
|
||||
number and <span class="literal">'rr'</span> the release number).</p></td>
|
||||
<td class="table_cells"><p>yes</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__WAVE_VERSION__</code><br> <code>__SPIRIT_PP_VERSION__</code></td>
|
||||
<td class="table_cells"><p>The full version number of the driver program (a
|
||||
hexadecimal constant of the form 0xMmrrbbbb, where <span class="literal">'M'</span>
|
||||
is the major version number, <span class="literal">'m'</span> the minor
|
||||
version number, <span class="literal">'rr'</span> the release number and
|
||||
<span class="literal">'bbbb'</span> the build number).</p></td>
|
||||
<td class="table_cells"><p>yes</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__WAVE_VERSION_STR__</code><br> <code>__SPIRIT_PP_VERSION_STR__</code></td>
|
||||
<td class="table_cells"><p>The full version number of the driver program (a
|
||||
character string literal of the form <span class="string">"M.m.rr.bbbb"</span>,
|
||||
where <span class="literal">'M'</span> is the major version number, <span class="literal">'m'</span>
|
||||
the minor version number, <span class="literal">'rr'</span> the release
|
||||
number and <span class="literal">'bbbb'</span> the build number).</p></td>
|
||||
<td class="table_cells"><p>yes</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__STDC_VERSION__</code></td>
|
||||
<td class="table_cells"><p>199901L (a decimal constant), this is defined in
|
||||
C99 mode only</p></td>
|
||||
<td class="table_cells"><p>yes</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><code>__WAVE_HAS_VARIADICS__</code></td>
|
||||
<td class="table_cells"><p>1 (a decimal constant), this is defined in C++
|
||||
mode only, if variadics and placemarkers are enabled, further it is defined
|
||||
in the C99 mode</p></td>
|
||||
<td class="table_cells"><p>no</p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="supported_pragmas.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 19, 2005 13:14<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
110
doc/preface.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Preface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Preface</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><img src="theme/l_arr_disabled.gif" width="20" height="19" border="0"></td>
|
||||
<td width="30"><a href="introduction.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>During the last time many new features were developed as additions to the <tt>Spirit</tt>
|
||||
<a href="references.html#spirit">[4]</a> parser construction framework and we
|
||||
felt more and more, that it would be very helpful, to have a 'real world' example,
|
||||
which could be used as a sandbox for testing the usability of certain features.
|
||||
Additionally a recent discussion on the Boost mailing list showed the widespread
|
||||
interest of developers to have a modern, open source C++ preprocessor library
|
||||
to play with. So we had the idea to implement a C++ preprocessor to fit
|
||||
this needs - <tt>Wave</tt> was born.</p>
|
||||
<p align="justify">The <tt>Wave</tt> C++ preprocessor library uses the <a href="http://spirit.sourceforge.net/">
|
||||
</a> <tt>Spirit<a href="references.html#spirit">[4]</a></tt> parser construction
|
||||
library to implement a C++ lexer with ISO/ANSI Standards conformant preprocessing
|
||||
capabilities. It exposes an iterator interface, which returns the current preprocessed
|
||||
token from the input stream. This preprocessed token is generated on the fly
|
||||
while iterating over the preprocessor iterator sequence (in the terminology
|
||||
of the STL these iterators are forward iterators). </p>
|
||||
<p align="justify"> The C++ preprocessor is a macro processor that under normal
|
||||
circumstances is used automatically by your C++ compiler to transform your program
|
||||
before actual compilation. It is called a macro processor because it allows
|
||||
you to define macros, which are brief abbreviations for longer constructs. The
|
||||
C++ preprocessor provides four separate facilities that you can use as you see
|
||||
fit: </p>
|
||||
<blockquote>
|
||||
<p><b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"> </b>Inclusion
|
||||
of header files<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"> </b>Macro
|
||||
expansion<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"> </b>Conditional
|
||||
compilation<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"> </b>Line
|
||||
control</p>
|
||||
</blockquote>
|
||||
<p>These features are greatly underestimated today, even more, the preprocessor
|
||||
has been frowned on for so long that its usage just hasn't been effectively
|
||||
pushed until the Boost preprocessor library <a href="references.html#pp_lib">[7]</a>
|
||||
came into being a few years ago. Only today we begin to understand, that preprocessor
|
||||
generative metaprogramming combined with template metaprogramming in C++ is
|
||||
by far one of the most powerful compile-time reflection/metaprogramming facilities
|
||||
that any language has ever supported.</p>
|
||||
<p>The C++ Standard <a href="http://www.codeproject.com/script/Submit/ViewHTML.asp?guid=wave%5Fpreprocessor%2Fcpp3%2F25%2F2003#iso_cpp">[2] </a> was adopted back in 1998, but there is still no (known to me) C++ compiler, which has a bugfree implementation of the rather simple preprocessor requirements mandated therein. This may be a result of the mentioned underestimation or even banning of the preprocessor from good programming style during the last few years or may stem from the somewhat awkward standardese dialect of English used to describe it. </p>
|
||||
<p align="justify">So the main goals for the <tt>Wave</tt> project are:</p>
|
||||
<blockquote>
|
||||
<p><b><img src="theme/bullet.gif" width="13" height="13" id="IMG1"> </b>full
|
||||
conformance with the C++ standard (ISO/IEC 14882:1998) <a href="references.html#iso_cpp">[1]</a>
|
||||
and with the C99 standard (INCITS/ISO/IEC 9899:1999) <a href="references.html#iso_c">[2]</a><br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13"> </b>usage of <tt>Spirit<a href="references.html#spirit">[4]</a></tt>
|
||||
for the parsing parts of the game (certainly :-)<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13"> </b>maximal usage
|
||||
of STL and/or <tt>Boost</tt> libraries (for compactness and maintainability)<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13"> </b>straightforward
|
||||
extendability for the implementation of additional features<br>
|
||||
<b><img src="theme/bullet.gif" width="13" height="13"> </b>building a
|
||||
flexible library for different C++ lexing and preprocessing needs</p>
|
||||
</blockquote>
|
||||
<p>At the first steps it is not planned to make a very high performance or very
|
||||
small C++ preprocessor. If you are looking for these objectives you probably
|
||||
have to look at other places. Although our C++ preprocessor iterator works as expected and is usable as a reference implementation, for instance
|
||||
for testing of other preprocessor oriented libraries as the Boost Preprocessor
|
||||
library <a href="references.html#pp_lib">[7]</a> et.al. Nevertheless recent work has lead to surprising performance enhancements (if compared
|
||||
with earlier versions). Wave is still somewhat slower as for instance EDG
|
||||
based preprocessors (Intel, Comeau) on simple input files, however, as
|
||||
complexity increases, time dilates expontentially on EDG. Preprocessing time
|
||||
dilates linearly under Wave, which causes it to easily outperform EDG based
|
||||
preprocessors when complexity increases.</p>
|
||||
<p>As tests showed, the <tt>Wave</tt> library is very conformant to the C++ Standard,
|
||||
such that it compiles several strict conformant macro definitions, which are
|
||||
not even compilable with EDG based preprocessors (i.e. Comeau or Intel). The only preprocessor known to have similar Standards conformance
|
||||
today is the preprocessor of the gcc C/C++ compiler.</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><img src="theme/l_arr_disabled.gif" width="20" height="19" border="0"></td>
|
||||
<td width="30"><a href="introduction.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 12:05<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
121
doc/quickstart.html
Normal file
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Quick Start</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Quick
|
||||
Start </font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_context.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Preprocessing with Wave is highly configurable. You must
|
||||
define a few options to control it. Here are a few of the
|
||||
options you can define:</p>
|
||||
<BLOCKQUOTE dir="ltr" style="MARGIN-RIGHT: 0px">
|
||||
<P><STRONG><IMG id="IMG1" height="13" src="theme/bullet.gif" width="13"></STRONG> include
|
||||
search paths, which define, where to search for files to be included with
|
||||
<tt>#include <...></tt> and <tt>#include "..."</tt> directives<br>
|
||||
<STRONG><img src="theme/bullet.gif" width="13" height="13"> </STRONG>which
|
||||
macros to predefine and which of the predefined macros to undefine<br>
|
||||
<STRONG><img src="theme/bullet.gif" width="13" height="13"> </STRONG>whether to enable any of several extensions to the C++
|
||||
Standard (such as for variadics and placemarkers)<br>
|
||||
</P>
|
||||
</BLOCKQUOTE>
|
||||
<p>You can access all these processing parameters through the <tt>boost::wave::context</tt>
|
||||
object. So you must instantiate one object of this type to use the <tt>Wave</tt>
|
||||
library. (For more information about the context template class, please refer
|
||||
to the class reference <a href="class_reference_context.html">here</a>.) To instantiate
|
||||
the <tt>boost::wave::context</tt> object you have to supply at least two template parameters:
|
||||
the iterator type of the underlying input stream to use and the type of the lexer iterator to be used as the token source for the preprocessing engine.</p>
|
||||
<P dir="ltr">Do not instantiate the main preprocessing iterators yourself.
|
||||
Get them from the wave::context object instead.<br>
|
||||
The following code snippet is taken from the <tt>quick_start</tt> sample, which shows a minimal usage scenario for <tt>Wave</tt>. </P>
|
||||
<pre><span class="comment"> // The following preprocesses a given input file.
|
||||
// Open the file and read it into a string variable</span>
|
||||
<span class="keyword">std::ifstream</span> instream(<span class="string">"input.cpp"</span>);
|
||||
<span class="keyword">std::string </span>input<span class="keyword">(
|
||||
std::istreambuf_iterator<char></span>(instream.rdbuf()),
|
||||
<span class="keyword">std::istreambuf_iterator<char></span>());
|
||||
|
||||
<span class="comment">// The template boost::wave::cpplexer::lex_token<> is the
|
||||
// token type to be used by the Wave library.
|
||||
// This token type is one of the central types throughout
|
||||
// the library, because it is a template parameter to some
|
||||
// of the public classes and templates and it is returned
|
||||
// from the iterators.
|
||||
// The template boost::wave::cpplexer::lex_iterator<> is
|
||||
// the lexer iterator to use as the token source for the
|
||||
// preprocessing engine. In this case this is parametrized
|
||||
// with the token type.</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost::wave::cpplexer::lex_iterator</span><span class="special"><</span>
|
||||
<span class="identifier">boost::wave::cpplexer::lex_token</span><span class="special"><> ></span>
|
||||
<span class="identifier">lex_iterator_type</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost::wave::context</span><span class="special"><</span>
|
||||
std::string::iterator<span class="special">,</span> lex_iterator_type<span class="special">></span>
|
||||
<span class="identifier">context_type</span><span class="special">;</span>
|
||||
|
||||
context_type ctx(input.begin(), input.end(), <span class="string">"input.cpp"</span>);
|
||||
|
||||
<span class="comment"> // At this point you may want to set the parameters of the
|
||||
// preprocessing as include pathes and/or predefined macros.
|
||||
</span> ctx.add_include_path(<span class="literal">"..."</span>);
|
||||
ctx.add_macro_definition(...);
|
||||
|
||||
<span class="comment"> // Get the preprocessor iterators and use them to generate
|
||||
// the token sequence.
|
||||
</span> context_type::iterator_type first = ctx.begin();
|
||||
context_type::iterator_type last = ctx.end();
|
||||
|
||||
<span class="comment"> // The input stream is preprocessed for you during iteration<br> // over [first, last)<br></span> <span class="keyword">while</span> (first != last) {
|
||||
<span class="keyword">std::cout</span> << (*first).get_value();
|
||||
++first;
|
||||
}
|
||||
|
||||
</pre>
|
||||
<P dir="ltr">The constructor of the <tt>boost::wave::context</tt> object can
|
||||
take a pair of arbitrary iterator types (at least <tt>input_iterator</tt> type
|
||||
iterators) to the input stream, which must supply the data to be processed.
|
||||
The third parameter supplies a filename, filename, which is reported in the preprocessor output to
|
||||
indicate the current context.
|
||||
Note though, that this filename is used
|
||||
only as long as no <tt>#include</tt> or <tt>#line</tt> directives are encountered,
|
||||
which in turn will alter the current filename reported.</P>
|
||||
<P dir="ltr">The iteration over the preprocessed tokens is relativley straightforward. Just get the starting and the ending iterators from the context object
|
||||
(maybe after initializing some include search paths) and you are done! Dereferencing
|
||||
the iterator will return the preprocessed tokens, which are generated on
|
||||
the fly from the input stream. (To get further information about the token type,
|
||||
you may want to look <a href="class_reference_tokentype.html">here</a>.)</P>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_context.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Sunday, February 13, 2005 14:37<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
100
doc/references.html
Normal file
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>References</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">References</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="acknowledgements.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><img src="theme/r_arr_disabled.gif" width="20" height="19" border="0"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table width="90%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="table_cells"> 1.</td>
|
||||
<td class="table_cells"> <a name="iso_cpp"></a>ISO/IEC </td>
|
||||
<td class="table_cells"><a href="http://webstore.ansi.org/ansidocstore/product.asp?sku=INCITS%2FISO%2FIEC%2B14882%2D1998">"Programming
|
||||
languages - C++"</a> <br>
|
||||
ISO/IEC 14882:1998</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="36" class="table_cells">2.</td>
|
||||
<td width="236" class="table_cells"> <a name="iso_c"></a>INCITS/ISO/IEC </td>
|
||||
<td width="520" class="table_cells"><a href="http://webstore.ansi.org/ansidocstore/product.asp?sku=INCITS/ISO/IEC%2B9899-1999">"Programming
|
||||
languages - C"</a> <br>
|
||||
INCITS/ISO/IEC 9899:1999</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells">3.</td>
|
||||
<td class="table_cells"> <a name="re2c"></a>Peter Bumbulis and <br>
|
||||
Donald D. Cowan</td>
|
||||
<td class="table_cells"><a href="http://www.tildeslash.org/re2c/index.html">Re2c
|
||||
V0.9.1 </a><br>
|
||||
A tool for generating C-based recognizers from regular expressions</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells">4.</td>
|
||||
<td class="table_cells"><a name="spirit"></a>Joel de Guzman et.al.</td>
|
||||
<td class="table_cells"><a href="http://spirit.sourceforge.net/">Spirit v1.8.2
|
||||
documentation</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells">5.</td>
|
||||
<td class="table_cells"><a name="slex"></a>Daniel C. Nuffer</td>
|
||||
<td class="table_cells"><a href="http://spirit.sourceforge.net/repository/applications/show_contents.php">The
|
||||
<tt>Spirit</tt> Slex example</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells">6.</td>
|
||||
<td class="table_cells"><a name="cpplexer"></a>Juan Carlos Arevalo-Baeza</td>
|
||||
<td class="table_cells"><a href="http://spirit.sourceforge.net/repository/applications/show_contents.php">The
|
||||
<tt>Spirit</tt> cpplexer example</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells">7.</td>
|
||||
<td class="table_cells"><a name="pp_lib"></a>Vesa Karvonen and <br>
|
||||
Paul Mensonides </td>
|
||||
<td class="table_cells"><a href="http://www.boost.org/libs/preprocessor/doc/index.html">The
|
||||
Boost Library Preprocessor Subset for C/C++</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells">8.</td>
|
||||
<td class="table_cells"><a name="boost"></a>boost.org</td>
|
||||
<td class="table_cells"><a href="http://www.boost.org">The Boost Libraries
|
||||
Documentation.</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="acknowledgements.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><img src="theme/r_arr_disabled.gif" width="20" height="19" border="0"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 10:07<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
94
doc/samples.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Samples</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body text="#000000" background="theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21">
|
||||
<h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Samples</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="wave_driver.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="references.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p dir="ltr">The <tt>Wave</tt> library contains several samples illustrating how to use the different features. This section describes these samples and its main characteristics. </p>
|
||||
<h2 dir="ltr">The quick_start sample</h2>
|
||||
<p>The <tt>quick_start</tt> sample shows a minimal way to use the <tt>Wave</tt> preprocessor library. It simply opens the file given as the first command line argument, preprocesses it assuming that there aren't any additional include pathes or macros defined and outputs the textual representation of the tokens generated from the given input file. This sample may be used to introduce yourself to <tt>Wave</tt>, because it does not contain all the potential additional complexity exposed by more complex samples. </p>
|
||||
<h2>The <strong>cpp_tokens sample </strong></h2>
|
||||
<p dir="ltr">The <tt>cpp_tokens</tt> sample dumps out the information contained within the tokens returned from the iterator supplied by the <tt>Wave</tt> library. It shows, how to use the <tt>Wave</tt> library in conjunction with custom lexer and custom token types. The lexer used within this sample is <tt>SLex</tt> <a href="references.html#slex">[5]</a> based, i.e. it <tt></tt> is feeded during runtime (at startup) with the token definitions (regular expressions) and generates a resulting DFA table. This table is used for token identification and is saved to disc afterwards to avoid the table generation process at the next program startup. The name of the file to which the DFA table is saved is <tt>wave_slex_lexer.dfa</tt>. </p>
|
||||
<p dir="ltr">The main advantage of this <tt>SLex</tt> based lexer if compared to the default <tt>Re2C</tt> <a href="references.html#re2c">[3]</a> generated lexer is, that it provides not only the line information, where a particular token was recognized, but also the related column position. Otherwise the <tt>SLex</tt> based lexer is functionally fully compatible to the <tt>Re2C</tt> based one, i.e. you always may switch your application to use it, if you additionally need to get the column information back from the preprocessing. </p>
|
||||
<p dir="ltr">Since no additional command line parameters are supported by this sample, it won't work well with include files, which aren't located in the same directory as the inspected input file. The command line syntax is straight forward:</p>
|
||||
<pre> cpp_tokens input_file</pre>
|
||||
<h2 dir="ltr">The list_includes sample </h2>
|
||||
<p dir="ltr">The <tt>list_includes</tt> sample shows how the <tt>Wave</tt> library may be used to generate a include file dependency list for a particular input file. It completely depends on the default library configuration. The command line syntax for this sample is given below: </p>
|
||||
<pre> Usage: list_includes [options] file ...:
|
||||
-h [ --help ] : print out program usage (this message)
|
||||
-v [ --version ] : print the version number
|
||||
-I [ --path ] dir : specify additional include directory
|
||||
-S [ --syspath ] dir : specify additional system include directory
|
||||
</pre>
|
||||
<p dir="ltr">Please note though, that this sample will output only those include file names, which are visible to the preprocessor, i.e. given the following code snippet, only one of the two include file directives is triggered during preprocessing and for this reason only the corresponding file name is reported by the <tt>list_includes</tt> sample:
|
||||
<pre><span class="preprocessor"> #if</span> <span class="keyword">defined</span></span><span class="special">(</span>INCLUDE_FILE_A<span class="special">)</span>
|
||||
<span class="preprocessor"> # include</span> <span class="literal">"file_a.h"</span>
|
||||
<span class="preprocessor"> #else</span>
|
||||
<span class="preprocessor"> # include</span> <span class="literal">"file_b.h"</span>
|
||||
<span class="preprocessor"> #endif</span></pre>
|
||||
<h2 dir="ltr">The wave sample</h2>
|
||||
<p dir="ltr">Because of its general usefulness the <tt>wave</tt> sample is not located in the sample directory of the library, but inside the tools directory of Boost. The wave sample is usable as a full fledged preprocessor executable
|
||||
on top of any other C++ compiler. It outputs the textual representation of the
|
||||
preprocessed tokens generated from a given input file. It is described in more details <a href="wave_driver.html">here</a>. </p>
|
||||
<h2 dir="ltr">The waveidl sample </h2>
|
||||
<p dir="ltr">The main point of the <tt>waveidl</tt> sample is to show, how a completely independent lexer type may be used in conjunction with the default token type of the <tt>Wave</tt> library. The lexer used in this sample is supposed to be used for an IDL language based preprocessor. It is based on the <tt>Re2C</tt> tool too, but recognizes a different set of tokens as the default C++ lexer contained within the <tt>Wave</tt> library. So this lexer does not recognize any keywords (except <tt>true</tt> and <tt>false</tt>, which are needed by the preprocessor itself). This is needed because there exist different IDL languages, where identifiers of one language may be keywords of others. Certainly this implies to postpone keyword identification after the preprocessing, but allows to use <tt>Wave</tt> for all of the IDL derivatives. </p>
|
||||
<p dir="ltr">It is only possible to use the <tt>Wave</tt> library to write an IDL preprocessor, because the token sets for both languages are very similar. The tokens to be recognized by the <tt>waveidl</tt> IDL language preprocessor is nearly a complete subset of the full C++ token set. </p>
|
||||
<p dir="ltr">The command line syntax usable for this sample is shown below:</p>
|
||||
<pre> Usage: waveidl [options] [@config-file(s)] file:
|
||||
|
||||
|
||||
Options allowed on the command line only:
|
||||
-h [ --help ] : print out program usage (this message)
|
||||
-v [ --version ] : print the version number
|
||||
-c [ --copyright ] : print out the copyright statement
|
||||
--config-file filepath : specify a config file (alternatively: @filepath)
|
||||
|
||||
|
||||
Options allowed additionally in a config file:
|
||||
-o [ --output ] path : specify a file to use for output instead of stdout
|
||||
-I [ --include ] path : specify an additional include directory
|
||||
-S [ --sysinclude ] syspath : specify an additional system include directory
|
||||
-D [ --define ] macro[=[value]] : specify a macro to define
|
||||
-P [ --predefine ] macro[=[value]] : specify a macro to predefine
|
||||
-U [ --undefine ] macro : specify a macro to undefine
|
||||
</pre>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="wave_driver.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="references.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Saturday, February 12, 2005 9:56<!-- #EndDate -->
|
||||
</span>
|
||||
</p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
||||
128
doc/supported_pragmas.html
Normal file
@@ -0,0 +1,128 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Supported Pragma Directives</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Supported
|
||||
Pragma Directives</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="predefined_macros.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="macro_expansion_process.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>The Wave preprocessor library supports a couple of specific <tt>#pragma</tt>
|
||||
directives, which may be used to control some of the library features. All directives
|
||||
described here are usable as conventional <tt>#pragma</tt> directives and as
|
||||
<tt>operator _Pragma</tt> (if variadics are enabled). So for instance the
|
||||
following directives are functionally identical:</p>
|
||||
<pre> #pragma wave trace(enable) </pre>
|
||||
<p>and </p>
|
||||
<pre> _Pragma("wave trace(enable)")</pre>
|
||||
<p>All <tt>Wave</tt> specific pragma's must have the general form <tt>'wave option[(value)]'</tt>,
|
||||
where <tt>'wave'</tt> is the specific keyword, <tt>'option'</tt> is the concrete
|
||||
pragma functionality to trigger and <tt>'value'</tt> is an optional value to
|
||||
be supplied to the <tt>'option'</tt> functionality. The following table lists
|
||||
all possible pragma functions supported by the <tt>Wave</tt> library. For all recognised pragmas of this general form the interpret_pragma hook function from inside the context_policies are call, so that the user of the library is responsible for </p>
|
||||
<table width="77%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="4"> <p class="table_title">Supported pragma's</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <p class="toc_title" width="36%">pragma option</p></td>
|
||||
<td> <p class="toc_title" width="28%">pragma value</p></td>
|
||||
<td> <p class="toc_title" width="36%">description</p></td>
|
||||
<td> <p class="toc_title" width="36%">supported by</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="19%"> <p>trace</p></td>
|
||||
<td class="table_cells" width="18%"> <p>enable/on/1<br>
|
||||
disable/off/0</p></td>
|
||||
<td class="table_cells" width="43%"><p>Enable or disable the tracing of the
|
||||
macro expansion process. This is needed, even if there is given the --trace
|
||||
command line option, because the trace output is generated only, if there
|
||||
is at least one trace(enable) pragma found.</p></td>
|
||||
<td class="table_cells" width="20%"><p>Wave driver</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><p>stop</p></td>
|
||||
<td class="table_cells"><p>message</p></td>
|
||||
<td class="table_cells"><p>Stop the execution of <tt>Wave</tt> and print out
|
||||
the given message. This is very helpful for direct debugging purposes.</p></td>
|
||||
<td class="table_cells"><p>Wave driver</p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="table_cells"><p>system</p></td>
|
||||
<td class="table_cells"><p>command</p></td>
|
||||
<td class="table_cells"><p>Try to spawn the 'command' as a new operating system
|
||||
command and intercept the generated stdout and stderr. The stdout output
|
||||
of this command (if any) is retokenized and used as the replacement text
|
||||
for the whole pragma, the stderr output is ignored. The command is considered
|
||||
to be successful, if/when the return value is zero, otherwise an error
|
||||
is reported. <br>
|
||||
</p></td>
|
||||
<td class="table_cells"><p>Wave driver</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells"><p>timer</p></td>
|
||||
<td class="table_cells"><p> restart/0<br>
|
||||
<no value> <br>
|
||||
suspend<br>
|
||||
resume </p></td>
|
||||
<td class="table_cells"><p>The value <tt>restart</tt> set the current elapsed
|
||||
time to 0 and restarts the timer.<br>
|
||||
If no value is provided, the current elpsed time is printed to the std::cerr
|
||||
stream.<br>
|
||||
The values <tt>suspend</tt> and <tt>resume</tt> allow to temporarily stop
|
||||
the timing.</p></td>
|
||||
<td class="table_cells"><p>Wave driver</p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>All pragma's not listed here but flagged as <tt>'wave'</tt> are reported as
|
||||
errors. The handling of all remaining pragma's depends on the compilation constant
|
||||
<code><tt>WAVE_RETURN_PRAGMA_DIRECTIVES</tt></code>, which allows to specify,
|
||||
if those pragmas are left unchanged in the output stream or not. Please note,
|
||||
that the operator _Pragma variant is always subject to full preprocessing, before
|
||||
the pragma itself is evaluated. The #pragma variant is subject to preprocessing
|
||||
only, if the <code><tt>WAVE_PREPROCESS_PRAGMA_BODY</tt></code> compilation constant
|
||||
was specified during compilation. For more information about the possible compilation
|
||||
constants look <a href="compiletime_config.html">here</a>.</p>
|
||||
<p>Additionally the Wave preprocessor supports the <tt>#pragma once</tt> directive,
|
||||
which specifies that the file, in which the pragma resides, will be included
|
||||
(opened) only once by the compiler in a build. This may be used to optimize
|
||||
the preprocessing of larger compilation units, which include a lot of files. Note though, that the #pragma once directive is supported only, if the compile time constant <tt>WAVE_SUPPORT_PRAGMA_ONCE</tt> was given during compilation of the library</span>.</p>
|
||||
<p>It is fairly easy to implement your own <tt>#pragma wave ... </tt> directives. All you have to do is to implement your own <tt>interpret_pragma</tt> function (see <a href="class_reference_contextpolicy.html#interpret_pragma">here</a>) which should the handle additional directives. For an example of how to do it, you may have a look at the Wave driver application, which implements the <tt>#pragma wave timer()</tt> directive with the help of a supplied <tt>interpret_pragma</tt> function. </p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="predefined_macros.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="macro_expansion_process.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Monday, January 17, 2005 16:39<!-- #EndDate -->
|
||||
</span>
|
||||
</p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
||||
BIN
doc/theme/bkd.gif
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
doc/theme/bkd2.gif
vendored
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
doc/theme/bullet.gif
vendored
Normal file
|
After Width: | Height: | Size: 152 B |
BIN
doc/theme/l_arr.gif
vendored
Normal file
|
After Width: | Height: | Size: 147 B |
BIN
doc/theme/l_arr_disabled.gif
vendored
Normal file
|
After Width: | Height: | Size: 91 B |
BIN
doc/theme/r_arr.gif
vendored
Normal file
|
After Width: | Height: | Size: 147 B |
BIN
doc/theme/r_arr_disabled.gif
vendored
Normal file
|
After Width: | Height: | Size: 91 B |
179
doc/theme/style.css
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/* Use, modification and distribution is subject to 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)
|
||||
*/
|
||||
body
|
||||
{
|
||||
background-image: url(bkd.gif);
|
||||
background-color: #FFFFFF;
|
||||
margin: 1em 2em 1em 2em;
|
||||
}
|
||||
|
||||
h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; }
|
||||
h2 { font: 140% sans-serif; font-weight: bold; text-align: left; }
|
||||
h3 { font: 120% sans-serif; font-weight: bold; text-align: left; }
|
||||
h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; }
|
||||
h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; }
|
||||
h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; }
|
||||
|
||||
pre
|
||||
{
|
||||
border-top: gray 1pt solid;
|
||||
border-right: gray 1pt solid;
|
||||
border-left: gray 1pt solid;
|
||||
border-bottom: gray 1pt solid;
|
||||
|
||||
padding-top: 2pt;
|
||||
padding-right: 2pt;
|
||||
padding-left: 2pt;
|
||||
padding-bottom: 2pt;
|
||||
|
||||
display: block;
|
||||
font-family: "courier new", courier, mono;
|
||||
background-color: #eeeeee; font-size: small
|
||||
}
|
||||
|
||||
code
|
||||
{
|
||||
font-family: "Courier New", Courier, mono;
|
||||
font-size: small
|
||||
}
|
||||
|
||||
tt
|
||||
{
|
||||
display: inline;
|
||||
font-family: "Courier New", Courier, mono;
|
||||
color: #000099;
|
||||
font-size: small
|
||||
}
|
||||
|
||||
p
|
||||
{
|
||||
text-align: justify;
|
||||
font-family: Georgia, "Times New Roman", Times, serif
|
||||
}
|
||||
|
||||
ul
|
||||
{
|
||||
list-style-image: url(bullet.gif);
|
||||
font-family: Georgia, "Times New Roman", Times, serif
|
||||
}
|
||||
|
||||
ol
|
||||
{
|
||||
font-family: Georgia, "Times New Roman", Times, serif
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
font-weight: bold;
|
||||
color: #003366;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover { color: #8080FF; }
|
||||
|
||||
.literal { color: #666666; font-style: italic}
|
||||
.keyword { color: #000099}
|
||||
.identifier {}
|
||||
.comment { font-style: italic; color: #990000}
|
||||
.special { color: #800040}
|
||||
.preprocessor { color: #990099}
|
||||
.string { font-style: italic; color: #666666}
|
||||
.copyright { color: #666666; font-size: small}
|
||||
.white_bkd { background-color: #FFFFFF}
|
||||
.dk_grey_bkd { background-color: #999999}
|
||||
.quotes { color: #666666; font-style: italic; font-weight: bold}
|
||||
|
||||
.note_box
|
||||
{
|
||||
display: block;
|
||||
|
||||
border-top: gray 1pt solid;
|
||||
border-right: gray 1pt solid;
|
||||
border-left: gray 1pt solid;
|
||||
border-bottom: gray 1pt solid;
|
||||
|
||||
padding-right: 12pt;
|
||||
padding-left: 12pt;
|
||||
padding-bottom: 12pt;
|
||||
padding-top: 12pt;
|
||||
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
background-color: #E2E9EF;
|
||||
font-size: small; text-align: justify
|
||||
}
|
||||
|
||||
.table_title
|
||||
{
|
||||
background-color: #648CCA;
|
||||
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF;
|
||||
font-weight: bold
|
||||
; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px
|
||||
}
|
||||
|
||||
.table_cells
|
||||
{
|
||||
background-color: #E2E9EF;
|
||||
|
||||
font-family: Geneva, Arial, Helvetica, san-serif;
|
||||
font-size: small
|
||||
; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px
|
||||
}
|
||||
|
||||
.toc
|
||||
{
|
||||
DISPLAY: block;
|
||||
background-color: #E2E9EF
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
|
||||
border-top: gray 1pt solid;
|
||||
border-left: gray 1pt solid;
|
||||
border-bottom: gray 1pt solid;
|
||||
border-right: gray 1pt solid;
|
||||
|
||||
padding-top: 24pt;
|
||||
padding-right: 24pt;
|
||||
padding-left: 24pt;
|
||||
padding-bottom: 24pt;
|
||||
}
|
||||
|
||||
.toc_title
|
||||
{
|
||||
background-color: #648CCA;
|
||||
padding-top: 4px;
|
||||
padding-right: 4px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 4px;
|
||||
font-family: Geneva, Arial, Helvetica, san-serif;
|
||||
color: #FFFFFF;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
.toc_cells
|
||||
{
|
||||
background-color: #E2E9EF;
|
||||
padding-top: 4px;
|
||||
padding-right: 4px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 4px;
|
||||
font-family: Geneva, Arial, Helvetica, san-serif;
|
||||
font-size: small
|
||||
}
|
||||
|
||||
div.logo
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
|
||||
.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
|
||||
.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
|
||||
.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
|
||||
.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
|
||||
.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
|
||||
.updated {
|
||||
font-size: x-small;
|
||||
color: #666666;
|
||||
font-style: italic;
|
||||
}
|
||||
BIN
doc/theme/u_arr.gif
vendored
Normal file
|
After Width: | Height: | Size: 170 B |
BIN
doc/theme/uc.gif
vendored
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
doc/theme/wave.gif
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
972
doc/token_ids.html
Normal file
@@ -0,0 +1,972 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Token Identifiers</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Token Identifiers</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_tokentype.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_fileposition.html"><img src="theme/r_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p><a href="token_ids.html#literal_tokens">Table of literal token identifiers</a><br>
|
||||
<a href="token_ids.html#whitespace_tokens">Table of white token identifiers</a><br>
|
||||
<a href="token_ids.html#keyword_tokens">Table of keyword token identifiers</a><br>
|
||||
<a href="token_ids.html#operator_tokens">Table of operator token identifiers</a><br>
|
||||
<a href="token_ids.html#preprocessor_tokens">Table of preprocessor token identifiers</a></p>
|
||||
</blockquote>
|
||||
<p>The following tables contain all those tokens, which should be recognized by
|
||||
a C++ lexer, which is to be used in conjunction with the <tt>Wave</tt> preprocessing
|
||||
engine. The tokens are grouped into categories to simplify some internal logic
|
||||
and eventually the driver programs. The token identifiers are defined as an
|
||||
<tt>enum</tt>, and it is recommended to reuse this definition for your own lexer
|
||||
implementations.</p>
|
||||
<p>Note though, that the preprocessor engine does some token transformation, so
|
||||
that not all of the listet here token identifiers may occur inside tokens, returned
|
||||
from the preprocessing iterator.</p>
|
||||
<a name="literal_tokens"></a>
|
||||
<table width="70%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="3"> <p class="table_title">List of literal token id's</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <p class="toc_title" width="36%" >Token identifier</p></td>
|
||||
<td> <p class="toc_title" width="28%" >Token category</p></td>
|
||||
<td> <p class="toc_title" width="36%" >Token value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CHARLIT </p></td>
|
||||
<td class="table_cells" width="31%"> <p>CharacterLiteralTokenType</p></td>
|
||||
<td class="table_cells" width="29%"><p><code>'a', '\t', '\u0057'</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_FLOATLIT </p></td>
|
||||
<td class="table_cells" > <p>FloatingLiteralTokenType</p></td>
|
||||
<td class="table_cells" ><code>-1.23456e78</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_IDENTIFIER </p></td>
|
||||
<td class="table_cells" > <p>IdentifierTokenType</p></td>
|
||||
<td class="table_cells" ><code> C++ identifier</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_OCTALINT </p></td>
|
||||
<td class="table_cells" > <p>IntegerLiteralTokenType</p></td>
|
||||
<td class="table_cells" ><code>007</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_DECIMALINT </p></td>
|
||||
<td class="table_cells" > <p>IntegerLiteralTokenType</p></td>
|
||||
<td class="table_cells" ><code>10</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_HEXAINT </p></td>
|
||||
<td class="table_cells" > <p>IntegerLiteralTokenType</p></td>
|
||||
<td class="table_cells" ><code>0x1234</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_INTLIT </p></td>
|
||||
<td class="table_cells" > <p>IntegerLiteralTokenType</p></td>
|
||||
<td class="table_cells" ><code>T_OCTALINT, T_DECIMALINT or T_HEXAINT</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_STRINGLIT </p></td>
|
||||
<td class="table_cells" > <p>StringLiteralTokenType</p></td>
|
||||
<td class="table_cells" ><code>"abc"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_FALSE </p></td>
|
||||
<td class="table_cells" > <p>BoolLiteralTokenType</p></td>
|
||||
<td class="table_cells" ><code>false</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_TRUE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>BoolLiteralTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>true</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<a name="whitespace_tokens"></a>
|
||||
<table width="70%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="3"> <p class="table_title">List of whitespace token id's</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <p class="toc_title" width="36%" >Token identifier</p></td>
|
||||
<td> <p class="toc_title" width="28%" >Token category</p></td>
|
||||
<td> <p class="toc_title" width="36%" >Token value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%"> <p>T_ANY </p></td>
|
||||
<td class="table_cells" width="31%"> <p>UnknownTokenType</p></td>
|
||||
<td class="table_cells" width="29%"> <p><code>any value not matched otherwise</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_CCOMMENT </p></td>
|
||||
<td class="table_cells" > <p>WhiteSpaceTokenType</p></td>
|
||||
<td class="table_cells" > <p><code>/* ... */</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_CPPCOMMENT </p></td>
|
||||
<td class="table_cells" > <p>WhiteSpaceTokenType</p></td>
|
||||
<td class="table_cells" ><code>// ... \n</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_SPACE </p></td>
|
||||
<td class="table_cells" > <p>WhiteSpaceTokenType</p></td>
|
||||
<td class="table_cells" > <p>blank or '\t'</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" > <p>T_SPACE2 </p></td>
|
||||
<td class="table_cells" > <p>WhiteSpaceTokenType</p></td>
|
||||
<td class="table_cells" ><code>'\v' or '\f'</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_EOF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>EOFTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>end of input</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CONTLINE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>EOLTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>'\\' followed by '\n'</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_NEWLINE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>EOLTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>'\n'</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<br>
|
||||
<a name="keyword_tokens"></a>
|
||||
<table width="70%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="3"> <p class="table_title">List of keyword token id's</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <p class="toc_title" width="36%" >Token identifier</p></td>
|
||||
<td> <p class="toc_title" width="28%" >Token category</p></td>
|
||||
<td> <p class="toc_title" width="36%" >Token value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ASM </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>asm</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_AUTO </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>auto</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_BOOL </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>bool</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_BREAK </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>break</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CASE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>case</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CATCH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>catch</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CHAR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>char</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CLASS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>class</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CONST </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>const</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CONSTCAST </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>const_cast</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_CONTINUE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>continue</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DEFAULT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>default</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DEFINED </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>defined</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DELETE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>delete</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DO </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>do</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DOUBLE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>double</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DYNAMICCAST </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>dynamic_cast</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ELSE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>else</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ENUM </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>enum</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_EXPLICIT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>explicit</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_EXPORT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>export</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_EXTERN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>extern</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_FLOAT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>float</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_FOR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>for</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_FRIEND </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>friend</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_GOTO </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>goto</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_IF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>if</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_INLINE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>inline</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_INT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>int</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LONG </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>long</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_MUTABLE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>mutable</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_NAMESPACE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>namespace</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_NEW </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>new</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_OPERATOR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>operator</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PRIVATE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>private</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PROTECTED </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>protected</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PUBLIC </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>public</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_REGISTER </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>register</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_REINTERPRETCAST </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>reinterpret_cast</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RETURN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>return</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SHORT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>short</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SIGNED </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>signed</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SIZEOF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>sizeof</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_STATIC </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>static</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_STATICCAST </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>static_cast</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_STRUCT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>struct</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SWITCH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>switch</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_TEMPLATE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>template</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_THIS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>this</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_THROW </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>throw</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_TRY </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>try</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_TYPEDEF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>typedef</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_TYPEID </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>typeid</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_TYPENAME </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>typename</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_UNION </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>union</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_UNSIGNED </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>unsigned</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_USING </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>using</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_VIRTUAL </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>virtual</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_VOID </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>void</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_VOLATILE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>volatile</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_WCHART </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>wchar_t</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_WHILE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>KeywordTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>while</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<a name="operator_tokens"></a>
|
||||
<table width="70%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="3"> <p class="table_title">List of operator token id's</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <p class="toc_title" width="36%" >Token identifier</p></td>
|
||||
<td> <p class="toc_title" width="28%" >Token category</p></td>
|
||||
<td> <p class="toc_title" width="36%" >Token value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_AND </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>&</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ANDAND </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>&&</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ANDASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>&=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_OR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>|</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ORASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>|=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_XOR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>^</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_XORASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>^=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_COMMA </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>,</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_COLON </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>:</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DIVIDE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>/</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DIVIDEASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>/=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DOT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>.</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_DOTSTAR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>.*</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ELLIPSIS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>...</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_EQUAL </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>==</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_GREATER </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_GREATEREQUAL </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>>=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LEFTBRACE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>{</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LESS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code><</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LESSEQUAL </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code><=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LEFTPAREN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>(</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LEFTBRACKET </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>[</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_MINUS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>-</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_MINUSASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>-=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_MINUSMINUS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>--</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PERCENT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>%</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PERCENTASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>%=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_NOT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>!</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_NOTEQUAL </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>!=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_OROR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>||</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PLUS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>+</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PLUSASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>+=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PLUSPLUS </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>++</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ARROW </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>-></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ARROWSTAR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>->*</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_QUESTION_MARK </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>?</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RIGHTBRACE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RIGHTPAREN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RIGHTBRACKET </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>]</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_COLON_COLON </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>::</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SEMICOLON </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>;</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SHIFTLEFT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code><<</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SHIFTLEFTASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code><<=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SHIFTRIGHT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>>></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_SHIFTRIGHTASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>>>=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_STAR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>*</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_COMPL </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>~</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_STARASSIGN </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>*=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_POUND_POUND </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>##</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_POUND </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_AND_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>bitand</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ANDASSIGN_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>and_eq</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_OR_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>or</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_ORASSIGN_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>or_eq</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_XOR_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>xor</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_XORASSIGN_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>xor_eq</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LEFTBRACE_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code><%</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LEFTBRACKET_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code><:</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_NOT_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>not</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_NOTEQUAL_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>not_eq</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RIGHTBRACE_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>%></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RIGHTBRACKET_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>:></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_COMPL_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>compl</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_POUND_POUND_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>%:%:</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_POUND_ALT </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | AltTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>%:</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_OR_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??!</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_XOR_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??'</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LEFTBRACE_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??<</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_LEFTBRACKET_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??(</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RIGHTBRACE_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_RIGHTBRACKET_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_COMPL_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??-</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_POUND_POUND_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??=??=</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_POUND_TRIGRAPH </p></td>
|
||||
<td class="table_cells" width="31%" > <p>OperatorTokenType | TriGraphTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>??=</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p><br>
|
||||
<a name="preprocessor_tokens"></a> The preprocessor tokens listet in the following
|
||||
table are returned by the C++ lexer only. The preprocessor naturally acts on
|
||||
these tokens and they are not returned by dereferencing the preprocessing iterators.</p>
|
||||
<table width="70%" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="3"> <p class="table_title">List of preprocessor token id's</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <p class="toc_title" width="36%" >Token identifier</p></td>
|
||||
<td> <p class="toc_title" width="28%" >Token category</p></td>
|
||||
<td> <p class="toc_title" width="36%" >Token value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_DEFINE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#define</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_IF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#if</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_IFDEF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#ifdef</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_IFNDEF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#ifndef</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_ELSE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#else</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_ELIF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#elif</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_ENDIF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#endif</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_ERROR </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#error</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_LINE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#line</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_PRAGMA </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#pragma</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_UNDEF </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#undef</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_WARNING </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#warning</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_INCLUDE </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#include "..."</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_QHEADER </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#include <...></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_cells" width="40%" > <p>T_PP_HHEADER </p></td>
|
||||
<td class="table_cells" width="31%" > <p>PPTokenType</p></td>
|
||||
<td class="table_cells" width="29%" ><code>#include ...</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_tokentype.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
<td width="30"><a href="class_reference_fileposition.html"><img src="theme/r_arr.gif" width="20" height="19" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Monday, January 17, 2005 16:39<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
163
doc/tracing_facility.html
Normal file
@@ -0,0 +1,163 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Tracing Facility</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Tracing Facility</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="wave_driver.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="acknowledgements.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>If you ever had the need to debug a macro expansion you had to discover, that
|
||||
your tools provide only little or no support for this task. For this reason
|
||||
the <i>Wave</i> library got a tracing facility, which allows to get selectively
|
||||
some information about the expansion of a certain macro or several macros. </p>
|
||||
<p>The tracing of macro expansions generates a possibly huge amount of information,
|
||||
so it is recommended, that you explicitely enable/disable the tracing for the
|
||||
macro in question only. This may be done with the help of a special, <tt>Wave</tt>
|
||||
specific #pragma:</p>
|
||||
<pre><span class="preprocessor"> #pragma</span> wave trace(enable) <span class="comment">// enable the tracing</span>
|
||||
<span class="comment">// the macro expansions here will be traced</span>
|
||||
<span class="comment">// ...</span>
|
||||
<span class="preprocessor"> #pragma</span> wave trace(disable) <span class="comment">// disable the tracing</span></pre>
|
||||
<p>In C99 mode or when specifying the <tt>--variadics</tt> command line option
|
||||
you may additionally use the <tt>operator _Pragma()</tt> variant to enable/disable
|
||||
the tracing output:</p>
|
||||
<pre><span class="preprocessor"> #define</span> CONCAT(x, y) \
|
||||
<span class="preprocessor">_Pragma</span>(<span class="string">"wave trace(enable)"</span>) \
|
||||
x \
|
||||
<span class="preprocessor">_Pragma</span>(<span class="string">"wave trace(disable)"</span>) \
|
||||
<span class="keyword">##</span> y</pre>
|
||||
<p>This way you have the possibility to enable the tracing during the expansion
|
||||
of a part of a macro only. In the sample shown there is traced the expansion
|
||||
of the macro argument <tt>'x'</tt> only. Note, that the <tt>operator _Pragma()</tt>
|
||||
directives expand to nothing inside the macro expansion result.</p>
|
||||
<p>To see, what the <tt>Wave</tt> driver generates while expanding a simple macro,
|
||||
let's have a look at the tracing output for the following example:</p>
|
||||
<pre ><span class="comment"> // test.cpp</span>
|
||||
<span class="preprocessor"> #define</span> X(x) x<br><span class="preprocessor"> #define</span> Y() 2<br><span class="preprocessor"> #define</span> CONCAT_(x, y) x <span class="keyword">##</span> y
|
||||
<span class="preprocessor"> #define</span> CONCAT(x, y) CONCAT_(x, y)
|
||||
<span class="preprocessor"> #pragma</span> wave trace(enable)
|
||||
<span class="comment"> // this macro expansion is to be traced</span>
|
||||
CONCAT(X(1), Y()) <span class="comment">// should expand to 12</span>
|
||||
<span class="preprocessor"> #pragma</span> wave trace(disable)</pre>
|
||||
<p>When preprocessed with <tt>'wave -t test.trace test.cpp'</tt> the <tt>Wave</tt>
|
||||
driver generates a file <tt>test.trace</tt>, which contains (without the line
|
||||
numbers in front of the lines):</p>
|
||||
<pre> 1: test.cpp(8): CONCAT(X(1), Y())
|
||||
2: test.cpp(5): see macro definition: CONCAT(x, y)
|
||||
3: invoked with
|
||||
4: [
|
||||
5: x = X(1)
|
||||
6: y = Y()
|
||||
7: ]
|
||||
8: [
|
||||
9: test.cpp(2): see macro definition: X(x)
|
||||
10: invoked with
|
||||
11: [
|
||||
12: x = 1
|
||||
13: ]
|
||||
14: [
|
||||
15: 1
|
||||
16: rescanning
|
||||
17: [
|
||||
18: 1
|
||||
19: ]
|
||||
20: ]
|
||||
21: test.cpp(3): see macro definition: Y()
|
||||
22: [
|
||||
23: 2
|
||||
24: rescanning
|
||||
25: [
|
||||
26: 2
|
||||
27: ]
|
||||
28: ]
|
||||
29: CONCAT_(1, 2)
|
||||
30: rescanning
|
||||
31: [
|
||||
32: test.cpp(4): see macro definition: CONCAT_(x, y)
|
||||
33: invoked with
|
||||
34: [
|
||||
35: x = 1
|
||||
36: y = 2
|
||||
37: ]
|
||||
38: [
|
||||
39: 12
|
||||
40: rescanning
|
||||
41: [
|
||||
42: 12
|
||||
43: ]
|
||||
44: ]
|
||||
45: 12
|
||||
46: ]
|
||||
47: ]
|
||||
</pre>
|
||||
<p>The generated trace output is very verbose, but allows to follow every step
|
||||
of the actual macro expansion process. The first line in this tracing example
|
||||
contains the reference to the position, from where the macro expansion was initiated.
|
||||
Additionally the following information is contained for every single macro expansion:</p>
|
||||
<ul>
|
||||
<li>The reference to the position, where the macro to expand was defined first
|
||||
(see lines 2, 9, 21 and 32).</li>
|
||||
<li>The real parameters supplied for this macro expansion (see lines 3, 10 and
|
||||
33), this information is traced inside the <tt>invoked with</tt> block, where
|
||||
the corresponding formal and actual parameters are listed.</li>
|
||||
<li>The expansion of the given arguments (if any and if these are defined as
|
||||
macros). This repeats the full tracing information for the argument macro
|
||||
expansion, only intended by one level. Note though, that the macro expansion
|
||||
of the actual arguments is traced, regardless of the fact, if this argument
|
||||
is really to be inserted into the replacement list only after its expansion
|
||||
or as it was initially supplied (see C++ Standard [16.3.1.1]: "A parameter
|
||||
in the replacement list, unless preceded by a <tt>#</tt> or <tt>##</tt> preprocessing
|
||||
token or followed by a <tt>##</tt> preprocessing token, is replaced by the
|
||||
corresponding argument after all macros contained therein have been expanded"
|
||||
<a href="references.html#iso_cpp">[1]</a>). </li>
|
||||
<li>The result of the argument substitution (see lines 15, 23, 29 and 39), i.e.
|
||||
the substituted replacement list.</li>
|
||||
<li>The rescanning process, which again includes the full subsequent macro expansion
|
||||
process of all found macros (see C++ Standard [16.3.4.1]: "After all
|
||||
parameters in the replacement list have been substituted, the resulting preprocessing
|
||||
token sequence is rescanned with all subsequent preprocessing tokens of the
|
||||
source file for more macro names to replace." <a href="references.html#iso_cpp">[1]</a>).</li>
|
||||
<li>The result of the actual macro expansion (this is the last line inside the
|
||||
corresponding rescanning block - see lines 18, 26, 42 and 45).</li>
|
||||
</ul>
|
||||
<p>Every found macro to expand will add an additional indentation level inside
|
||||
the trace output.</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="wave_driver.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="acknowledgements.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Wednesday, February 9, 2005 23:37<!-- #EndDate -->
|
||||
</span>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- #BeginDate format:fcAm1m -->Wednesday, February 9, 2005 23:37<!-- #EndDate -->
|
||||
219
doc/wave_driver.html
Normal file
@@ -0,0 +1,219 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Wave Driver</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">The
|
||||
Wave Driver</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="samples.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="tracing_facility.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>There is implemented a driver program for the <tt>Wave</tt> library, which
|
||||
utilizes nearly all capabilities of the library. It is usable as a preprocessor executable
|
||||
on top of any other C++ compiler. It outputs the textual representation of the
|
||||
preprocessed tokens generated from a given input file. This driver program has
|
||||
the following command line syntax:</p>
|
||||
<pre>Usage: wave [options] [@config-file(s)] file:
|
||||
|
||||
Options allowed on the command line only:
|
||||
-h [--help]: print out program usage (this message)
|
||||
-v [--version]: print the version number
|
||||
-c [--copyright]: print out the copyright statement
|
||||
--config-file filepath: specify a config file (alternatively: @filepath)
|
||||
|
||||
Options allowed additionally in a config file:
|
||||
-o [--output] path: specify a file to use for output instead of stdout
|
||||
-I [--include] path: specify an additional include directory
|
||||
-S [--sysinclude] syspath: specify an additional system include directory
|
||||
-F [--forceinclude] file: force inclusion of the given file
|
||||
-D [--define] macro[=[value]]: specify a macro to define
|
||||
-P [--predefine] macro[=[value]]: specify a macro to predefine
|
||||
-U [--undefine] macro: specify a macro to undefine
|
||||
-n [--nesting] depth: specify a new maximal include nesting depth
|
||||
|
||||
Extended options (allowed everywhere)
|
||||
-t [--traceto] path: output trace info to a file [path] or to stderr [-]
|
||||
--timer output overall elapsed computing time
|
||||
--variadics: enable variadics and placemarkers in C++ mode
|
||||
--c99: enable C99 mode (implies variadics and placemarkers)
|
||||
|
||||
</pre>
|
||||
<P dir="ltr">The possible options are straightforward and self explanatory. The
|
||||
following describes some of these options in more detail. Please note, that
|
||||
the extended options (--c99 and --variadics) are available only, if the driver
|
||||
was compiled with the constant <tt>WAVE_SUPPORT_VARIADICS_PLACEMARKERS</tt>
|
||||
defined. </P>
|
||||
<P dir="ltr">-o [--output] path</P>
|
||||
<blockquote>
|
||||
<p dir="ltr">Specify a filename to be used for the generated preprocessed output
|
||||
stream. If this option is not given, then the standard output is used (stdout).</p>
|
||||
</blockquote>
|
||||
<P dir="ltr">-I [--include] option</P>
|
||||
<blockquote>
|
||||
<p dir="ltr">Add the given directory to the head of the list of directories
|
||||
to be searched for header files. This can be used to override a system header
|
||||
file, substituting your own version, since these directories are searched
|
||||
before the system header file directories. If you use more than one '-I' option, the directories are scanned in left-to-right order, the system directories
|
||||
come after. </p>
|
||||
</blockquote>
|
||||
<p dir="ltr">-I- [--include-] option</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">The <tt>Wave</tt> library maintains two separate search pathes
|
||||
for include files. A search path for user include files and a search path
|
||||
for system include files. Any directories specified with '-I' options before
|
||||
an eventually given '-I-' option are searched only for the case of '#include "file"'
|
||||
(user include files), they are not searched for '#include <file>'
|
||||
directives (system include files). If additional directories are specified
|
||||
with '-I' options after a '-I-' option was given, these directories are searched
|
||||
for all '#include' directives. In addition, the '-I-' option inhibits the
|
||||
use of the current directory as the first search directory for '#include "file"'
|
||||
directives. Therefore, the current directory is searched only if it is requested
|
||||
explicitly with a '-I.' option. Specifying both '-I-' and '-I.' allows to
|
||||
control precisely which directories are searched before the current one and
|
||||
which are searched after.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">-S [--sysinclude] option</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Add the given directory to the head of the list of directories
|
||||
to be searched for system header files. If you use more than one '-S' option,
|
||||
the directories are scanned in left-to-right order. This option is most useful
|
||||
in the wave.cfg configuration file to specify, where the system include files
|
||||
are to be searched.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">-F [--forceinclude] option</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Process the given file as normal input and include all the resulting
|
||||
output before the processing the regular input file starts. If more than one
|
||||
such option is given, the files are pre-included in the sequence of its occurance
|
||||
on the command line.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">-D [--define] macro[=definition]<br>-P [--predefine] macro[=definition]</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">This option allows to define ('-D') or predefine ('-P') a macro
|
||||
from the command line. The string given in conjunction with the '-D' or '-P'
|
||||
option should conform to the usual syntax MACRO(x)=definition as is described
|
||||
in more detail <a href="class_reference_context.html#add_macro_definition">here</a>.</p>
|
||||
<p dir="ltr"> The only difference between the '-D' and the '-P' options is,
|
||||
that the latter predefines a macro such, that it is <b>not</b> undefinable
|
||||
through an <tt>#undef</tt> directive from inside the preprocessed program.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">-U [--undefine] option</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">This allows to undefine some of the automatically predefined macros
|
||||
of the <tt>Wave</tt> library (see Predefined macros). The only exception are
|
||||
the <code class="keyword">__LINE__</code>, <code class="keyword">__FILE__</code>,
|
||||
<code class="keyword">__DATE__</code>, <code class="keyword">__TIME__</code>,
|
||||
<code class="keyword">__STDC__</code> and <code class="keyword">__cplusplus</code>
|
||||
predefined macros, which are not undefinable. If -U and -D are both specified
|
||||
for one name, the name is not predefined.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">-n [--nesting] depth</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Specify a new maximal include nesting depth. If the preprocessing
|
||||
reaches this include file nesting depth, it aborts the preprocessing after
|
||||
emitting an error message. The default include file nesting depth is 1024.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">-t [--traceto] path</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Enable the tracing facility build into the <tt>Wave</tt> library.
|
||||
The path specifies the filename to use for the output of the generated trace
|
||||
log. If the filename given equals to <tt>'-'</tt> (without the quotes), the
|
||||
trace log is put into the standard error stream (stderr).</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">--timer</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Enable to track the overall elapsed computing time required for
|
||||
the given input file. The elapsed time is printed to stdout after the compilation
|
||||
is completed.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">--variadics</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Enables support for variadics (macros with variable parameter lists),
|
||||
placemarkers (empty macro arguments) and <tt>operator _Pragma</tt> in
|
||||
normal C++ mode. This option predefines a special predefined macro <tt>__WAVE_HAS_VARIADICS__</tt>.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">--c99</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Enable the C99 mode. This mode enables certain C99 specific features
|
||||
as variadics (macros with variable parameter lists), placemarkers (empty macro
|
||||
arguments) and <tt>operator _Pragma</tt> support and disables some C++
|
||||
specific token types as for instance <tt>'::'</tt>, <tt>'->*'</tt> and <tt>'->.'</tt>.
|
||||
Several predefined macros are different for this mode, for more information
|
||||
about predefined macros you may look <a href="predefined_macros.html">here</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">@ [--config-file] option</p>
|
||||
<blockquote>
|
||||
<p dir="ltr">Some of the possible command line options may be specified inside
|
||||
of special configuration files. This is very useful, as a shorthand for different
|
||||
global configurations. A config file may contain additional options (-I, -S,
|
||||
-F, -U, -D and -P options), one option per line. Empty lines and lines beginning
|
||||
with a '#' character are ignored (are treated as a comment lines). Note that
|
||||
the '#' character is treated as the beginning of a comment only, if it is
|
||||
the first non-whitespace character on a line. Here is a small sample illustrating the supported configuration file syntax:</p>
|
||||
<pre><span class="comment"> #
|
||||
# enable variadics et.al. in C++ mode
|
||||
#</span>
|
||||
--variadics
|
||||
<span class="comment"> #
|
||||
# enable timer support
|
||||
#
|
||||
</span> --timer
|
||||
<span class="comment"> #
|
||||
# emulate gcc V3.3.2
|
||||
#
|
||||
</span> -D__GNUC__=3
|
||||
-D__GNUC_MINOR__=3
|
||||
-D__GNUC_PATCHLEVEL__=2
|
||||
-D__GNUG__
|
||||
<span class="comment"> #
|
||||
# add Boost to the system include search paths
|
||||
#</span>
|
||||
-S/usr/local/boost</pre>
|
||||
<p dir="ltr"> There is a shorthand for specifying a configuration file on the
|
||||
command line: simply use the '@' character immediatly before the corresponding
|
||||
file name.</p>
|
||||
<p dir="ltr"> The options found in a configuration file are interpreted, as
|
||||
if they were place instead of the configuration file option on the command
|
||||
line.</p>
|
||||
</blockquote>
|
||||
<p dir="ltr">The <tt>Wave</tt> driver program looks at startup for a configuration
|
||||
file named 'wave.cfg' in the same directory, where it was started from (where
|
||||
is located the driver executable). If this file exists, it is treated as a normal
|
||||
configuration file and the specified herein options are interpreted as if they
|
||||
were given as the first options on the command line. This feature is very useful
|
||||
for defining a global environment for the <tt>Wave</tt> preprocessor driver.</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="10"></td>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="samples.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="tracing_facility.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Friday, February 18, 2005 12:33<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
21
include/boost/wave.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(WAVE_HPP_DCA0EA51_EF5B_4BF1_88A8_461DBC5F292B_INCLUDED)
|
||||
#define WAVE_HPP_DCA0EA51_EF5B_4BF1_88A8_461DBC5F292B_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
#include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/cpp_context.hpp>
|
||||
|
||||
#endif // !defined(WAVE_HPP_DCA0EA51_EF5B_4BF1_88A8_461DBC5F292B_INCLUDED)
|
||||
300
include/boost/wave/cpp_context.hpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
Definition of the preprocessor context
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
|
||||
#define CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include <boost/wave/util/unput_queue_iterator.hpp>
|
||||
#include <boost/wave/util/cpp_ifblock.hpp>
|
||||
#include <boost/wave/util/cpp_include_pathes.hpp>
|
||||
#include <boost/wave/util/iteration_context.hpp>
|
||||
#include <boost/wave/util/cpp_iterator.hpp>
|
||||
#include <boost/wave/util/cpp_macromap.hpp>
|
||||
|
||||
#include <boost/wave/preprocessing_hooks.hpp>
|
||||
#include <boost/wave/cpp_iteration_context.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The C preprocessor context template class
|
||||
//
|
||||
// The boost::wave::context template is the main interface class to
|
||||
// control the behaviour of the preprocessing engine.
|
||||
//
|
||||
// The following template parameters has to be supplied:
|
||||
//
|
||||
// IteratorT The iterator type of the underlying input stream
|
||||
// LexIteratorT The lexer iterator type to use as the token factory
|
||||
// InputPolicyT The input policy type to use for loading the files
|
||||
// to be included. This template parameter is optional and
|
||||
// defaults to the
|
||||
// iteration_context_policies::load_file_to_string
|
||||
// type
|
||||
// TraceT The trace policy to use for trace and include file
|
||||
// notification callback.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <
|
||||
typename IteratorT,
|
||||
typename LexIteratorT,
|
||||
typename InputPolicyT = iteration_context_policies::load_file_to_string,
|
||||
typename TraceT = context_policies::default_preprocessing_hooks
|
||||
>
|
||||
class context {
|
||||
|
||||
public:
|
||||
|
||||
// concept checks
|
||||
// the given iterator shall be at least a forward iterator type
|
||||
BOOST_CLASS_REQUIRE(IteratorT, boost, ForwardIteratorConcept);
|
||||
|
||||
// public typedefs
|
||||
typedef typename LexIteratorT::token_type token_type;
|
||||
typedef context<IteratorT, LexIteratorT, InputPolicyT, TraceT>
|
||||
self_type;
|
||||
|
||||
typedef IteratorT target_iterator_type;
|
||||
typedef LexIteratorT lexer_type;
|
||||
typedef pp_iterator<self_type> iterator_type;
|
||||
|
||||
typedef InputPolicyT input_policy_type;
|
||||
typedef typename token_type::position_type position_type;
|
||||
|
||||
// type of a token sequence
|
||||
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
|
||||
token_sequence_type;
|
||||
|
||||
// types of the policies
|
||||
typedef TraceT trace_policy_type;
|
||||
|
||||
private:
|
||||
// stack of shared_ptr's to the pending iteration contexts
|
||||
typedef boost::shared_ptr<base_iteration_context<lexer_type> >
|
||||
iteration_ptr_type;
|
||||
typedef boost::wave::util::iteration_context_stack<iteration_ptr_type>
|
||||
iteration_context_stack_type;
|
||||
typedef typename iteration_context_stack_type::size_type iter_size_type;
|
||||
|
||||
public:
|
||||
context(target_iterator_type const &first_, target_iterator_type const &last_,
|
||||
char const *fname = "<Unknown>", TraceT const &trace_ = TraceT())
|
||||
: first(first_), last(last_), filename(fname)
|
||||
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
|
||||
, current_filename(fname)
|
||||
#endif
|
||||
, macros(*this), language(boost::wave::support_cpp), trace(trace_)
|
||||
{
|
||||
macros.init_predefined_macros(fname);
|
||||
includes.init_initial_path();
|
||||
includes.set_current_directory(filename.c_str());
|
||||
}
|
||||
|
||||
// iterator interface
|
||||
iterator_type begin()
|
||||
{
|
||||
return iterator_type(*this, first, last, position_type(filename.c_str()),
|
||||
get_language());
|
||||
}
|
||||
iterator_type end() const
|
||||
{ return iterator_type(); }
|
||||
|
||||
// maintain include paths
|
||||
bool add_include_path(char const *path_)
|
||||
{ return includes.add_include_path(path_, false);}
|
||||
bool add_sysinclude_path(char const *path_)
|
||||
{ return includes.add_include_path(path_, true);}
|
||||
void set_sysinclude_delimiter() { includes.set_sys_include_delimiter(); }
|
||||
typename iteration_context_stack_type::size_type get_iteration_depth() const
|
||||
{ return iter_ctxs.size(); }
|
||||
|
||||
// maintain defined macros
|
||||
#if BOOST_WAVE_ENABLE_COMMANDLINE_MACROS != 0
|
||||
bool add_macro_definition(std::string macrostring,
|
||||
bool is_predefined = false)
|
||||
{ return boost::wave::util::add_macro_definition(*this, macrostring,
|
||||
is_predefined, get_language()); }
|
||||
#endif
|
||||
bool add_macro_definition(token_type const &name, bool has_params,
|
||||
std::vector<token_type> ¶meters, token_sequence_type &definition,
|
||||
bool is_predefined = false)
|
||||
{ return macros.add_macro(name, has_params, parameters, definition,
|
||||
is_predefined); }
|
||||
template <typename IteratorT2>
|
||||
bool is_defined_macro(IteratorT2 const &begin, IteratorT2 const &end)
|
||||
{ return macros.is_defined(begin, end); }
|
||||
bool remove_macro_definition(typename token_type::string_type const &name,
|
||||
bool even_predefined = false)
|
||||
{ return macros.remove_macro(name, even_predefined); }
|
||||
void reset_macro_definitions()
|
||||
{ macros.reset_macromap(); macros.init_predefined_macros(); }
|
||||
|
||||
// get the pp-iterator version information
|
||||
static std::string get_version()
|
||||
{ return boost::wave::util::predefined_macros::get_fullversion(false); }
|
||||
static std::string get_version_string()
|
||||
{ return boost::wave::util::predefined_macros::get_versionstr(false); }
|
||||
|
||||
void set_language(boost::wave::language_support language_)
|
||||
{
|
||||
language = language_;
|
||||
reset_macro_definitions();
|
||||
}
|
||||
boost::wave::language_support get_language() const { return language; }
|
||||
|
||||
// change and ask for maximal possible include nesting depth
|
||||
void set_max_include_nesting_depth(iter_size_type new_depth)
|
||||
{ iter_ctxs.set_max_include_nesting_depth(new_depth); }
|
||||
iter_size_type get_max_include_nesting_depth() const
|
||||
{ return iter_ctxs.get_max_include_nesting_depth(); }
|
||||
|
||||
// access the trace policy
|
||||
trace_policy_type &get_trace_policy()
|
||||
{ return trace; }
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
protected:
|
||||
friend class boost::wave::pp_iterator<
|
||||
boost::wave::context<IteratorT, lexer_type, InputPolicyT, TraceT> >;
|
||||
friend class boost::wave::impl::pp_iterator_functor<
|
||||
boost::wave::context<IteratorT, lexer_type, InputPolicyT, TraceT> >;
|
||||
#endif
|
||||
|
||||
// maintain include pathes (helper functions)
|
||||
bool find_include_file (std::string &s, bool is_system,
|
||||
char const *current_file) const
|
||||
{ return includes.find_include_file(s, is_system, current_file); }
|
||||
void set_current_directory(char const *path_)
|
||||
{ includes.set_current_directory(path_); }
|
||||
|
||||
// conditional compilation contexts
|
||||
bool get_if_block_status() const { return ifblocks.get_status(); }
|
||||
void enter_if_block(bool new_status)
|
||||
{ ifblocks.enter_if_block(new_status); }
|
||||
bool enter_elif_block(bool new_status)
|
||||
{ return ifblocks.enter_elif_block(new_status); }
|
||||
bool enter_else_block() { return ifblocks.enter_else_block(); }
|
||||
bool exit_if_block() { return ifblocks.exit_if_block(); }
|
||||
typename boost::wave::util::if_block_stack::size_type get_if_block_depth() const
|
||||
{ return ifblocks.get_if_block_depth(); }
|
||||
|
||||
// stack of iteration contexts
|
||||
iteration_ptr_type pop_iteration_context()
|
||||
{ iteration_ptr_type top = iter_ctxs.top(); iter_ctxs.pop(); return top; }
|
||||
void push_iteration_context(position_type const &act_pos, iteration_ptr_type iter_ctx)
|
||||
{ iter_ctxs.push(act_pos, iter_ctx); }
|
||||
|
||||
position_type &get_main_pos() { return macros.get_main_pos(); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// expand_tokensequence():
|
||||
// expands all macros contained in a given token sequence, handles '##'
|
||||
// and '#' pp operators and re-scans the resulting sequence
|
||||
// (essentially preprocesses the token sequence).
|
||||
//
|
||||
// The expand_undefined parameter is true during macro expansion inside
|
||||
// a C++ expression given for a #if or #elif statement.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT2>
|
||||
token_type expand_tokensequence(IteratorT2 &first, IteratorT2 const &last,
|
||||
token_sequence_type &pending, token_sequence_type &expanded,
|
||||
bool expand_undefined = false)
|
||||
{
|
||||
return macros.expand_tokensequence(first, last, pending, expanded,
|
||||
expand_undefined);
|
||||
}
|
||||
|
||||
template <typename IteratorT2>
|
||||
void expand_whole_tokensequence(IteratorT2 &first, IteratorT2 const &last,
|
||||
token_sequence_type &expanded, bool expand_undefined = true)
|
||||
{
|
||||
macros.expand_whole_tokensequence(expanded, first, last,
|
||||
expand_undefined);
|
||||
|
||||
// remove any contained placeholder
|
||||
boost::wave::util::impl::remove_placeholders(expanded);
|
||||
}
|
||||
|
||||
public:
|
||||
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
|
||||
// support for #pragma once
|
||||
// maintain the real name of the current preprocessed file
|
||||
void set_current_filename(char const *real_name)
|
||||
{ current_filename = real_name; }
|
||||
std::string const &get_current_filename() const
|
||||
{ return current_filename; }
|
||||
|
||||
// maintain the list of known headers containing #pragma once
|
||||
bool has_pragma_once(std::string const &filename)
|
||||
{ return includes.has_pragma_once(filename); }
|
||||
bool add_pragma_once_header(std::string const &filename)
|
||||
{ return includes.add_pragma_once_header(filename); }
|
||||
#endif
|
||||
|
||||
// forwarding functions for the context policy hooks
|
||||
template <typename ContainerT>
|
||||
bool interpret_pragma(ContainerT &pending, token_type const &option,
|
||||
ContainerT const &values, token_type const &act_token)
|
||||
{
|
||||
return trace.interpret_pragma(*this, pending, option, values,
|
||||
act_token);
|
||||
}
|
||||
template <typename ParametersT, typename DefinitionT>
|
||||
void defined_macro(token_type const &name, bool is_functionlike,
|
||||
ParametersT const ¶meters, DefinitionT const &definition,
|
||||
bool is_predefined)
|
||||
{
|
||||
trace.defined_macro(name, is_functionlike, parameters, definition,
|
||||
is_predefined);
|
||||
}
|
||||
void undefined_macro(typename token_type::string_type const &name)
|
||||
{
|
||||
trace.undefined_macro(name);
|
||||
}
|
||||
|
||||
private:
|
||||
// the main input stream
|
||||
target_iterator_type first; // underlying input stream
|
||||
target_iterator_type last;
|
||||
std::string filename; // associated main filename
|
||||
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
|
||||
std::string current_filename; // real name of current preprocessed file
|
||||
#endif
|
||||
|
||||
boost::wave::util::if_block_stack ifblocks; // conditional compilation contexts
|
||||
boost::wave::util::include_pathes includes; // lists of include directories to search
|
||||
iteration_context_stack_type iter_ctxs; // iteration contexts
|
||||
boost::wave::util::macromap<self_type> macros; // map of defined macros
|
||||
boost::wave::language_support language; // supported language/extensions
|
||||
trace_policy_type trace; // trace policy instance
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
|
||||
282
include/boost/wave/cpp_exceptions.hpp
Normal file
@@ -0,0 +1,282 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED)
|
||||
#define CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// helper macro for throwing exceptions
|
||||
#if !defined(BOOST_WAVE_THROW)
|
||||
#ifdef BOOST_NO_STRINGSTREAM
|
||||
#include <strstream>
|
||||
#define BOOST_WAVE_THROW(cls, code, msg, act_pos) \
|
||||
{ \
|
||||
using namespace boost::wave; \
|
||||
std::strstream stream; \
|
||||
stream << cls::severity_text(cls::code) << ": " \
|
||||
<< cls::error_text(cls::code); \
|
||||
if ((msg)[0] != 0) stream << ": " << (msg); \
|
||||
stream << std::ends; \
|
||||
std::string throwmsg = stream.str(); stream.freeze(false); \
|
||||
throw cls(throwmsg.c_str(), cls::code, (act_pos).get_line(), \
|
||||
(act_pos).get_column(), (act_pos).get_file().c_str()); \
|
||||
} \
|
||||
/**/
|
||||
#else
|
||||
#include <sstream>
|
||||
#define BOOST_WAVE_THROW(cls, code, msg, act_pos) \
|
||||
{ \
|
||||
using namespace boost::wave; \
|
||||
std::stringstream stream; \
|
||||
stream << cls::severity_text(cls::code) << ": " \
|
||||
<< cls::error_text(cls::code); \
|
||||
if ((msg)[0] != 0) stream << ": " << (msg); \
|
||||
stream << std::ends; \
|
||||
throw cls(stream.str().c_str(), cls::code, (act_pos).get_line(), \
|
||||
(act_pos).get_column(), (act_pos).get_file().c_str()); \
|
||||
} \
|
||||
/**/
|
||||
#endif // BOOST_NO_STRINGSTREAM
|
||||
#endif // BOOST_WAVE_THROW
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// exception severity
|
||||
namespace util {
|
||||
|
||||
enum severity {
|
||||
severity_remark = 0,
|
||||
severity_warning,
|
||||
severity_error,
|
||||
severity_fatal,
|
||||
severity_commandline_error
|
||||
};
|
||||
|
||||
inline char const *
|
||||
get_severity(severity level)
|
||||
{
|
||||
static char const *severity_text[] =
|
||||
{
|
||||
"remark", // severity_remark
|
||||
"warning", // severity_warning
|
||||
"error", // severity_error
|
||||
"fatal error", // severity_fatal
|
||||
"command line error" // severity_commandline_error
|
||||
};
|
||||
BOOST_ASSERT(severity_remark <= level &&
|
||||
level <= severity_commandline_error);
|
||||
return severity_text[level];
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// cpp_exception, the base class for all specific C preprocessor exceptions
|
||||
class cpp_exception
|
||||
: public std::exception
|
||||
{
|
||||
public:
|
||||
cpp_exception(int line_, int column_, char const *filename_) throw()
|
||||
: line(line_), column(column_)
|
||||
{
|
||||
unsigned int off = 0;
|
||||
while (off < sizeof(filename) && *filename_)
|
||||
filename[off++] = *filename_++;
|
||||
filename[off] = 0;
|
||||
}
|
||||
~cpp_exception() throw() {}
|
||||
|
||||
virtual char const *what() const throw() = 0; // to be overloaded
|
||||
virtual char const *description() const throw() = 0;
|
||||
|
||||
int line_no() const throw() { return line; }
|
||||
int column_no() const throw() { return column; }
|
||||
char const *file_name() const throw() { return filename; }
|
||||
|
||||
protected:
|
||||
char filename[512];
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// preprocessor error
|
||||
class preprocess_exception :
|
||||
public cpp_exception
|
||||
{
|
||||
public:
|
||||
enum error_code {
|
||||
unexpected_error = 0,
|
||||
macro_redefinition,
|
||||
macro_insertion_error,
|
||||
bad_include_file,
|
||||
bad_include_statement,
|
||||
ill_formed_directive,
|
||||
error_directive,
|
||||
warning_directive,
|
||||
ill_formed_expression,
|
||||
missing_matching_if,
|
||||
missing_matching_endif,
|
||||
ill_formed_operator,
|
||||
bad_define_statement,
|
||||
too_few_macroarguments,
|
||||
too_many_macroarguments,
|
||||
improperly_terminated_macro,
|
||||
bad_line_statement,
|
||||
bad_undefine_statement,
|
||||
bad_macro_definition,
|
||||
illegal_redefinition,
|
||||
duplicate_parameter_name,
|
||||
invalid_concat,
|
||||
last_line_not_terminated,
|
||||
ill_formed_pragma_option,
|
||||
include_nesting_too_deep,
|
||||
misplaced_operator,
|
||||
alreadydefined_name,
|
||||
undefined_macroname,
|
||||
invalid_macroname,
|
||||
unexpected_qualified_name,
|
||||
division_by_zero
|
||||
};
|
||||
|
||||
preprocess_exception(char const *what_, error_code code, int line_,
|
||||
int column_, char const *filename_) throw()
|
||||
: cpp_exception(line_, column_, filename_), level(severity_level(code))
|
||||
{
|
||||
unsigned int off = 0;
|
||||
while (off < sizeof(buffer) && *what_)
|
||||
buffer[off++] = *what_++;
|
||||
buffer[off] = 0;
|
||||
}
|
||||
~preprocess_exception() throw() {}
|
||||
|
||||
virtual char const *what() const throw()
|
||||
{
|
||||
return "boost::wave::preprocess_exception";
|
||||
}
|
||||
virtual char const *description() const throw()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
util::severity get_severity()
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
static char const *error_text(int code)
|
||||
{
|
||||
// error texts in this array must appear in the same order as the items in
|
||||
// the error enum above
|
||||
static char const *preprocess_exception_errors[] = {
|
||||
"unexpected error (should not happen)", // unexpected_error
|
||||
"illegal macro redefinition", // macro_redefinition
|
||||
"macro definition failed (out of memory?)", // macro_insertion_error
|
||||
"could not find include file", // bad_include_file
|
||||
"ill formed #include directive", // bad_include_statement
|
||||
"ill formed preprocessor directive", // ill_formed_directive
|
||||
"encountered #error directive or #pragma wave stop()", // error_directive
|
||||
"encountered #warning directive", // warning_directive
|
||||
"ill formed preprocessor expression", // ill_formed_expression
|
||||
"the #if for this directive is missing", // missing_matching_if
|
||||
"detected at least one missing #endif directive", // missing_matching_endif
|
||||
"ill formed preprocessing operator", // ill_formed_operator
|
||||
"ill formed #define directive", // bad_define_statement
|
||||
"too few macro arguments", // too_few_macroarguments
|
||||
"too many macro arguments", // too_many_macroarguments
|
||||
"improperly terminated macro invocation "
|
||||
"or replacement-list terminates in partial "
|
||||
"macro expansion (not supported yet)", // improperly_terminated_macro
|
||||
"ill formed #line directive", // bad_line_statement
|
||||
"#undef may not be used on this predefined name", // bad_undefine_statement
|
||||
"invalid macro definition", // bad_macro_definition
|
||||
"this predefined name may not be redefined", // illegal_redefinition
|
||||
"duplicate macro parameter name", // duplicate_parameter_name
|
||||
"pasting the following two tokens does not "
|
||||
"give a valid preprocessing token", // invalid_concat
|
||||
"last line of file ends without a newline", // last_line_not_terminated
|
||||
"unknown or illformed pragma option", // ill_formed_pragma_option
|
||||
"include files nested too deep", // include_nesting_too_deep
|
||||
"misplaced operator defined()", // misplaced_operator
|
||||
"the name is already used in this scope as "
|
||||
"a macro or scope name", // alreadydefined_name
|
||||
"undefined macro or scope name may not be imported", // undefined_macroname
|
||||
"ill formed macro name", // invalid_macroname
|
||||
"qualified names are supported in C++0x mode only", // unexpected_qualified_name
|
||||
"division by zero in preprocessor expression" // division_by_zero
|
||||
};
|
||||
BOOST_ASSERT(unexpected_error <= code &&
|
||||
code <= division_by_zero);
|
||||
return preprocess_exception_errors[code];
|
||||
}
|
||||
|
||||
static util::severity severity_level(int code)
|
||||
{
|
||||
static util::severity preprocess_exception_severity[] = {
|
||||
util::severity_fatal, // unexpected_error
|
||||
util::severity_warning, // macro_redefinition
|
||||
util::severity_fatal, // macro_insertion_error
|
||||
util::severity_error, // bad_include_file
|
||||
util::severity_error, // bad_include_statement
|
||||
util::severity_error, // ill_formed_directive
|
||||
util::severity_fatal, // error_directive
|
||||
util::severity_warning, // warning_directive
|
||||
util::severity_error, // ill_formed_expression
|
||||
util::severity_error, // missing_matching_if
|
||||
util::severity_error, // missing_matching_endif
|
||||
util::severity_error, // ill_formed_operator
|
||||
util::severity_error, // bad_define_statement
|
||||
util::severity_warning, // too_few_macroarguments
|
||||
util::severity_warning, // too_many_macroarguments
|
||||
util::severity_error, // improperly_terminated_macro
|
||||
util::severity_warning, // bad_line_statement
|
||||
util::severity_warning, // bad_undefine_statement
|
||||
util::severity_commandline_error, // bad_macro_definition
|
||||
util::severity_warning, // illegal_redefinition
|
||||
util::severity_error, // duplicate_parameter_name
|
||||
util::severity_error, // invalid_concat
|
||||
util::severity_warning, // last_line_not_terminated
|
||||
util::severity_warning, // ill_formed_pragma_option
|
||||
util::severity_fatal, // include_nesting_too_deep
|
||||
util::severity_error, // misplaced_operator
|
||||
util::severity_error, // alreadydefined_name
|
||||
util::severity_error, // undefined_macroname
|
||||
util::severity_error, // invalid_macroname
|
||||
util::severity_error, // unexpected_qualified_name
|
||||
util::severity_fatal // division_by_zero
|
||||
};
|
||||
BOOST_ASSERT(unexpected_error <= code &&
|
||||
code <= division_by_zero);
|
||||
return preprocess_exception_severity[code];
|
||||
}
|
||||
static char const *severity_text(int code)
|
||||
{
|
||||
return util::get_severity(severity_level(code));
|
||||
}
|
||||
|
||||
private:
|
||||
char buffer[512];
|
||||
util::severity level;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED)
|
||||
193
include/boost/wave/cpp_iteration_context.hpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
Definition of the preprocessor context
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)
|
||||
#define CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED
|
||||
|
||||
#include <iterator>
|
||||
#include <fstream>
|
||||
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
#include <boost/wave/util/file_position.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace iteration_context_policies {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The iteration_context_policies templates are policies for the
|
||||
// boost::wave::iteration_context which allows to control, how a given input file
|
||||
// is to be represented by a pair of iterators pointing to the begin and
|
||||
// the end of the resulting input sequence.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// load_file_to_string
|
||||
//
|
||||
// Loads a file into a string and returns the iterators pointing to
|
||||
// the beginning and the end of the loaded string.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct load_file_to_string {
|
||||
|
||||
template <typename IterContextT>
|
||||
class inner {
|
||||
|
||||
public:
|
||||
template <typename PositionT>
|
||||
static
|
||||
void init_iterators(IterContextT &iter_ctx,
|
||||
PositionT const &act_pos)
|
||||
{
|
||||
typedef typename IterContextT::iterator_type iterator_type;
|
||||
|
||||
std::ifstream instream(iter_ctx.filename.c_str());
|
||||
if (!instream.is_open()) {
|
||||
BOOST_WAVE_THROW(preprocess_exception, bad_include_file,
|
||||
iter_ctx.filename, act_pos);
|
||||
}
|
||||
instream.unsetf(std::ios::skipws);
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
|
||||
// this is known to be very slow for large files on some systems
|
||||
std::copy (istream_iterator<char>(instream),
|
||||
istream_iterator<char>(),
|
||||
std::inserter(iter_ctx.instring, iter_ctx.instring.end()));
|
||||
#else
|
||||
iter_ctx.instring = std::string(
|
||||
std::istreambuf_iterator<char>(instream.rdbuf()),
|
||||
std::istreambuf_iterator<char>());
|
||||
#endif // defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
|
||||
|
||||
iter_ctx.first = iterator_type(iter_ctx.instring.begin(),
|
||||
iter_ctx.instring.end(), PositionT(iter_ctx.filename),
|
||||
iter_ctx.language);
|
||||
iter_ctx.last = iterator_type();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string instring;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// load_file
|
||||
//
|
||||
// The load_file policy opens a given file and returns the wrapped
|
||||
// istreambuf_iterators.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct load_file {
|
||||
|
||||
template <typename IterContextT>
|
||||
class inner {
|
||||
|
||||
public:
|
||||
~inner() { if (instream.is_open()) instream.close(); }
|
||||
|
||||
template <typename PositionT>
|
||||
static
|
||||
void init_iterators(IterContextT &iter_ctx,
|
||||
PositionT const &act_pos)
|
||||
{
|
||||
typedef typename IterContextT::iterator_type iterator_type;
|
||||
|
||||
iter_ctx.instream.open(iter_ctx.filename.c_str());
|
||||
if (!iter_ctx.instream.is_open()) {
|
||||
BOOST_WAVE_THROW(preprocess_exception, bad_include_file,
|
||||
iter_ctx.filename, act_pos);
|
||||
}
|
||||
iter_ctx.instream.unsetf(std::ios::skipws);
|
||||
|
||||
using boost::spirit::make_multi_pass;
|
||||
iter_ctx.first = iterator_type(
|
||||
make_multi_pass(std::istreambuf_iterator<char>(
|
||||
iter_ctx.instream.rdbuf())),
|
||||
make_multi_pass(std::istreambuf_iterator<char>()),
|
||||
PositionT(iter_ctx.filename), iter_ctx.language);
|
||||
iter_ctx.last = iterator_type();
|
||||
}
|
||||
|
||||
private:
|
||||
std::ifstream instream;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace iterattion_context_policies
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template <typename IteratorT>
|
||||
struct base_iteration_context {
|
||||
|
||||
public:
|
||||
base_iteration_context(BOOST_WAVE_STRINGTYPE const &fname)
|
||||
: real_filename(fname), filename(fname), line(1), emitted_lines(1)
|
||||
{}
|
||||
base_iteration_context(IteratorT const &first_, IteratorT const &last_,
|
||||
BOOST_WAVE_STRINGTYPE const &fname)
|
||||
: first(first_), last(last_), real_filename(fname), filename(fname),
|
||||
line(1), emitted_lines(1)
|
||||
{}
|
||||
|
||||
// the actual input stream
|
||||
IteratorT first; // actual input stream position
|
||||
IteratorT last; // end of input stream
|
||||
BOOST_WAVE_STRINGTYPE real_filename; // real name of the current file
|
||||
BOOST_WAVE_STRINGTYPE filename; // actual processed file
|
||||
int line; // line counter of underlying stream
|
||||
int emitted_lines; // count of emitted newlines
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template <
|
||||
typename IteratorT,
|
||||
typename InputPolicyT =
|
||||
iteration_context_policies::load_file_to_string
|
||||
>
|
||||
struct iteration_context
|
||||
: public base_iteration_context<IteratorT>,
|
||||
public InputPolicyT::template
|
||||
inner<iteration_context<IteratorT, InputPolicyT> >
|
||||
{
|
||||
typedef IteratorT iterator_type;
|
||||
typedef typename IteratorT::token_type::position_type position_type;
|
||||
|
||||
typedef iteration_context<IteratorT, InputPolicyT> self_type;
|
||||
|
||||
iteration_context(BOOST_WAVE_STRINGTYPE const &fname,
|
||||
position_type const &act_pos,
|
||||
boost::wave::language_support language_)
|
||||
: base_iteration_context<IteratorT>(fname),
|
||||
language(language_)
|
||||
{
|
||||
InputPolicyT::template inner<self_type>::init_iterators(*this, act_pos);
|
||||
}
|
||||
|
||||
boost::wave::language_support language;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)
|
||||
81
include/boost/wave/cpplexer/cpp_lex_interface.hpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Definition of the abstract lexer interface
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_LEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED)
|
||||
#define CPP_LEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED
|
||||
|
||||
#include <boost/wave/util/file_position.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// new_lexer_gen: generates a new instance of the required C++ lexer
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT> struct lex_input_interface;
|
||||
|
||||
template <
|
||||
typename IteratorT,
|
||||
typename PositionT = boost::wave::util::file_position_type
|
||||
>
|
||||
struct new_lexer_gen
|
||||
{
|
||||
// The NewLexer function allows the opaque generation of a new lexer object.
|
||||
// It is coupled to the token type to allow to decouple the lexer/token
|
||||
// configurations at compile time.
|
||||
static lex_input_interface<lex_token<PositionT> > *
|
||||
new_lexer(IteratorT const &first, IteratorT const &last,
|
||||
PositionT const &pos, boost::wave::language_support language);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The lex_input_interface decouples the lex_iterator_shim from the actual
|
||||
// lexer. This is done to allow compile time reduction.
|
||||
// Thanks to JCAB for having this idea.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename TokenT>
|
||||
struct lex_input_interface
|
||||
{
|
||||
typedef typename TokenT::position_type position_type;
|
||||
|
||||
virtual TokenT get() = 0;
|
||||
virtual void set_position(position_type const &pos) = 0;
|
||||
|
||||
virtual ~lex_input_interface() {}
|
||||
|
||||
// The new_lexer function allows the opaque generation of a new lexer object.
|
||||
// It is coupled to the token type to allow to distinguish different
|
||||
// lexer/token configurations at compile time.
|
||||
template <typename IteratorT>
|
||||
static lex_input_interface *
|
||||
new_lexer(IteratorT const &first, IteratorT const &last,
|
||||
position_type const &pos, boost::wave::language_support language)
|
||||
{
|
||||
return new_lexer_gen<IteratorT, position_type>::new_lexer (first, last,
|
||||
pos, language);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_LEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED)
|
||||
139
include/boost/wave/cpplexer/cpp_lex_iterator.hpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Definition of the lexer iterator
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)
|
||||
#define CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/spirit/iterator/multi_pass.hpp>
|
||||
|
||||
#include <boost/wave/util/file_position.hpp>
|
||||
#include <boost/wave/util/functor_input.hpp>
|
||||
#include <boost/wave/cpplexer/cpp_lex_interface.hpp>
|
||||
|
||||
#include <boost/wave/language_support.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lex_iterator_functor_shim
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename TokenT>
|
||||
class lex_iterator_functor_shim
|
||||
{
|
||||
public:
|
||||
template <typename IteratorT>
|
||||
lex_iterator_functor_shim(IteratorT const &first, IteratorT const &last,
|
||||
typename TokenT::position_type const &pos,
|
||||
boost::wave::language_support language)
|
||||
: functor_ptr(lex_input_interface<TokenT>
|
||||
::new_lexer(first, last, pos, language))
|
||||
{}
|
||||
|
||||
// interface to the boost::spirit::multi_pass_policies::functor_input policy
|
||||
typedef TokenT result_type;
|
||||
|
||||
static result_type const eof;
|
||||
|
||||
result_type operator()()
|
||||
{
|
||||
BOOST_ASSERT(0 != functor_ptr.get());
|
||||
return functor_ptr->get();
|
||||
}
|
||||
void set_position(typename TokenT::position_type const &pos)
|
||||
{
|
||||
BOOST_ASSERT(0 != functor_ptr.get());
|
||||
functor_ptr->set_position(pos);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<lex_input_interface<TokenT> > functor_ptr;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// eof token
|
||||
template <typename LexT>
|
||||
typename lex_iterator_functor_shim<LexT>::result_type const
|
||||
lex_iterator_functor_shim<LexT>::eof;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lex_iterator
|
||||
//
|
||||
// A generic C++ lexer interface class, which allows to plug in different
|
||||
// lexer implementations. The interface between the lexer type used and
|
||||
// the preprocessor component depends on the token type only (template
|
||||
// parameter TokenT).
|
||||
// Additionally, the following requirements apply:
|
||||
//
|
||||
// - the lexer type should have a function implemented, which returnes
|
||||
// the next lexed token from the input stream:
|
||||
// typename TokenT get();
|
||||
// - at the end of the input stream this function should return the
|
||||
// eof token equivalent
|
||||
// - the lexer should implement a constructor taking two iterators
|
||||
// pointing to the beginning and the end of the input stream,
|
||||
// a third parameter containing the name of the parsed input file
|
||||
// and a 4th parameter of the type boost::wave::language_support
|
||||
// which specifies, which language subset should be supported (C++,
|
||||
// C99, C++0x etc.).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename TokenT>
|
||||
class lex_iterator
|
||||
: public boost::spirit::multi_pass<
|
||||
impl::lex_iterator_functor_shim<TokenT>,
|
||||
boost::wave::util::functor_input
|
||||
>
|
||||
{
|
||||
typedef impl::lex_iterator_functor_shim<TokenT> input_policy_type;
|
||||
typedef
|
||||
boost::spirit::multi_pass<input_policy_type,
|
||||
boost::wave::util::functor_input>
|
||||
base_t;
|
||||
typedef lex_iterator<TokenT> self_type;
|
||||
|
||||
public:
|
||||
typedef TokenT token_type;
|
||||
|
||||
lex_iterator()
|
||||
{}
|
||||
|
||||
template <typename IteratorT>
|
||||
lex_iterator(IteratorT const &first, IteratorT const &last,
|
||||
typename TokenT::position_type const &pos,
|
||||
boost::wave::language_support language)
|
||||
: base_t(input_policy_type(first, last, pos, language))
|
||||
{}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)
|
||||
108
include/boost/wave/cpplexer/cpp_lex_token.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
A generic C++ lexer token definition
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
|
||||
#define CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/util/file_position.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// forward declaration of the token type
|
||||
template <typename PositionT = boost::wave::util::file_position_type>
|
||||
class lex_token;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lex_token
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename PositionT>
|
||||
class lex_token
|
||||
{
|
||||
public:
|
||||
typedef BOOST_WAVE_STRINGTYPE string_type;
|
||||
typedef PositionT position_type;
|
||||
|
||||
lex_token()
|
||||
: id(T_EOI)
|
||||
{}
|
||||
|
||||
lex_token(token_id id_, string_type const &value_, PositionT const &pos_)
|
||||
: id(id_), value(value_), pos(pos_)
|
||||
{}
|
||||
|
||||
// accessors
|
||||
operator token_id() const { return id; }
|
||||
string_type const &get_value() const { return value; }
|
||||
position_type const &get_position() const { return pos; }
|
||||
void set_token_id (token_id id_) { id = id_; }
|
||||
void set_value (string_type const &newval) { value = newval; }
|
||||
void set_position (position_type const &pos_) { pos = pos_; }
|
||||
|
||||
// debug support
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
// access functions for the tree_to_xml functionality
|
||||
static int get_token_id(lex_token const &t)
|
||||
{ return ID_FROM_TOKEN(token_id(t)); }
|
||||
static string_type get_token_value(lex_token const &t)
|
||||
{ return t.get_value(); }
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
// debug support
|
||||
void print (std::ostream &stream) const
|
||||
{
|
||||
stream << get_token_name(id) << "(";
|
||||
for (std::size_t i = 0; i < value.size(); ++i) {
|
||||
switch (value[i]) {
|
||||
case '\r': stream << "\\r"; break;
|
||||
case '\n': stream << "\\n"; break;
|
||||
default:
|
||||
stream << value[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
stream << ")";
|
||||
}
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
private:
|
||||
token_id id; // the token id
|
||||
string_type value; // the text, which was parsed into this token
|
||||
PositionT pos; // the original file position
|
||||
};
|
||||
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
template <typename PositionT>
|
||||
inline std::ostream &
|
||||
operator<< (std::ostream &stream, lex_token<PositionT> const &object)
|
||||
{
|
||||
object.print(stream);
|
||||
return stream;
|
||||
}
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
|
||||
194
include/boost/wave/cpplexer/cpplexer_exceptions.hpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED)
|
||||
#define CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// helper macro for throwing exceptions
|
||||
#if !defined(BOOST_WAVE_LEXER_THROW)
|
||||
#ifdef BOOST_NO_STRINGSTREAM
|
||||
#include <strstream>
|
||||
#define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \
|
||||
{ \
|
||||
using namespace boost::wave; \
|
||||
std::strstream stream; \
|
||||
stream << cls::severity_text(cls::code) << ": " \
|
||||
<< cls::error_text(cls::code); \
|
||||
if (msg[0] != 0) stream << ": " << msg; \
|
||||
stream << std::ends; \
|
||||
std::string throwmsg = stream.str(); stream.freeze(false); \
|
||||
throw cls(throwmsg.c_str(), cls::code, line, column, name); \
|
||||
} \
|
||||
/**/
|
||||
#else
|
||||
#include <sstream>
|
||||
#define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \
|
||||
{ \
|
||||
using namespace boost::wave; \
|
||||
std::stringstream stream; \
|
||||
stream << cls::severity_text(cls::code) << ": " \
|
||||
<< cls::error_text(cls::code); \
|
||||
if (msg[0] != 0) stream << ": " << msg; \
|
||||
stream << std::ends; \
|
||||
throw cls(stream.str().c_str(), cls::code, line, column, name); \
|
||||
} \
|
||||
/**/
|
||||
#endif // BOOST_NO_STRINGSTREAM
|
||||
#endif // BOOST_WAVE_LEXER_THROW
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// exception severity
|
||||
namespace util {
|
||||
|
||||
enum severity {
|
||||
severity_remark = 0,
|
||||
severity_warning,
|
||||
severity_error,
|
||||
severity_fatal
|
||||
};
|
||||
|
||||
inline char const *
|
||||
get_severity(severity level)
|
||||
{
|
||||
static char const *severity_text[] =
|
||||
{
|
||||
"remark", // severity_remark
|
||||
"warning", // severity_warning
|
||||
"error", // severity_error
|
||||
"fatal error" // severity_fatal
|
||||
};
|
||||
BOOST_ASSERT(severity_remark <= level && level <= severity_fatal);
|
||||
return severity_text[level];
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// cpplexer_exception, the base class for all specific C++ lexer exceptions
|
||||
class cpplexer_exception
|
||||
: public std::exception
|
||||
{
|
||||
public:
|
||||
cpplexer_exception(int line_, int column_, char const *filename_) throw()
|
||||
: line(line_), column(column_)
|
||||
{
|
||||
unsigned int off = 0;
|
||||
while (off < sizeof(filename) && *filename_)
|
||||
filename[off++] = *filename_++;
|
||||
filename[off] = 0;
|
||||
}
|
||||
~cpplexer_exception() throw() {}
|
||||
|
||||
virtual char const *what() const throw() = 0; // to be overloaded
|
||||
virtual char const *description() const throw() = 0;
|
||||
|
||||
int line_no() const throw() { return line; }
|
||||
int column_no() const throw() { return column; }
|
||||
char const *file_name() const throw() { return filename; }
|
||||
|
||||
protected:
|
||||
char filename[512];
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lexing_exception error
|
||||
class lexing_exception :
|
||||
public cpplexer_exception
|
||||
{
|
||||
public:
|
||||
enum error_code {
|
||||
unexpected_error = 0,
|
||||
universal_char_invalid = 1,
|
||||
universal_char_base_charset = 2,
|
||||
universal_char_not_allowed = 3,
|
||||
generic_lexing_error = 4
|
||||
};
|
||||
|
||||
lexing_exception(char const *what_, error_code code, int line_,
|
||||
int column_, char const *filename_) throw()
|
||||
: cpplexer_exception(line_, column_, filename_),
|
||||
level(severity_level(code))
|
||||
{
|
||||
unsigned int off = 0;
|
||||
while (off < sizeof(buffer) && *what_)
|
||||
buffer[off++] = *what_++;
|
||||
buffer[off] = 0;
|
||||
}
|
||||
~lexing_exception() throw() {}
|
||||
|
||||
virtual char const *what() const throw()
|
||||
{
|
||||
return "boost::wave::lexing_exception";
|
||||
}
|
||||
virtual char const *description() const throw()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
util::severity get_severity()
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
static char const *error_text(int code)
|
||||
{
|
||||
// error texts in this array must appear in the same order as the items in
|
||||
// the error enum above
|
||||
static char const *preprocess_exception_errors[] = {
|
||||
"unexpected error (should not happen)", // unexpected_error
|
||||
"universal character name specifies an invalid character", // universal_char_invalid
|
||||
"a universal character name cannot designate a character in the "
|
||||
"basic character set", // universal_char_base_charset
|
||||
"this universal character is not allowed in an identifier", // universal_char_not_allowed
|
||||
"generic lexing error" // generic_lexing_error
|
||||
};
|
||||
return preprocess_exception_errors[code];
|
||||
}
|
||||
|
||||
static util::severity severity_level(int code)
|
||||
{
|
||||
static util::severity preprocess_exception_severity[] = {
|
||||
util::severity_fatal, // unexpected_error
|
||||
util::severity_error, // universal_char_invalid
|
||||
util::severity_error, // universal_char_base_charset
|
||||
util::severity_error, // universal_char_not_allowed
|
||||
util::severity_error // generic_lexing_error
|
||||
};
|
||||
return preprocess_exception_severity[code];
|
||||
}
|
||||
static char const *severity_text(int code)
|
||||
{
|
||||
return util::get_severity(severity_level(code));
|
||||
}
|
||||
|
||||
private:
|
||||
char buffer[512];
|
||||
util::severity level;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED)
|
||||
52
include/boost/wave/cpplexer/re2clex/aq.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001 Daniel C. Nuffer.
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(AQ_HPP_A21D9145_B643_44C0_81E7_DB346DD67EE1_INCLUDED)
|
||||
#define AQ_HPP_A21D9145_B643_44C0_81E7_DB346DD67EE1_INCLUDED
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
namespace re2clex {
|
||||
|
||||
typedef std::size_t aq_stdelement;
|
||||
|
||||
typedef struct tag_aq_queuetype
|
||||
{
|
||||
std::size_t head;
|
||||
std::size_t tail;
|
||||
std::size_t size;
|
||||
std::size_t max_size;
|
||||
aq_stdelement* queue;
|
||||
} aq_queuetype;
|
||||
|
||||
typedef aq_queuetype* aq_queue;
|
||||
|
||||
int aq_enqueue(aq_queue q, aq_stdelement e);
|
||||
int aq_enqueue_front(aq_queue q, aq_stdelement e);
|
||||
int aq_serve(aq_queue q, aq_stdelement *e);
|
||||
int aq_pop(aq_queue q);
|
||||
#define AQ_EMPTY(q) (q->size == 0)
|
||||
#define AQ_FULL(q) (q->size == q->max_size)
|
||||
aq_queue aq_create(void);
|
||||
void aq_terminate(aq_queue q);
|
||||
int aq_grow(aq_queue q);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace re2clex
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(AQ_HPP_A21D9145_B643_44C0_81E7_DB346DD67EE1_INCLUDED)
|
||||
34
include/boost/wave/cpplexer/re2clex/cpp.re.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Re2C based C++ lexer
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_RE_HPP_B76C4F5E_63E9_4B8A_9975_EC32FA6BF027_INCLUDED)
|
||||
#define CPP_RE_HPP_B76C4F5E_63E9_4B8A_9975_EC32FA6BF027_INCLUDED
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
namespace re2clex {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The scanner function to call whenever a new token is requested
|
||||
boost::wave::token_id scan(Scanner *s);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace re2clex
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_RE_HPP_B76C4F5E_63E9_4B8A_9975_EC32FA6BF027_INCLUDED)
|
||||
307
include/boost/wave/cpplexer/re2clex/cpp_re2c_lexer.hpp
Normal file
@@ -0,0 +1,307 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Re2C based C++ lexer
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED)
|
||||
#define CPP_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
#include <iostream>
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/spirit/core.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/util/file_position.hpp>
|
||||
#include <boost/wave/cpplexer/validate_universal_char.hpp>
|
||||
#include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
|
||||
#include <boost/wave/cpplexer/token_cache.hpp>
|
||||
|
||||
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
|
||||
#include <boost/wave/cpplexer/cpp_lex_interface.hpp>
|
||||
#include <boost/wave/cpplexer/re2clex/scanner.hpp>
|
||||
#include <boost/wave/cpplexer/re2clex/cpp.re.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
namespace re2clex {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// encapsulation of the re2c based cpp lexer
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename IteratorT, typename PositionT = boost::wave::util::file_position_type>
|
||||
class lexer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef char char_t;
|
||||
typedef Scanner base_t;
|
||||
typedef lex_token<PositionT> token_type;
|
||||
typedef typename token_type::string_type string_type;
|
||||
|
||||
lexer(IteratorT const &first, IteratorT const &last,
|
||||
PositionT const &pos, boost::wave::language_support language);
|
||||
~lexer();
|
||||
|
||||
lex_token<PositionT> get();
|
||||
void set_position(PositionT const &pos)
|
||||
{
|
||||
filename = pos.get_file();
|
||||
scanner.line = pos.get_line();
|
||||
scanner.file_name = filename.c_str();
|
||||
}
|
||||
|
||||
// error reporting from the re2c generated lexer
|
||||
static int report_error(Scanner *s, char *, ...);
|
||||
|
||||
private:
|
||||
static char const *tok_names[];
|
||||
|
||||
Scanner scanner;
|
||||
string_type filename;
|
||||
string_type value;
|
||||
bool at_eof;
|
||||
|
||||
static token_cache<string_type> const cache;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// initialize cpp lexer
|
||||
template <typename IteratorT, typename PositionT>
|
||||
inline
|
||||
lexer<IteratorT, PositionT>::lexer(IteratorT const &first,
|
||||
IteratorT const &last, PositionT const &pos,
|
||||
boost::wave::language_support language)
|
||||
: filename(pos.get_file()), at_eof(false)
|
||||
{
|
||||
memset(&scanner, '\0', sizeof(Scanner));
|
||||
scanner.fd = -1;
|
||||
scanner.eol_offsets = aq_create();
|
||||
scanner.first = scanner.act = (uchar *)&(*first);
|
||||
scanner.last = scanner.first + std::distance(first, last);
|
||||
scanner.line = 1; // start with line_no 1
|
||||
scanner.error_proc = report_error;
|
||||
scanner.file_name = filename.c_str();
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
scanner.enable_ms_extensions = 1;
|
||||
#else
|
||||
scanner.enable_ms_extensions = 0;
|
||||
#endif
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
scanner.act_in_c99_mode = boost::wave::need_c99(language);
|
||||
#endif
|
||||
|
||||
boost::ignore_unused_variable_warning(language);
|
||||
}
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
inline
|
||||
lexer<IteratorT, PositionT>::~lexer()
|
||||
{
|
||||
aq_terminate(scanner.eol_offsets);
|
||||
free(scanner.bot);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get the next token from the input stream
|
||||
template <typename IteratorT, typename PositionT>
|
||||
inline lex_token<PositionT>
|
||||
lexer<IteratorT, PositionT>::get()
|
||||
{
|
||||
if (at_eof)
|
||||
return lex_token<PositionT>(); // return T_EOI
|
||||
|
||||
token_id id = token_id(scan(&scanner));
|
||||
|
||||
switch (id) {
|
||||
case T_IDENTIFIER:
|
||||
// test identifier characters for validity (throws if invalid chars found)
|
||||
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
|
||||
impl::validate_identifier_name(value, scanner.line, -1, filename);
|
||||
break;
|
||||
|
||||
case T_STRINGLIT:
|
||||
case T_CHARLIT:
|
||||
// test literal characters for validity (throws if invalid chars found)
|
||||
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
|
||||
impl::validate_literal(value, scanner.line, -1, filename);
|
||||
break;
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
case T_PP_HHEADER:
|
||||
case T_PP_QHEADER:
|
||||
case T_PP_INCLUDE:
|
||||
// convert to the corresponding ..._next token, if appropriate
|
||||
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
|
||||
if (string_type::npos != value.find("include_"))
|
||||
id = token_id(id | AltTokenType);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case T_OCTALINT:
|
||||
case T_DECIMALINT:
|
||||
case T_HEXAINT:
|
||||
case T_INTLIT:
|
||||
case T_FLOATLIT:
|
||||
case T_FIXEDPOINTLIT:
|
||||
case T_CCOMMENT:
|
||||
case T_CPPCOMMENT:
|
||||
case T_SPACE:
|
||||
case T_SPACE2:
|
||||
case T_ANY:
|
||||
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
|
||||
break;
|
||||
|
||||
case T_EOF:
|
||||
// T_EOF is returned as a valid token, the next call will return T_EOI,
|
||||
// i.e. the actual end of input
|
||||
at_eof = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (CATEGORY_FROM_TOKEN(id) != EXTCATEGORY_FROM_TOKEN(id) ||
|
||||
IS_CATEGORY(id, UnknownTokenType))
|
||||
{
|
||||
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
|
||||
}
|
||||
else {
|
||||
value = cache.get_token_value(id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return lex_token<PositionT>(id, value,
|
||||
PositionT(filename, scanner.line, -1));
|
||||
}
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
inline int
|
||||
lexer<IteratorT, PositionT>::report_error(Scanner *s, char *msg, ...)
|
||||
{
|
||||
BOOST_ASSERT(0 != s);
|
||||
BOOST_ASSERT(0 != msg);
|
||||
|
||||
using namespace std; // some system have vsprintf in namespace std
|
||||
|
||||
char buffer[200]; // should be large enough
|
||||
va_list params;
|
||||
va_start(params, msg);
|
||||
vsprintf(buffer, msg, params);
|
||||
va_end(params);
|
||||
|
||||
BOOST_WAVE_LEXER_THROW(lexing_exception, generic_lexing_error, buffer, s->line, -1,
|
||||
s->file_name);
|
||||
return 0; // unreachable code;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lex_functor
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename IteratorT, typename PositionT = boost::wave::util::file_position_type>
|
||||
class lex_functor
|
||||
: public lex_input_interface<typename lexer<IteratorT, PositionT>::token_type>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename lexer<IteratorT, PositionT>::token_type token_type;
|
||||
|
||||
lex_functor(IteratorT const &first, IteratorT const &last,
|
||||
PositionT const &pos, boost::wave::language_support language)
|
||||
: lexer(first, last, pos, language)
|
||||
{}
|
||||
virtual ~lex_functor() {}
|
||||
|
||||
// get the next token from the input stream
|
||||
token_type get() { return lexer.get(); }
|
||||
void set_position(PositionT const &pos)
|
||||
{ lexer.set_position(pos); }
|
||||
|
||||
private:
|
||||
lexer<IteratorT, PositionT> lexer;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename PositionT>
|
||||
token_cache<typename lexer<IteratorT, PositionT>::string_type> const
|
||||
lexer<IteratorT, PositionT>::cache =
|
||||
token_cache<typename lexer<IteratorT, PositionT>::string_type>();
|
||||
|
||||
} // namespace re2clex
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The new_lexer_gen<>::new_lexer function (declared in cpp_lex_interface.hpp)
|
||||
// should be defined inline, if the lex_functor shouldn't be instantiated
|
||||
// separately from the lex_iterator.
|
||||
//
|
||||
// Separate (explicit) instantiation helps to reduce compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_RE2C_NEW_LEXER_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_RE2C_NEW_LEXER_INLINE inline
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The 'new_lexer' function allows the opaque generation of a new lexer object.
|
||||
// It is coupled to the iterator type to allow to decouple the lexer/iterator
|
||||
// configurations at compile time.
|
||||
//
|
||||
// This function is declared inside the cpp_slex_token.hpp file, which is
|
||||
// referenced by the source file calling the lexer and the source file, which
|
||||
// instantiates the lex_functor. But is is defined here, so it will be
|
||||
// instantiated only while compiling the source file, which instantiates the
|
||||
// lex_functor. While the cpp_re2c_token.hpp file may be included everywhere,
|
||||
// this file (cpp_re2c_lexer.hpp) should be included only once. This allows
|
||||
// to decouple the lexer interface from the lexer implementation and reduces
|
||||
// compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
BOOST_WAVE_RE2C_NEW_LEXER_INLINE
|
||||
lex_input_interface<lex_token<PositionT> > *
|
||||
new_lexer_gen<IteratorT, PositionT>::new_lexer(IteratorT const &first,
|
||||
IteratorT const &last, PositionT const &pos,
|
||||
boost::wave::language_support language)
|
||||
{
|
||||
return new re2clex::lex_functor<IteratorT, PositionT>(first, last, pos,
|
||||
language);
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_RE2C_NEW_LEXER_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED)
|
||||
58
include/boost/wave/cpplexer/re2clex/scanner.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001 Daniel C. Nuffer.
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(SCANNER_HPP_F4FB01EB_E75C_4537_A146_D34B9895EF37_INCLUDED)
|
||||
#define SCANNER_HPP_F4FB01EB_E75C_4537_A146_D34B9895EF37_INCLUDED
|
||||
|
||||
#include <boost/wave/cpplexer/re2clex/aq.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
namespace re2clex {
|
||||
|
||||
struct Scanner;
|
||||
typedef unsigned char uchar;
|
||||
typedef int (* ReportErrorProc)(struct Scanner *, char *, ...);
|
||||
|
||||
typedef struct Scanner {
|
||||
int fd; /* file descriptor */
|
||||
uchar* first; /* start of input buffer (if fd == -1) */
|
||||
uchar* act; /* act position of input buffer (if fd == -1) */
|
||||
uchar* last; /* end (one past last char) of input buffer (if fd == -1) */
|
||||
uchar* bot; /* beginning of the current buffer */
|
||||
uchar* top; /* top of the current buffer */
|
||||
uchar* eof; /* when we read in the last buffer, will point 1 past the
|
||||
end of the file, otherwise 0 */
|
||||
uchar* tok; /* points to the beginning of the current token */
|
||||
uchar* ptr; /* used for YYMARKER - saves backtracking info */
|
||||
uchar* cur; /* saves the cursor (maybe is redundant with tok?) */
|
||||
uchar* lim; /* used for YYLIMIT - points to the end of the buffer */
|
||||
/* (lim == top) except for the last buffer, it points to
|
||||
the end of the input (lim == eof - 1) */
|
||||
unsigned int line; /* current line being lexed */
|
||||
ReportErrorProc error_proc; /* if != 0 this function is called to
|
||||
report an error */
|
||||
char const *file_name; /* name of the lexed file */
|
||||
aq_queue eol_offsets;
|
||||
int enable_ms_extensions; /* enable MS extensions */
|
||||
int act_in_c99_mode; /* lexer works in C99 mode */
|
||||
int act_in_cpp0x_mode; /* lexer works in C++0x mode */
|
||||
} Scanner;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace re2clex
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(SCANNER_HPP_F4FB01EB_E75C_4537_A146_D34B9895EF37_INCLUDED)
|
||||
60
include/boost/wave/cpplexer/token_cache.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(TOKEN_CACHE_HPP_4D2320B7_1D56_4113_A114_397E70FA438C_INCLUDED)
|
||||
#define TOKEN_CACHE_HPP_4D2320B7_1D56_4113_A114_397E70FA438C_INCLUDED
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The token_cache template is used to cache the tokens corresponding to the
|
||||
// keywords, operators and other constant language elements.
|
||||
//
|
||||
// This avoids repeated construction of these tokens, which is especially
|
||||
// effective when used in conjunction with a copy on write string
|
||||
// implementation (COW string).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename StringT>
|
||||
class token_cache
|
||||
{
|
||||
public:
|
||||
token_cache()
|
||||
: cache(T_LAST_TOKEN - T_FIRST_TOKEN)
|
||||
{
|
||||
typename std::vector<StringT>::iterator it = cache.begin();
|
||||
typename std::vector<StringT>::iterator end = cache.end();
|
||||
for (unsigned int i = T_FIRST_TOKEN; i < T_LAST_TOKEN; ++i, ++it)
|
||||
{
|
||||
*it = StringT(boost::wave::get_token_value(token_id(i)));
|
||||
}
|
||||
}
|
||||
|
||||
StringT const &get_token_value(token_id id) const
|
||||
{
|
||||
return cache[BASEID_FROM_TOKEN(id) - T_FIRST_TOKEN];
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<StringT> cache;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(TOKEN_CACHE_HPP_4D2320B7_1D56_4113_A114_397E70FA438C_INCLUDED)
|
||||
314
include/boost/wave/cpplexer/validate_universal_char.hpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Grammar for universal character validation (see C++ standard: Annex E)
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
#if !defined(VALIDATE_UNIVERSAL_CHAR_HPP_55F1B811_CD76_4C72_8344_CBC69CF3B339_INCLUDED)
|
||||
#define VALIDATE_UNIVERSAL_CHAR_HPP_55F1B811_CD76_4C72_8344_CBC69CF3B339_INCLUDED
|
||||
|
||||
#include <boost/spirit/core.hpp>
|
||||
|
||||
#include <boost/wave/util/file_position.hpp>
|
||||
#include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpplexer {
|
||||
namespace impl {
|
||||
|
||||
enum universal_char_type {
|
||||
universal_char_type_valid = 0,
|
||||
universal_char_type_invalid = 1,
|
||||
universal_char_type_base_charset = 2,
|
||||
universal_char_type_not_allowed_for_identifiers = 3,
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// is_range is a helper function for the classification by brute force
|
||||
// below
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
inline bool
|
||||
in_range(unsigned long ch, unsigned long l, unsigned long u)
|
||||
{
|
||||
return (l <= ch && ch <= u);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// classify_universal_char
|
||||
//
|
||||
// This function classifies an universal character value into 4 subranges:
|
||||
// universal_char_type_valid
|
||||
// the universal character value is valid for identifiers
|
||||
// universal_char_type_invalid
|
||||
// the universal character value is not valid for its usage inside
|
||||
// identifiers (see C++ Standard: 2.2.2 [lex.charset])
|
||||
// universal_char_type_base_charset
|
||||
// the universal character value designates a character from the base
|
||||
// character set
|
||||
// universal_char_type_not_allowed_for_identifiers
|
||||
// the universal character value is not allowed in an identifier
|
||||
//
|
||||
// Implementation note:
|
||||
// This classification isn't implemented very effectively here. This
|
||||
// function should be rewritten with some range run matching algorithm.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline universal_char_type
|
||||
classify_universal_char (unsigned long ch)
|
||||
{
|
||||
// test for invalid characters
|
||||
if (ch <= 0x0020 || in_range(ch, 0x007f, 0x009f))
|
||||
return universal_char_type_invalid;
|
||||
|
||||
// test for characters in the range of the base character set
|
||||
if (in_range(ch, 0x0021, 0x005f) || in_range(ch, 0x0061, 0x007e))
|
||||
return universal_char_type_base_charset;
|
||||
|
||||
// test for additional valid character values (see C++ Standard: Annex E)
|
||||
if (in_range(ch, 0x00c0, 0x00d6) || in_range(ch, 0x00d8, 0x00f6) ||
|
||||
in_range(ch, 0x00f8, 0x01f5) || in_range(ch, 0x01fa, 0x0217) ||
|
||||
in_range(ch, 0x0250, 0x02a8) || in_range(ch, 0x1e00, 0x1e9a) ||
|
||||
in_range(ch, 0x1ea0, 0x1ef9))
|
||||
{
|
||||
return universal_char_type_valid; // Latin
|
||||
}
|
||||
|
||||
if (0x0384 == ch || in_range(ch, 0x0388, 0x038a) ||
|
||||
0x038c == ch || in_range(ch, 0x038e, 0x03a1) ||
|
||||
in_range(ch, 0x03a3, 0x03ce) || in_range(ch, 0x03d0, 0x03d6) ||
|
||||
0x03da == ch || 0x03dc == ch || 0x03de == ch || 0x03e0 == ch ||
|
||||
in_range(ch, 0x03e2, 0x03f3) || in_range(ch, 0x1f00, 0x1f15) ||
|
||||
in_range(ch, 0x1f18, 0x1f1d) || in_range(ch, 0x1f20, 0x1f45) ||
|
||||
in_range(ch, 0x1f48, 0x1f4d) || in_range(ch, 0x1f50, 0x1f57) ||
|
||||
0x1f59 == ch || 0x1f5b == ch || 0x1f5d == ch ||
|
||||
in_range(ch, 0x1f5f, 0x1f7d) || in_range(ch, 0x1f80, 0x1fb4) ||
|
||||
in_range(ch, 0x1fb6, 0x1fbc) || in_range(ch, 0x1fc2, 0x1fc4) ||
|
||||
in_range(ch, 0x1fc6, 0x1fcc) || in_range(ch, 0x1fd0, 0x1fd3) ||
|
||||
in_range(ch, 0x1fd6, 0x1fdb) || in_range(ch, 0x1fe0, 0x1fec) ||
|
||||
in_range(ch, 0x1ff2, 0x1ff4) || in_range(ch, 0x1ff6, 0x1ffc))
|
||||
{
|
||||
return universal_char_type_valid; // Greek
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0401, 0x040d) || in_range(ch, 0x040f, 0x044f) ||
|
||||
in_range(ch, 0x0451, 0x045c) || in_range(ch, 0x045e, 0x0481) ||
|
||||
in_range(ch, 0x0490, 0x04c4) || in_range(ch, 0x04c7, 0x04c8) ||
|
||||
in_range(ch, 0x04cb, 0x04cc) || in_range(ch, 0x04d0, 0x04eb) ||
|
||||
in_range(ch, 0x04ee, 0x04f5) || in_range(ch, 0x04f8, 0x04f9))
|
||||
{
|
||||
return universal_char_type_valid; // Cyrillic
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0531, 0x0556) || in_range(ch, 0x0561, 0x0587))
|
||||
return universal_char_type_valid; // Armenian
|
||||
|
||||
if (in_range(ch, 0x05d0, 0x05ea) || in_range(ch, 0x05f0, 0x05f4))
|
||||
return universal_char_type_valid; // Hebrew
|
||||
|
||||
if (in_range(ch, 0x0621, 0x063a) || in_range(ch, 0x0640, 0x0652) ||
|
||||
in_range(ch, 0x0670, 0x06b7) || in_range(ch, 0x06ba, 0x06be) ||
|
||||
in_range(ch, 0x06c0, 0x06ce) || in_range(ch, 0x06e5, 0x06e7))
|
||||
{
|
||||
return universal_char_type_valid; // Arabic
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0905, 0x0939) || in_range(ch, 0x0958, 0x0962))
|
||||
return universal_char_type_valid; // Devanagari
|
||||
|
||||
if (in_range(ch, 0x0985, 0x098c) || in_range(ch, 0x098f, 0x0990) ||
|
||||
in_range(ch, 0x0993, 0x09a8) || in_range(ch, 0x09aa, 0x09b0) ||
|
||||
0x09b2 == ch || in_range(ch, 0x09b6, 0x09b9) ||
|
||||
in_range(ch, 0x09dc, 0x09dd) || in_range(ch, 0x09df, 0x09e1) ||
|
||||
in_range(ch, 0x09f0, 0x09f1))
|
||||
{
|
||||
return universal_char_type_valid; // Bengali
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0a05, 0x0a0a) || in_range(ch, 0x0a0f, 0x0a10) ||
|
||||
in_range(ch, 0x0a13, 0x0a28) || in_range(ch, 0x0a2a, 0x0a30) ||
|
||||
in_range(ch, 0x0a32, 0x0a33) || in_range(ch, 0x0a35, 0x0a36) ||
|
||||
in_range(ch, 0x0a38, 0x0a39) || in_range(ch, 0x0a59, 0x0a5c) ||
|
||||
0x0a5e == ch)
|
||||
{
|
||||
return universal_char_type_valid; // Gurmukhi
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0a85, 0x0a8b) || 0x0a8d == ch ||
|
||||
in_range(ch, 0x0a8f, 0x0a91) || in_range(ch, 0x0a93, 0x0aa8) ||
|
||||
in_range(ch, 0x0aaa, 0x0ab0) || in_range(ch, 0x0ab2, 0x0ab3) ||
|
||||
in_range(ch, 0x0ab5, 0x0ab9) || 0x0ae0 == ch)
|
||||
{
|
||||
return universal_char_type_valid; // Gujarati
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0b05, 0x0b0c) || in_range(ch, 0x0b0f, 0x0b10) ||
|
||||
in_range(ch, 0x0b13, 0x0b28) || in_range(ch, 0x0b2a, 0x0b30) ||
|
||||
in_range(ch, 0x0b32, 0x0b33) || in_range(ch, 0x0b36, 0x0b39) ||
|
||||
in_range(ch, 0x0b5c, 0x0b5d) || in_range(ch, 0x0b5f, 0x0b61))
|
||||
{
|
||||
return universal_char_type_valid; // Oriya
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0b85, 0x0b8a) || in_range(ch, 0x0b8e, 0x0b90) ||
|
||||
in_range(ch, 0x0b92, 0x0b95) || in_range(ch, 0x0b99, 0x0b9a) ||
|
||||
0x0b9c == ch || in_range(ch, 0x0b9e, 0x0b9f) ||
|
||||
in_range(ch, 0x0ba3, 0x0ba4) || in_range(ch, 0x0ba8, 0x0baa) ||
|
||||
in_range(ch, 0x0bae, 0x0bb5) || in_range(ch, 0x0bb7, 0x0bb9))
|
||||
{
|
||||
return universal_char_type_valid; // Tamil
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0c05, 0x0c0c) || in_range(ch, 0x0c0e, 0x0c10) ||
|
||||
in_range(ch, 0x0c12, 0x0c28) || in_range(ch, 0x0c2a, 0x0c33) ||
|
||||
in_range(ch, 0x0c35, 0x0c39) || in_range(ch, 0x0c60, 0x0c61))
|
||||
{
|
||||
return universal_char_type_valid; // Telugu
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0c85, 0x0c8c) || in_range(ch, 0x0c8e, 0x0c90) ||
|
||||
in_range(ch, 0x0c92, 0x0ca8) || in_range(ch, 0x0caa, 0x0cb3) ||
|
||||
in_range(ch, 0x0cb5, 0x0cb9) || in_range(ch, 0x0ce0, 0x0ce1))
|
||||
{
|
||||
return universal_char_type_valid; // Kannada
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0d05, 0x0d0c) || in_range(ch, 0x0d0e, 0x0d10) ||
|
||||
in_range(ch, 0x0d12, 0x0d28) || in_range(ch, 0x0d2a, 0x0d39) ||
|
||||
in_range(ch, 0x0d60, 0x0d61))
|
||||
{
|
||||
return universal_char_type_valid; // Malayalam
|
||||
}
|
||||
|
||||
if (in_range(ch, 0x0e01, 0x0e30) || in_range(ch, 0x0e32, 0x0e33) ||
|
||||
in_range(ch, 0x0e40, 0x0e46) || in_range(ch, 0x0e4f, 0x0e5b))
|
||||
{
|
||||
return universal_char_type_valid; // Thai
|
||||
}
|
||||
|
||||
return universal_char_type_not_allowed_for_identifiers;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// validate_identifier_name
|
||||
//
|
||||
// The validate_identifier_name function tests a given identifier name for
|
||||
// its validity with regard to eventually contained universal characters.
|
||||
// These should be in valid ranges (see the function
|
||||
// classify_universal_char above).
|
||||
//
|
||||
// If the identifier name contains invalid or not allowed universal
|
||||
// characters a corresponding lexing_exception is thrown.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename StringT>
|
||||
inline void
|
||||
validate_identifier_name (StringT const &name, int line, int column,
|
||||
StringT const &file_name)
|
||||
{
|
||||
using namespace std; // some systems have strtoul in namespace std::
|
||||
|
||||
typename StringT::size_type pos = name.find_first_of('\\');
|
||||
|
||||
while (StringT::npos != pos) {
|
||||
// the identifier name contains a backslash (must be universal char)
|
||||
BOOST_SPIRIT_ASSERT('u' == name[pos+1] || 'U' == name[pos+1]);
|
||||
|
||||
StringT uchar_val(name.substr(pos+2, ('u' == name[pos+1]) ? 4 : 8));
|
||||
universal_char_type type =
|
||||
classify_universal_char(strtoul(uchar_val.c_str(), 0, 16));
|
||||
|
||||
if (universal_char_type_valid != type) {
|
||||
// an invalid char was found, so throw an exception
|
||||
StringT error_uchar(name.substr(pos, ('u' == name[pos+1]) ? 6 : 10));
|
||||
|
||||
if (universal_char_type_invalid == type) {
|
||||
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_invalid,
|
||||
error_uchar, line, column, file_name.c_str());
|
||||
}
|
||||
else if (universal_char_type_base_charset == type) {
|
||||
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_base_charset,
|
||||
error_uchar, line, column, file_name.c_str());
|
||||
}
|
||||
else {
|
||||
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_not_allowed,
|
||||
error_uchar, line, column, file_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// find next universal char (if appropriate)
|
||||
pos = name.find_first_of('\\', pos+2);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// validate_literal
|
||||
//
|
||||
// The validate_literal function tests a given string or character literal
|
||||
// for its validity with regard to eventually contained universal
|
||||
// characters. These should be in valid ranges (see the function
|
||||
// classify_universal_char above).
|
||||
//
|
||||
// If the string or character literal contains invalid or not allowed
|
||||
// universal characters a corresponding lexing_exception is thrown.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename StringT>
|
||||
inline void
|
||||
validate_literal (StringT const &name, int line, int column,
|
||||
StringT const &file_name)
|
||||
{
|
||||
using namespace std; // some systems have strtoul in namespace std::
|
||||
|
||||
typename StringT::size_type pos = name.find_first_of('\\');
|
||||
|
||||
while (StringT::npos != pos) {
|
||||
// the literal contains a backslash (may be universal char)
|
||||
if ('u' == name[pos+1] || 'U' == name[pos+1]) {
|
||||
StringT uchar_val(name.substr(pos+2, ('u' == name[pos+1]) ? 4 : 8));
|
||||
universal_char_type type =
|
||||
classify_universal_char(strtoul(uchar_val.c_str(), 0, 16));
|
||||
|
||||
if (universal_char_type_valid != type &&
|
||||
universal_char_type_not_allowed_for_identifiers != type)
|
||||
{
|
||||
// an invalid char was found, so throw an exception
|
||||
StringT error_uchar(name.substr(pos, ('u' == name[pos+1]) ? 6 : 10));
|
||||
|
||||
if (universal_char_type_invalid == type) {
|
||||
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_invalid,
|
||||
error_uchar, line, column, file_name.c_str());
|
||||
}
|
||||
else {
|
||||
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_base_charset,
|
||||
error_uchar, line, column, file_name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find next universal char (if appropriate)
|
||||
pos = name.find_first_of('\\', pos+2);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
} // namespace cpplexer
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(VALIDATE_UNIVERSAL_CHAR_HPP_55F1B811_CD76_4C72_8344_CBC69CF3B339_INCLUDED)
|
||||
229
include/boost/wave/grammars/cpp_chlit_grammar.hpp
Normal file
@@ -0,0 +1,229 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)
|
||||
#define CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED
|
||||
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/attribute/closure.hpp>
|
||||
|
||||
#include <boost/spirit/phoenix/operators.hpp>
|
||||
#include <boost/spirit/phoenix/primitives.hpp>
|
||||
#include <boost/spirit/phoenix/statements.hpp>
|
||||
#include <boost/spirit/phoenix/functions.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reusable grammar to parse a C++ style character literal
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
namespace closures {
|
||||
|
||||
struct chlit_closure
|
||||
: boost::spirit::closure<chlit_closure, unsigned int>
|
||||
{
|
||||
member1 value;
|
||||
};
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// compose a multibyte character literal
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct compose_character_literal {
|
||||
|
||||
template <typename ResultT, typename ArgT>
|
||||
struct result {
|
||||
|
||||
typedef unsigned int type;
|
||||
};
|
||||
|
||||
unsigned int
|
||||
operator()(unsigned int res, unsigned int character) const
|
||||
{
|
||||
unsigned int retval = (res << 8) | (character & 0xff);
|
||||
return retval;
|
||||
}
|
||||
};
|
||||
phoenix::function<compose_character_literal> const compose;
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CHLIT_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
struct chlit_grammar :
|
||||
public boost::spirit::grammar<chlit_grammar,
|
||||
closures::chlit_closure::context_t>
|
||||
{
|
||||
chlit_grammar()
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "chlit_grammar",
|
||||
TRACE_CHLIT_GRAMMAR);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
typedef
|
||||
boost::spirit::rule<ScannerT, closures::chlit_closure::context_t>
|
||||
rule_t;
|
||||
|
||||
rule_t ch_lit;
|
||||
|
||||
definition(chlit_grammar const &self)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace phoenix;
|
||||
|
||||
ch_lit
|
||||
= !ch_p('L')
|
||||
>> ch_p('\'')[self.value = val(0)]
|
||||
>> +( (
|
||||
ch_p('\\')
|
||||
>> ( ch_p('a') // BEL
|
||||
[
|
||||
self.value = impl::compose(self.value, val(0x07))
|
||||
]
|
||||
| ch_p('b') // BS
|
||||
[
|
||||
self.value = impl::compose(self.value, val(0x08))
|
||||
]
|
||||
| ch_p('t') // HT
|
||||
[
|
||||
self.value = impl::compose(self.value, val(0x09))
|
||||
]
|
||||
| ch_p('n') // NL
|
||||
[
|
||||
self.value = impl::compose(self.value, val(0x0a))
|
||||
]
|
||||
| ch_p('v') // VT
|
||||
[
|
||||
self.value = impl::compose(self.value, val(0x0b))
|
||||
]
|
||||
| ch_p('f') // FF
|
||||
[
|
||||
self.value = impl::compose(self.value, val(0x0c))
|
||||
]
|
||||
| ch_p('r') // CR
|
||||
[
|
||||
self.value = impl::compose(self.value, val(0x0d))
|
||||
]
|
||||
| ch_p('?')
|
||||
[
|
||||
self.value = impl::compose(self.value, val('?'))
|
||||
]
|
||||
| ch_p('\'')
|
||||
[
|
||||
self.value = impl::compose(self.value, val('\''))
|
||||
]
|
||||
| ch_p('\"')
|
||||
[
|
||||
self.value = impl::compose(self.value, val('\"'))
|
||||
]
|
||||
| ch_p('\\')
|
||||
[
|
||||
self.value = impl::compose(self.value, val('\\'))
|
||||
]
|
||||
| ch_p('x')
|
||||
>> uint_parser<unsigned int, 16, 2, 2>()
|
||||
[
|
||||
self.value = impl::compose(self.value, arg1)
|
||||
]
|
||||
| ch_p('u')
|
||||
>> uint_parser<unsigned int, 16, 4, 4>()
|
||||
[
|
||||
self.value = impl::compose(self.value, arg1)
|
||||
]
|
||||
| ch_p('U')
|
||||
>> uint_parser<unsigned int, 16, 8, 8>()
|
||||
[
|
||||
self.value = impl::compose(self.value, arg1)
|
||||
]
|
||||
| uint_parser<unsigned int, 8, 1, 3>()
|
||||
[
|
||||
self.value = impl::compose(self.value, arg1)
|
||||
]
|
||||
)
|
||||
)
|
||||
| ~eps_p(ch_p('\'')) >> anychar_p
|
||||
[
|
||||
self.value = impl::compose(self.value, arg1)
|
||||
]
|
||||
)
|
||||
>> ch_p('\'')
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ch_lit, TRACE_CHLIT_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_t const& start() const
|
||||
{ return ch_lit; }
|
||||
};
|
||||
};
|
||||
|
||||
#undef TRACE_CHLIT_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following function is defined here, to allow the separation of
|
||||
// the compilation of the intlit_grammap from the function using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename TokenT>
|
||||
BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
|
||||
unsigned int
|
||||
chlit_grammar_gen<TokenT>::evaluate(TokenT const &token)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
|
||||
static chlit_grammar g;
|
||||
unsigned int result = 0;
|
||||
typename TokenT::string_type const &token_val = token.get_value();
|
||||
parse_info<typename TokenT::string_type::const_iterator> hit =
|
||||
parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
|
||||
|
||||
if (!hit.hit) {
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
||||
token_val, token.get_position());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)
|
||||
172
include/boost/wave/grammars/cpp_defined_grammar.hpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
|
||||
#define CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/attribute/closure.hpp>
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#include <boost/spirit/actor/assign_actor.hpp>
|
||||
#include <boost/spirit/actor/push_back_actor.hpp>
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
#include <boost/wave/grammars/cpp_defined_grammar_gen.hpp>
|
||||
|
||||
#if !defined(spirit_append_actor)
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
|
||||
#else
|
||||
#define spirit_append_actor(actor) boost::spirit::append(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
#endif // !defined(spirit_append_actor)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CPP_DEFINED_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
template <typename ContainerT>
|
||||
struct defined_grammar :
|
||||
public boost::spirit::grammar<defined_grammar<ContainerT> >
|
||||
{
|
||||
defined_grammar(ContainerT &result_seq_)
|
||||
: result_seq(result_seq_)
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "defined_grammar",
|
||||
TRACE_CPP_DEFINED_GRAMMAR);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
typedef boost::spirit::rule<ScannerT> rule_t;
|
||||
|
||||
rule_t defined_op;
|
||||
rule_t identifier;
|
||||
|
||||
definition(defined_grammar const &self)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::wave;
|
||||
using namespace boost::wave::util;
|
||||
|
||||
defined_op // parens not required, see C++ standard 16.1.1
|
||||
= ch_p(T_IDENTIFIER) // token contains 'defined'
|
||||
>> (
|
||||
( ch_p(T_LEFTPAREN)
|
||||
>> identifier
|
||||
>> ch_p(T_RIGHTPAREN)
|
||||
)
|
||||
| identifier
|
||||
)
|
||||
;
|
||||
|
||||
identifier
|
||||
= ch_p(T_IDENTIFIER)
|
||||
[
|
||||
spirit_append_actor(self.result_seq)
|
||||
]
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
[
|
||||
spirit_append_actor(self.result_seq)
|
||||
]
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(defined_op, TRACE_CPP_DEFINED_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(identifier, TRACE_CPP_DEFINED_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_t const& start() const
|
||||
{ return defined_op; }
|
||||
};
|
||||
|
||||
ContainerT &result_seq;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_CPP_DEFINED_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following parse function is defined here, to allow the separation of
|
||||
// the compilation of the defined_grammar from the function
|
||||
// using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
// The parse_operator_define function is instantiated manually twice to
|
||||
// simplify the explicit specialization of this template. This way the user
|
||||
// has only to specify one template parameter (the lexer type) to correctly
|
||||
// formulate the required explicit specialization.
|
||||
// This results in no code overhead, because otherwise the function would be
|
||||
// generated by the compiler twice anyway.
|
||||
|
||||
template <typename LexIteratorT>
|
||||
BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::parse_info<
|
||||
typename defined_grammar_gen<LexIteratorT>::iterator1_t
|
||||
>
|
||||
defined_grammar_gen<LexIteratorT>::parse_operator_defined (
|
||||
iterator1_t const &first, iterator1_t const &last,
|
||||
token_sequence_type &found_qualified_name)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::wave;
|
||||
|
||||
defined_grammar<token_sequence_type> g(found_qualified_name);
|
||||
return boost::spirit::parse (
|
||||
first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
|
||||
}
|
||||
|
||||
template <typename LexIteratorT>
|
||||
BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::parse_info<
|
||||
typename defined_grammar_gen<LexIteratorT>::iterator2_t
|
||||
>
|
||||
defined_grammar_gen<LexIteratorT>::parse_operator_defined (
|
||||
iterator2_t const &first, iterator2_t const &last,
|
||||
token_sequence_type &found_qualified_name)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::wave;
|
||||
|
||||
defined_grammar<token_sequence_type> g(found_qualified_name);
|
||||
return boost::spirit::parse (
|
||||
first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
|
||||
63
include/boost/wave/grammars/cpp_defined_grammar_gen.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED)
|
||||
#define CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <boost/spirit/core/parser.hpp>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
#include <boost/wave/util/unput_queue_iterator.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
template <typename LexIteratorT>
|
||||
struct defined_grammar_gen
|
||||
{
|
||||
typedef typename LexIteratorT::token_type token_type;
|
||||
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
|
||||
token_sequence_type;
|
||||
|
||||
// The parse_operator_define function is instantiated manually twice to
|
||||
// simplify the explicit specialization of this template. This way the user
|
||||
// has only to specify one template parameter (the lexer iterator type) to
|
||||
// correctly formulate the required explicit specialization.
|
||||
// This results in no code overhead, because otherwise the function would be
|
||||
// generated by the compiler twice anyway.
|
||||
|
||||
typedef boost::wave::util::unput_queue_iterator<
|
||||
typename token_sequence_type::iterator, token_type, token_sequence_type>
|
||||
iterator1_t;
|
||||
|
||||
typedef boost::wave::util::unput_queue_iterator<
|
||||
LexIteratorT, token_type, token_sequence_type>
|
||||
iterator2_t;
|
||||
|
||||
// parse the operator defined and return the found qualified name
|
||||
static boost::spirit::parse_info<iterator1_t>
|
||||
parse_operator_defined (iterator1_t const &first, iterator1_t const &last,
|
||||
token_sequence_type &found_qualified_name);
|
||||
|
||||
static boost::spirit::parse_info<iterator2_t>
|
||||
parse_operator_defined (iterator2_t const &first, iterator2_t const &last,
|
||||
token_sequence_type &found_qualified_name);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED)
|
||||
710
include/boost/wave/grammars/cpp_expression_grammar.hpp
Normal file
@@ -0,0 +1,710 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|
||||
#define CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/attribute/closure.hpp>
|
||||
#include <boost/spirit/dynamic/if.hpp>
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#include <boost/spirit/actor/assign_actor.hpp>
|
||||
#include <boost/spirit/actor/push_back_actor.hpp>
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
|
||||
#include <boost/spirit/phoenix/functions.hpp>
|
||||
#include <boost/spirit/phoenix/operators.hpp>
|
||||
#include <boost/spirit/phoenix/primitives.hpp>
|
||||
#include <boost/spirit/phoenix/statements.hpp>
|
||||
#include <boost/spirit/phoenix/casts.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
#include <boost/wave/grammars/cpp_expression_grammar_gen.hpp>
|
||||
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
|
||||
#include <boost/wave/grammars/cpp_expression_value.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
#include <boost/wave/util/macro_helpers.hpp>
|
||||
|
||||
#if !defined(spirit_append_actor)
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
|
||||
#else
|
||||
#define spirit_append_actor(actor) boost::spirit::append(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
#endif // !defined(spirit_append_actor)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Encapsulation of the grammar for evaluation of constant preprocessor
|
||||
// expressions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
namespace closures {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// define the closure type used throughout the C++ expression grammar
|
||||
//
|
||||
// Throughout this grammar all literal tokens are stored into a
|
||||
// closure_value variables, which converts the types appropriately, where
|
||||
// required.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct cpp_expr_closure
|
||||
: boost::spirit::closure<cpp_expr_closure, closure_value>
|
||||
{
|
||||
member1 val;
|
||||
};
|
||||
|
||||
} // namespace closures
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// convert the given tokenvalue (integer literal) to a unsigned long
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct convert_intlit {
|
||||
|
||||
template <typename ArgT>
|
||||
struct result {
|
||||
|
||||
typedef boost::wave::grammars::closures::closure_value type;
|
||||
};
|
||||
|
||||
template <typename TokenT>
|
||||
boost::wave::grammars::closures::closure_value
|
||||
operator()(TokenT const &token) const
|
||||
{
|
||||
typedef boost::wave::grammars::closures::closure_value return_t;
|
||||
bool is_unsigned = false;
|
||||
unsigned long ul = intlit_grammar_gen<TokenT>::evaluate(token,
|
||||
is_unsigned);
|
||||
|
||||
return is_unsigned ? return_t(ul) : return_t(static_cast<long>(ul));
|
||||
}
|
||||
};
|
||||
phoenix::function<convert_intlit> const as_intlit;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// convert the given tokenvalue (character literal) to a unsigned int
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct convert_chlit {
|
||||
|
||||
template <typename ArgT>
|
||||
struct result {
|
||||
|
||||
typedef boost::wave::grammars::closures::closure_value type;
|
||||
};
|
||||
|
||||
template <typename TokenT>
|
||||
boost::wave::grammars::closures::closure_value
|
||||
operator()(TokenT const &token) const
|
||||
{
|
||||
typedef boost::wave::grammars::closures::closure_value return_t;
|
||||
return return_t(chlit_grammar_gen<TokenT>::evaluate(token));
|
||||
}
|
||||
};
|
||||
phoenix::function<convert_chlit> const as_chlit;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Handle the ?: operator with correct type propagation
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct operator_questionmark {
|
||||
|
||||
template <typename CondT, typename Arg1T, typename Arg2T>
|
||||
struct result {
|
||||
|
||||
typedef boost::wave::grammars::closures::closure_value type;
|
||||
};
|
||||
|
||||
template <typename CondT, typename Arg1T, typename Arg2T>
|
||||
boost::wave::grammars::closures::closure_value
|
||||
operator()(CondT const &cond, Arg1T &val1, Arg2T const &val2) const
|
||||
{
|
||||
typedef boost::wave::grammars::closures::closure_value return_t;
|
||||
return return_t(val1.handle_questionmark(cond, val2));
|
||||
}
|
||||
};
|
||||
phoenix::function<operator_questionmark> const questionmark;
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CPP_EXPR_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
struct expression_grammar :
|
||||
public boost::spirit::grammar<
|
||||
expression_grammar,
|
||||
closures::cpp_expr_closure::context_t
|
||||
>
|
||||
{
|
||||
expression_grammar()
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "expression_grammar",
|
||||
TRACE_CPP_EXPR_GRAMMAR);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
typedef closures::cpp_expr_closure closure_type;
|
||||
typedef boost::spirit::rule<ScannerT, closure_type::context_t> rule_t;
|
||||
typedef boost::spirit::rule<ScannerT> simple_rule_t;
|
||||
|
||||
simple_rule_t pp_expression;
|
||||
|
||||
rule_t const_exp;
|
||||
rule_t logical_or_exp, logical_and_exp;
|
||||
rule_t inclusive_or_exp, exclusive_or_exp, and_exp;
|
||||
rule_t cmp_equality, cmp_relational;
|
||||
rule_t shift_exp;
|
||||
rule_t add_exp, multiply_exp;
|
||||
rule_t unary_exp, primary_exp, constant;
|
||||
|
||||
rule_t const_exp_nocalc;
|
||||
rule_t logical_or_exp_nocalc, logical_and_exp_nocalc;
|
||||
rule_t inclusive_or_exp_nocalc, exclusive_or_exp_nocalc, and_exp_nocalc;
|
||||
rule_t cmp_equality_nocalc, cmp_relational_nocalc;
|
||||
rule_t shift_exp_nocalc;
|
||||
rule_t add_exp_nocalc, multiply_exp_nocalc;
|
||||
rule_t unary_exp_nocalc, primary_exp_nocalc, constant_nocalc;
|
||||
|
||||
boost::spirit::subrule<0, closure_type::context_t> const_exp_subrule;
|
||||
|
||||
definition(expression_grammar const &self)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace phoenix;
|
||||
using namespace boost::wave;
|
||||
using boost::wave::util::pattern_p;
|
||||
|
||||
pp_expression
|
||||
= const_exp[self.val = arg1]
|
||||
;
|
||||
|
||||
const_exp
|
||||
= logical_or_exp[const_exp.val = arg1]
|
||||
>> !(const_exp_subrule =
|
||||
ch_p(T_QUESTION_MARK)
|
||||
>> const_exp
|
||||
[
|
||||
const_exp_subrule.val = arg1
|
||||
]
|
||||
>> ch_p(T_COLON)
|
||||
>> const_exp
|
||||
[
|
||||
const_exp_subrule.val =
|
||||
impl::questionmark(const_exp.val,
|
||||
const_exp_subrule.val, arg1)
|
||||
]
|
||||
)[const_exp.val = arg1]
|
||||
;
|
||||
|
||||
logical_or_exp
|
||||
= logical_and_exp[logical_or_exp.val = arg1]
|
||||
>> *( if_p(static_cast_<bool>(logical_or_exp.val))
|
||||
[
|
||||
// if one of the || operators is true, no more
|
||||
// evaluation is required
|
||||
pattern_p(T_OROR, MainTokenMask)
|
||||
>> logical_and_exp_nocalc
|
||||
[
|
||||
logical_or_exp.val =
|
||||
static_cast_<bool>(logical_or_exp.val)
|
||||
]
|
||||
]
|
||||
.else_p
|
||||
[
|
||||
pattern_p(T_OROR, MainTokenMask)
|
||||
>> logical_and_exp
|
||||
[
|
||||
logical_or_exp.val =
|
||||
logical_or_exp.val || arg1
|
||||
]
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
logical_and_exp
|
||||
= inclusive_or_exp[logical_and_exp.val = arg1]
|
||||
>> *( if_p(static_cast_<bool>(logical_and_exp.val))
|
||||
[
|
||||
pattern_p(T_ANDAND, MainTokenMask)
|
||||
>> inclusive_or_exp
|
||||
[
|
||||
logical_and_exp.val =
|
||||
logical_and_exp.val && arg1
|
||||
]
|
||||
]
|
||||
.else_p
|
||||
[
|
||||
// if one of the && operators is false, no more
|
||||
// evaluation is required
|
||||
pattern_p(T_ANDAND, MainTokenMask)
|
||||
>> inclusive_or_exp_nocalc
|
||||
[
|
||||
logical_and_exp.val =
|
||||
static_cast_<bool>(logical_and_exp.val)
|
||||
]
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
inclusive_or_exp
|
||||
= exclusive_or_exp[inclusive_or_exp.val = arg1]
|
||||
>> *( pattern_p(T_OR, MainTokenMask)
|
||||
>> exclusive_or_exp
|
||||
[
|
||||
inclusive_or_exp.val =
|
||||
static_cast_<unsigned int>(inclusive_or_exp.val)
|
||||
| static_cast_<unsigned int>(arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
exclusive_or_exp
|
||||
= and_exp[exclusive_or_exp.val = arg1]
|
||||
>> *( pattern_p(T_XOR, MainTokenMask)
|
||||
>> and_exp
|
||||
[
|
||||
exclusive_or_exp.val =
|
||||
static_cast_<unsigned int>(exclusive_or_exp.val)
|
||||
^ static_cast_<unsigned int>(arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
and_exp
|
||||
= cmp_equality[and_exp.val = arg1]
|
||||
>> *( pattern_p(T_AND, MainTokenMask)
|
||||
>> cmp_equality
|
||||
[
|
||||
and_exp.val =
|
||||
static_cast_<unsigned int>(and_exp.val)
|
||||
& static_cast_<unsigned int>(arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
cmp_equality
|
||||
= cmp_relational[cmp_equality.val = arg1]
|
||||
>> *( ch_p(T_EQUAL)
|
||||
>> cmp_relational
|
||||
[
|
||||
cmp_equality.val =
|
||||
cmp_equality.val == arg1
|
||||
]
|
||||
| pattern_p(T_NOTEQUAL, MainTokenMask)
|
||||
>> cmp_relational
|
||||
[
|
||||
cmp_equality.val =
|
||||
cmp_equality.val != arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
cmp_relational
|
||||
= shift_exp[cmp_relational.val = arg1]
|
||||
>> *( ch_p(T_LESSEQUAL)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
cmp_relational.val <= arg1
|
||||
]
|
||||
| ch_p(T_GREATEREQUAL)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
cmp_relational.val >= arg1
|
||||
]
|
||||
| ch_p(T_LESS)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
cmp_relational.val < arg1
|
||||
]
|
||||
| ch_p(T_GREATER)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
cmp_relational.val > arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
shift_exp
|
||||
= add_exp[shift_exp.val = arg1]
|
||||
>> *( ch_p(T_SHIFTLEFT)
|
||||
>> add_exp
|
||||
[
|
||||
shift_exp.val <<= arg1
|
||||
]
|
||||
| ch_p(T_SHIFTRIGHT)
|
||||
>> add_exp
|
||||
[
|
||||
shift_exp.val >>= arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
add_exp
|
||||
= multiply_exp[add_exp.val = arg1]
|
||||
>> *( ch_p(T_PLUS)
|
||||
>> multiply_exp
|
||||
[
|
||||
add_exp.val += arg1
|
||||
]
|
||||
| ch_p(T_MINUS)
|
||||
>> multiply_exp
|
||||
[
|
||||
add_exp.val -= arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
multiply_exp
|
||||
= unary_exp[multiply_exp.val = arg1]
|
||||
>> *( ch_p(T_STAR)
|
||||
>> unary_exp
|
||||
[
|
||||
multiply_exp.val *= arg1
|
||||
]
|
||||
| ch_p(T_DIVIDE)
|
||||
>> unary_exp
|
||||
[
|
||||
multiply_exp.val /= arg1
|
||||
]
|
||||
| ch_p(T_PERCENT)
|
||||
>> unary_exp
|
||||
[
|
||||
multiply_exp.val =
|
||||
static_cast_<int>(multiply_exp.val)
|
||||
% static_cast_<int>(arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
unary_exp
|
||||
= primary_exp[unary_exp.val = arg1]
|
||||
| ch_p(T_PLUS) >> unary_exp
|
||||
[
|
||||
unary_exp.val = static_cast_<int>(arg1)
|
||||
]
|
||||
| ch_p(T_MINUS) >> unary_exp
|
||||
[
|
||||
unary_exp.val = -static_cast_<int>(arg1)
|
||||
]
|
||||
| pattern_p(T_COMPL, MainTokenMask) >> unary_exp
|
||||
[
|
||||
unary_exp.val = ~static_cast_<unsigned int>(arg1)
|
||||
]
|
||||
| pattern_p(T_NOT, MainTokenMask) >> unary_exp
|
||||
[
|
||||
unary_exp.val = !static_cast_<bool>(arg1)
|
||||
]
|
||||
;
|
||||
|
||||
primary_exp
|
||||
= constant[primary_exp.val = arg1]
|
||||
| ch_p(T_LEFTPAREN)
|
||||
>> const_exp[primary_exp.val = arg1]
|
||||
>> ch_p(T_RIGHTPAREN)
|
||||
;
|
||||
|
||||
constant
|
||||
= ch_p(T_INTLIT)
|
||||
[
|
||||
constant.val = impl::as_intlit(arg1)
|
||||
]
|
||||
| ch_p(T_CHARLIT)
|
||||
[
|
||||
constant.val = impl::as_chlit(arg1)
|
||||
]
|
||||
;
|
||||
|
||||
// here follows the same grammar, but without any embedded
|
||||
// calculations
|
||||
const_exp_nocalc
|
||||
= logical_or_exp_nocalc
|
||||
>> !( ch_p(T_QUESTION_MARK)
|
||||
>> const_exp_nocalc
|
||||
>> ch_p(T_COLON)
|
||||
>> const_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
logical_or_exp_nocalc
|
||||
= logical_and_exp_nocalc
|
||||
>> *( pattern_p(T_OROR, MainTokenMask)
|
||||
>> logical_and_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
logical_and_exp_nocalc
|
||||
= inclusive_or_exp_nocalc
|
||||
>> *( pattern_p(T_ANDAND, MainTokenMask)
|
||||
>> inclusive_or_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
inclusive_or_exp_nocalc
|
||||
= exclusive_or_exp_nocalc
|
||||
>> *( pattern_p(T_OR, MainTokenMask)
|
||||
>> exclusive_or_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
exclusive_or_exp_nocalc
|
||||
= and_exp_nocalc
|
||||
>> *( pattern_p(T_XOR, MainTokenMask)
|
||||
>> and_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
and_exp_nocalc
|
||||
= cmp_equality_nocalc
|
||||
>> *( pattern_p(T_AND, MainTokenMask)
|
||||
>> cmp_equality_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
cmp_equality_nocalc
|
||||
= cmp_relational_nocalc
|
||||
>> *( ch_p(T_EQUAL)
|
||||
>> cmp_relational_nocalc
|
||||
| pattern_p(T_NOTEQUAL, MainTokenMask)
|
||||
>> cmp_relational_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
cmp_relational_nocalc
|
||||
= shift_exp_nocalc
|
||||
>> *( ch_p(T_LESSEQUAL)
|
||||
>> shift_exp_nocalc
|
||||
| ch_p(T_GREATEREQUAL)
|
||||
>> shift_exp_nocalc
|
||||
| ch_p(T_LESS)
|
||||
>> shift_exp_nocalc
|
||||
| ch_p(T_GREATER)
|
||||
>> shift_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
shift_exp_nocalc
|
||||
= add_exp_nocalc
|
||||
>> *( ch_p(T_SHIFTLEFT)
|
||||
>> add_exp_nocalc
|
||||
| ch_p(T_SHIFTRIGHT)
|
||||
>> add_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
add_exp_nocalc
|
||||
= multiply_exp_nocalc
|
||||
>> *( ch_p(T_PLUS)
|
||||
>> multiply_exp_nocalc
|
||||
| ch_p(T_MINUS)
|
||||
>> multiply_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
multiply_exp_nocalc
|
||||
= unary_exp_nocalc
|
||||
>> *( ch_p(T_STAR)
|
||||
>> unary_exp_nocalc
|
||||
| ch_p(T_DIVIDE)
|
||||
>> unary_exp_nocalc
|
||||
| ch_p(T_PERCENT)
|
||||
>> unary_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
unary_exp_nocalc
|
||||
= primary_exp_nocalc
|
||||
| ch_p(T_PLUS) >> unary_exp_nocalc
|
||||
| ch_p(T_MINUS) >> unary_exp_nocalc
|
||||
| pattern_p(T_COMPL, MainTokenMask) >> unary_exp_nocalc
|
||||
| pattern_p(T_NOT, MainTokenMask) >> unary_exp_nocalc
|
||||
;
|
||||
|
||||
primary_exp_nocalc
|
||||
= constant_nocalc
|
||||
| ch_p(T_LEFTPAREN)
|
||||
>> const_exp_nocalc
|
||||
>> ch_p(T_RIGHTPAREN)
|
||||
;
|
||||
|
||||
constant_nocalc
|
||||
= ch_p(T_INTLIT)
|
||||
| ch_p(T_CHARLIT)
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_expression, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(constant, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_subrule, TRACE_CPP_EXPR_GRAMMAR);
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(constant_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
simple_rule_t const& start() const
|
||||
{ return pp_expression; }
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_CPP_EXPR_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following function is defined here, to allow the separation of
|
||||
// the compilation of the expression_grammar from the function using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename TokenT>
|
||||
BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
||||
bool
|
||||
expression_grammar_gen<TokenT>::evaluate(
|
||||
typename token_sequence_type::const_iterator const &first,
|
||||
typename token_sequence_type::const_iterator const &last,
|
||||
typename token_type::position_type const &act_pos,
|
||||
bool if_block_status)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::wave;
|
||||
|
||||
typedef typename token_sequence_type::const_iterator iterator_type;
|
||||
|
||||
static expression_grammar g; // expression grammar
|
||||
boost::wave::grammars::closures::closure_value result; // expression result
|
||||
parse_info<iterator_type> hit = parse (first, last, g[spirit_assign_actor(result)],
|
||||
ch_p(T_SPACE) | ch_p(T_CCOMMENT) | ch_p(T_CPPCOMMENT));
|
||||
|
||||
if (!hit.hit) {
|
||||
// expression is illformed
|
||||
if (if_block_status) {
|
||||
typedef typename token_sequence_type::value_type::string_type string_type;
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
||||
boost::wave::util::impl::as_string<string_type>(first, last), act_pos);
|
||||
}
|
||||
else {
|
||||
// as the if_block_status is false any errors will not be reported
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hit.full) {
|
||||
// The token list starts with a valid expression, but there remains
|
||||
// something. If the remainder consists out of whitespace only, the
|
||||
// expression is still valid.
|
||||
iterator_type next = hit.stop;
|
||||
|
||||
while (next != last) {
|
||||
switch (token_id(*next)) {
|
||||
case T_SPACE:
|
||||
case T_SPACE2:
|
||||
case T_CCOMMENT:
|
||||
break; // ok continue
|
||||
|
||||
case T_NEWLINE:
|
||||
case T_EOF:
|
||||
case T_CPPCOMMENT: // contains newline
|
||||
return bool(result); // expression is valid
|
||||
|
||||
default:
|
||||
// expression is illformed
|
||||
if (if_block_status) {
|
||||
typedef typename token_sequence_type::value_type::string_type
|
||||
string_type;
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
||||
boost::wave::util::impl::as_string<string_type>(first, last),
|
||||
act_pos);
|
||||
}
|
||||
else {
|
||||
// as the if_block_status is false any errors will not be
|
||||
// reported
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++next;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.is_valid()) {
|
||||
// division by zero occured
|
||||
typedef typename token_sequence_type::value_type::string_type string_type;
|
||||
BOOST_WAVE_THROW(preprocess_exception, division_by_zero,
|
||||
boost::wave::util::impl::as_string<string_type>(first, last),
|
||||
act_pos);
|
||||
}
|
||||
|
||||
// token sequence is a valid expression
|
||||
return bool(result);
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|
||||
53
include/boost/wave/grammars/cpp_expression_grammar_gen.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED)
|
||||
#define CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED
|
||||
|
||||
#include <list>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
#include <boost/wave/cpp_iteration_context.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// expression_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the
|
||||
// expression_grammar class from the compilation of the main
|
||||
// pp_iterator. This is done to safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename TokenT>
|
||||
struct expression_grammar_gen {
|
||||
|
||||
typedef TokenT token_type;
|
||||
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
|
||||
token_sequence_type;
|
||||
|
||||
static bool evaluate(
|
||||
typename token_sequence_type::const_iterator const &first,
|
||||
typename token_sequence_type::const_iterator const &last,
|
||||
typename token_type::position_type const &tok,
|
||||
bool if_block_status);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED)
|
||||
585
include/boost/wave/grammars/cpp_expression_value.hpp
Normal file
@@ -0,0 +1,585 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
|
||||
#define CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED
|
||||
|
||||
#if defined (BOOST_SPIRIT_DEBUG)
|
||||
#include <iostream>
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
namespace closures {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The closure_value class represents the closure type, which is used for the
|
||||
// expression grammar.
|
||||
//
|
||||
// This class was introduced to allow the expression grammar to respect
|
||||
// the numeric type of a numeric literal or expression result.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class closure_value {
|
||||
public:
|
||||
|
||||
enum value_type {
|
||||
is_int = 1,
|
||||
is_uint = 2,
|
||||
is_bool = 3
|
||||
};
|
||||
|
||||
closure_value(bool valid_ = true)
|
||||
: type(is_int), valid(valid_)
|
||||
{ value.i = 0; }
|
||||
explicit closure_value(int i, bool valid_ = true)
|
||||
: type(is_int), valid(valid_)
|
||||
{ value.i = i; }
|
||||
explicit closure_value(unsigned int ui, bool valid_ = true)
|
||||
: type(is_uint), valid(valid_)
|
||||
{ value.ui = ui; }
|
||||
explicit closure_value(long i, bool valid_ = true)
|
||||
: type(is_int), valid(valid_)
|
||||
{ value.i = i; }
|
||||
explicit closure_value(unsigned long ui, bool valid_ = true)
|
||||
: type(is_uint), valid(valid_)
|
||||
{ value.ui = ui; }
|
||||
explicit closure_value(bool b, bool valid_ = true)
|
||||
: type(is_bool), valid(valid_)
|
||||
{ value.b = b; }
|
||||
|
||||
value_type get_type() const { return type; }
|
||||
bool is_valid() const { return valid; }
|
||||
|
||||
// implicit conversion
|
||||
operator int() const
|
||||
{
|
||||
switch (type) {
|
||||
case is_uint: return value.ui;
|
||||
case is_bool: return value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return value.i;
|
||||
}
|
||||
operator unsigned int() const
|
||||
{
|
||||
switch (type) {
|
||||
case is_uint: return value.ui;
|
||||
case is_bool: return value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return value.i;
|
||||
}
|
||||
operator long() const
|
||||
{
|
||||
switch (type) {
|
||||
case is_uint: return value.ui;
|
||||
case is_bool: return value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return value.i;
|
||||
}
|
||||
operator unsigned long() const
|
||||
{
|
||||
switch (type) {
|
||||
case is_uint: return value.ui;
|
||||
case is_bool: return value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return value.i;
|
||||
}
|
||||
operator bool() const
|
||||
{
|
||||
switch (type) {
|
||||
case is_uint: return value.ui != 0;
|
||||
case is_bool: return value.b;
|
||||
case is_int: break;
|
||||
}
|
||||
return value.i != 0.0;
|
||||
}
|
||||
|
||||
// assignment
|
||||
closure_value &operator= (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.get_type()) {
|
||||
case is_int:
|
||||
value.i = long(rhs);
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.ui = (unsigned long)(rhs);
|
||||
type = is_uint;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
value.b = bool(rhs);
|
||||
type = is_bool;
|
||||
break;
|
||||
}
|
||||
valid = rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (int rhs)
|
||||
{
|
||||
type = is_int;
|
||||
value.i = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (unsigned int rhs)
|
||||
{
|
||||
type = is_uint;
|
||||
value.ui = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (long rhs)
|
||||
{
|
||||
type = is_int;
|
||||
value.i = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (unsigned long rhs)
|
||||
{
|
||||
type = is_uint;
|
||||
value.ui = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (bool rhs)
|
||||
{
|
||||
type = is_bool;
|
||||
value.b = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// arithmetics
|
||||
closure_value &operator+= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: value.i += long(rhs); break;
|
||||
case is_int: value.i += rhs.value.i; break;
|
||||
case is_uint: value.ui += rhs.value.ui; type = is_uint; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: value.ui += (unsigned long)(rhs); break;
|
||||
case is_bool:
|
||||
value.i = value.b + bool(rhs);
|
||||
type = is_int;
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator-= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: value.i -= long(rhs); break;
|
||||
case is_int: value.i -= rhs.value.i; break;
|
||||
case is_uint: value.ui -= rhs.value.ui; type = is_uint; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: value.ui -= (unsigned long)(rhs); break;
|
||||
case is_bool:
|
||||
value.i = value.b - bool(rhs);
|
||||
type = is_int;
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator*= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: value.i *= long(rhs); break;
|
||||
case is_int: value.i *= rhs.value.i; break;
|
||||
case is_uint: value.ui *= rhs.value.ui; type = is_uint; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: value.ui *= (unsigned long)(rhs); break;
|
||||
case is_bool:
|
||||
switch (rhs.type) {
|
||||
case is_int:
|
||||
value.i = (value.b ? 1 : 0) * rhs.value.i;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.ui = (value.b ? 1 : 0) * rhs.value.ui;
|
||||
type = is_uint;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator/= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
if (valid && long(rhs) != 0)
|
||||
value.i /= long(rhs);
|
||||
else
|
||||
valid = false; // division by zero
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (valid && rhs.value.ui != 0) {
|
||||
value.ui /= rhs.value.ui;
|
||||
type = is_uint;
|
||||
}
|
||||
else {
|
||||
valid = false; // division by zero
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (valid && (unsigned long)(rhs) != 0)
|
||||
value.ui /= (unsigned long)(rhs);
|
||||
else
|
||||
valid = false; // division by zero
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
if (valid && bool(rhs)) {
|
||||
switch(rhs.type) {
|
||||
case is_int:
|
||||
value.i = (value.b ? 1 : 0) / rhs.value.i;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.i = (value.b ? 1 : 0) / rhs.value.ui;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
valid = false; // division by zero
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator- (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.type) {
|
||||
case is_int: return closure_value(-long(rhs), rhs.valid);
|
||||
case is_bool: return closure_value(!bool(rhs), rhs.valid);
|
||||
case is_uint: break;
|
||||
}
|
||||
return closure_value(-(int)(unsigned long)(rhs), rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator! (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.type) {
|
||||
case is_int: return closure_value(!long(rhs), rhs.valid);
|
||||
case is_bool: return closure_value(!bool(rhs), rhs.valid);
|
||||
case is_uint: break;
|
||||
}
|
||||
return closure_value(!(unsigned long)(rhs), rhs.valid);
|
||||
}
|
||||
|
||||
// comparison
|
||||
friend closure_value
|
||||
operator== (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = bool(lhs) == rhs.value.b; break;
|
||||
case is_int: cmp = lhs.value.i == rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui == rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui == (unsigned long)(rhs); break;
|
||||
case is_bool: cmp = lhs.value.b == bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator!= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!bool(lhs == rhs), lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator> (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = lhs.value.i > long(rhs); break;
|
||||
case is_int: cmp = lhs.value.i > rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui > rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui > (unsigned long)(rhs); break;
|
||||
case is_bool: cmp = lhs.value.b > bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator< (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int: cmp = long(lhs) < long(rhs); break;
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = lhs.value.i < long(rhs); break;
|
||||
case is_int: cmp = lhs.value.i < rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui < rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui < (unsigned long)(rhs); break;
|
||||
case is_bool: cmp = bool(lhs) < bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator<= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!bool(lhs > rhs), lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator>= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!bool(lhs < rhs), lhs.valid && rhs.valid);
|
||||
}
|
||||
|
||||
closure_value &
|
||||
operator<<= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.i <<= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = (unsigned long)(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui <<= shift_by;
|
||||
|
||||
// Note: The usual arithmetic conversions are not performed on
|
||||
// bit shift operations.
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.ui <<= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = (unsigned long)(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui <<= shift_by;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
closure_value &
|
||||
operator>>= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.i >>= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = (unsigned long)(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui >>= shift_by;
|
||||
|
||||
// Note: The usual arithmetic conversions are not performed on
|
||||
// bit shift operations.
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.ui >>= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = (unsigned long)(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui >>= shift_by;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator|| (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool result = bool(lhs) || bool(rhs);
|
||||
return closure_value(result, lhs.valid && rhs.valid);
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator&& (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool result = bool(lhs) && bool(rhs);
|
||||
return closure_value(result, lhs.valid && rhs.valid);
|
||||
}
|
||||
|
||||
// handle the ?: operator
|
||||
closure_value &
|
||||
handle_questionmark(closure_value const &cond, closure_value const &val2)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch (val2.type) {
|
||||
case is_bool: value.b = bool(cond) ? value.b : bool(val2); break;
|
||||
case is_int: value.i = bool(cond) ? value.i : long(val2); break;
|
||||
case is_uint:
|
||||
value.ui = bool(cond) ? value.ui : (unsigned long)(val2);
|
||||
type = is_uint; // changing type!
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: value.ui = bool(cond) ? value.ui : (unsigned long)(val2); break;
|
||||
case is_bool: value.b = bool(cond) ? value.b : bool(val2); break;
|
||||
}
|
||||
valid = bool(cond) ? valid : val2.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined (BOOST_SPIRIT_DEBUG)
|
||||
friend std::ostream&
|
||||
operator<< (std::ostream &o, closure_value const &val)
|
||||
{
|
||||
switch (val.type) {
|
||||
case is_int: o << "int(" << long(val) << ")"; break;
|
||||
case is_uint: o << "unsigned int(" << (unsigned long)(val) << ")"; break;
|
||||
case is_bool: o << "bool(" << bool(val) << ")"; break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
private:
|
||||
value_type type;
|
||||
union {
|
||||
long i;
|
||||
unsigned long ui;
|
||||
bool b;
|
||||
} value;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace closures
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
|
||||
556
include/boost/wave/grammars/cpp_expression_variant.hpp
Normal file
@@ -0,0 +1,556 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
|
||||
#define CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED
|
||||
|
||||
#if defined (BOOST_SPIRIT_DEBUG)
|
||||
#include <iostream>
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
namespace closures {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Definition of the variant visitors needed for type correct value access
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct long_visitor : public boost::static_visitor<long>
|
||||
{
|
||||
template <typename T>
|
||||
long operator() (T val)
|
||||
{
|
||||
return T(val);
|
||||
}
|
||||
};
|
||||
|
||||
struct ulong_visitor : public boost::static_visitor<unsigned long>
|
||||
{
|
||||
template <typename T>
|
||||
unsigned long operator() (T val)
|
||||
{
|
||||
return T(val);
|
||||
}
|
||||
};
|
||||
|
||||
struct bool_visitor : public boost::static_visitor<bool>
|
||||
{
|
||||
template <typename T>
|
||||
bool operator() (T val)
|
||||
{
|
||||
return T(val);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Definition of the variant visitors needed for unary and binary operations
|
||||
// on the expression values.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct plus_visitor : public boost::static_visitor<>
|
||||
{
|
||||
template <typename T1, typename T2>
|
||||
void operator()(unsigned long &lhs, T2 rhs) const
|
||||
{
|
||||
return lhs + rhs;
|
||||
}
|
||||
};
|
||||
|
||||
struct minus_visitor : public boost::static_visitor<long>
|
||||
{
|
||||
template <typename T1, typename T2>
|
||||
long operator()(T1 lhs, T2 rhs) const
|
||||
{
|
||||
return lhs - rhs;
|
||||
}
|
||||
};
|
||||
|
||||
struct multiply_visitor : public boost::static_visitor<long>
|
||||
{
|
||||
template <typename T1, typename T2>
|
||||
long operator()(T1 &lhs, T2 rhs) const
|
||||
{
|
||||
lhs *= rhs;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The closure_value class represents the closure type, which is used for the
|
||||
// expression grammar.
|
||||
//
|
||||
// This class was introduced to allow the expression grammar to respect
|
||||
// the numeric type of a numeric literal or expression result.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class closure_value
|
||||
{
|
||||
public:
|
||||
|
||||
closure_value()
|
||||
: value(0L), valid(true)
|
||||
{}
|
||||
explicit closure_value(long i, bool valid_ = true)
|
||||
: value(i), valid(valid_)
|
||||
{}
|
||||
explicit closure_value(unsigned long ui, bool valid_ = true)
|
||||
: value(ui), valid(valid_)
|
||||
{}
|
||||
explicit closure_value(bool b, bool valid_ = true)
|
||||
: value(b), valid(valid_)
|
||||
{}
|
||||
|
||||
bool is_valid() const { return valid; }
|
||||
|
||||
// implicit conversion
|
||||
operator long() const
|
||||
{
|
||||
return as_long();
|
||||
}
|
||||
operator unsigned long() const
|
||||
{
|
||||
return as_ulong();
|
||||
}
|
||||
operator bool() const
|
||||
{
|
||||
return as_bool();
|
||||
}
|
||||
|
||||
// assignment
|
||||
closure_value &operator= (long rhs)
|
||||
{
|
||||
value = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (unsigned long rhs)
|
||||
{
|
||||
value = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (bool rhs)
|
||||
{
|
||||
value = rhs;
|
||||
valid = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// arithmetics
|
||||
closure_value &operator+= (closure_value const &rhs)
|
||||
{
|
||||
if (valid = valid && rhs.valid)
|
||||
value = boost::apply_visitor(plus_visitor(), value, rhs.value);
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator-= (closure_value const &rhs)
|
||||
{
|
||||
if (valid = valid && rhs.valid)
|
||||
value = boost::apply_visitor(minus_visitor(), value, rhs.value);
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator*= (closure_value const &rhs)
|
||||
{
|
||||
if (valid = valid && rhs.valid)
|
||||
value = boost::apply_visitor(multiply_visitor(), value, rhs.value);
|
||||
return *this;
|
||||
}
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: value.i *= long(rhs); break;
|
||||
case is_int: value.i *= rhs.value.i; break;
|
||||
case is_uint: value.ui *= rhs.value.ui; type = is_uint; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: value.ui *= unsigned long(rhs); break;
|
||||
case is_bool:
|
||||
switch (rhs.type) {
|
||||
case is_int:
|
||||
value.i = (value.b ? 1 : 0) * rhs.value.i;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.ui = (value.b ? 1 : 0) * rhs.value.ui;
|
||||
type = is_uint;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator/= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
if (valid && long(rhs) != 0)
|
||||
value.i /= long(rhs);
|
||||
else
|
||||
valid = false; // division by zero
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (valid && rhs.value.ui != 0) {
|
||||
value.ui /= rhs.value.ui;
|
||||
type = is_uint;
|
||||
}
|
||||
else {
|
||||
valid = false; // division by zero
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (valid && unsigned long(rhs) != 0)
|
||||
value.ui /= unsigned long(rhs);
|
||||
else
|
||||
valid = false; // division by zero
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
if (valid && bool(rhs)) {
|
||||
switch(rhs.type) {
|
||||
case is_int:
|
||||
value.i = (value.b ? 1 : 0) / rhs.value.i;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.i = (value.b ? 1 : 0) / rhs.value.ui;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
valid = false; // division by zero
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator- (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.type) {
|
||||
case is_int: return closure_value(-long(rhs), rhs.valid);
|
||||
case is_bool: return closure_value(!bool(rhs), rhs.valid);
|
||||
case is_uint: break;
|
||||
}
|
||||
return closure_value(-(int)unsigned long(rhs), rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator! (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.type) {
|
||||
case is_int: return closure_value(!long(rhs), rhs.valid);
|
||||
case is_bool: return closure_value(!bool(rhs), rhs.valid);
|
||||
case is_uint: break;
|
||||
}
|
||||
return closure_value(!unsigned long(rhs), rhs.valid);
|
||||
}
|
||||
|
||||
// comparison
|
||||
friend closure_value
|
||||
operator== (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = bool(lhs) == rhs.value.b; break;
|
||||
case is_int: cmp = lhs.value.i == rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui == rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui == unsigned long(rhs); break;
|
||||
case is_bool: cmp = lhs.value.b == bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator!= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!bool(lhs == rhs), lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator> (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = lhs.value.i > long(rhs); break;
|
||||
case is_int: cmp = lhs.value.i > rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui > rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui > unsigned long(rhs); break;
|
||||
case is_bool: cmp = lhs.value.b > bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator< (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int: cmp = long(lhs) < long(rhs); break;
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = lhs.value.i < long(rhs); break;
|
||||
case is_int: cmp = lhs.value.i < rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui < rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui < unsigned long(rhs); break;
|
||||
case is_bool: cmp = bool(lhs) < bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator<= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!bool(lhs > rhs), lhs.valid && rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator>= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!bool(lhs < rhs), lhs.valid && rhs.valid);
|
||||
}
|
||||
|
||||
closure_value &
|
||||
operator<<= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.i <<= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = unsigned long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui <<= shift_by;
|
||||
|
||||
// Note: The usual arithmetic conversions are not performed on
|
||||
// bit shift operations.
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.ui <<= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = unsigned long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui <<= shift_by;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
closure_value &
|
||||
operator>>= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.i >>= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = unsigned long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui >>= shift_by;
|
||||
|
||||
// Note: The usual arithmetic conversions are not performed on
|
||||
// bit shift operations.
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
long shift_by = long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.ui >>= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
unsigned long shift_by = unsigned long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui >>= shift_by;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
valid = valid && rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator|| (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool result = bool(lhs) || bool(rhs);
|
||||
return closure_value(result, lhs.valid && rhs.valid);
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator&& (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool result = bool(lhs) && bool(rhs);
|
||||
return closure_value(result, lhs.valid && rhs.valid);
|
||||
}
|
||||
|
||||
// handle the ?: operator
|
||||
closure_value &
|
||||
handle_questionmark(closure_value const &cond, closure_value const &val2)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch (val2.type) {
|
||||
case is_bool: value.b = bool(cond) ? value.b : bool(val2); break;
|
||||
case is_int: value.i = bool(cond) ? value.i : long(val2); break;
|
||||
case is_uint:
|
||||
value.ui = bool(cond) ? value.ui : unsigned long(val2);
|
||||
type = is_uint; // changing type!
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: value.ui = bool(cond) ? value.ui : unsigned long(val2); break;
|
||||
case is_bool: value.b = bool(cond) ? value.b : bool(val2); break;
|
||||
}
|
||||
valid = bool(cond) ? valid : val2.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined (BOOST_SPIRIT_DEBUG)
|
||||
friend std::ostream&
|
||||
operator<< (std::ostream &o, closure_value const &val)
|
||||
{
|
||||
switch (val.type) {
|
||||
case is_int: o << "int(" << long(val) << ")"; break;
|
||||
case is_uint: o << "unsigned int(" << unsigned long(val) << ")"; break;
|
||||
case is_bool: o << "bool(" << bool(val) << ")"; break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
protected:
|
||||
long as_long() const
|
||||
{
|
||||
return boost::apply_visitor(long_visitor(), value);
|
||||
}
|
||||
unsigned long as_ulong() const
|
||||
{
|
||||
return boost::apply_visitor(ulong_visitor(), value);
|
||||
}
|
||||
bool as_bool() const
|
||||
{
|
||||
return boost::apply_visitor(bool_visitor(), value);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::variant<long, unsigned long, bool> value;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace closures
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
|
||||
738
include/boost/wave/grammars/cpp_grammar.hpp
Normal file
@@ -0,0 +1,738 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
|
||||
#define CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED
|
||||
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/tree/parse_tree.hpp>
|
||||
#include <boost/spirit/tree/parse_tree_utils.hpp>
|
||||
#include <boost/spirit/utility/confix.hpp>
|
||||
#include <boost/spirit/utility/lists.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
#include <map>
|
||||
#include <boost/spirit/tree/tree_to_xml.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/grammars/cpp_grammar_gen.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store_position
|
||||
//
|
||||
// The store_position functor extracts the actual file position from the
|
||||
// supplied token.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename PositionT>
|
||||
struct store_position {
|
||||
|
||||
store_position(PositionT &pos_) : pos(pos_) {}
|
||||
|
||||
template <typename TokenT>
|
||||
void operator()(TokenT const &token) const
|
||||
{
|
||||
pos = token.get_position();
|
||||
}
|
||||
|
||||
PositionT &pos;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store_found_eof
|
||||
//
|
||||
// The store_found_eof functor sets a given flag if the T_EOF token was
|
||||
// found during the parsing process
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct store_found_eof {
|
||||
|
||||
store_found_eof(bool &found_eof_) : found_eof(found_eof_) {}
|
||||
|
||||
template <typename TokenT>
|
||||
void operator()(TokenT const &token) const
|
||||
{
|
||||
found_eof = true;
|
||||
}
|
||||
|
||||
bool &found_eof;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store_found_directive
|
||||
//
|
||||
// The store_found_directive functor stores the token_id of the recognized
|
||||
// pp directive
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct store_found_directive {
|
||||
|
||||
store_found_directive(boost::wave::token_id &found_directive_)
|
||||
: found_directive(found_directive_) {}
|
||||
|
||||
template <typename TokenT>
|
||||
void operator()(TokenT const &token) const
|
||||
{
|
||||
found_directive = boost::wave::token_id(token);
|
||||
}
|
||||
|
||||
boost::wave::token_id &found_directive;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// flush_underlying_parser
|
||||
//
|
||||
// The flush_underlying_parser flushes the underlying
|
||||
// multi_pass_iterator during the normal parsing process. This is
|
||||
// used at certain points during the parsing process, when it is
|
||||
// clear, that no backtracking is needed anymore and the input
|
||||
// gathered so far may be discarded.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct flush_underlying_parser
|
||||
: public boost::spirit::parser<flush_underlying_parser>
|
||||
{
|
||||
typedef flush_underlying_parser this_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
typename boost::spirit::parser_result<this_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
scan.first.clear_queue();
|
||||
return scan.empty_match();
|
||||
}
|
||||
};
|
||||
|
||||
flush_underlying_parser const
|
||||
flush_underlying_parser_p = flush_underlying_parser();
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CPP_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Encapsulation of the C++ preprocessor grammar.
|
||||
template <typename PositionT>
|
||||
struct cpp_grammar :
|
||||
public boost::spirit::grammar<cpp_grammar<PositionT> >
|
||||
{
|
||||
typedef cpp_grammar<PositionT> grammar_t;
|
||||
typedef impl::store_position<PositionT> store_pos_t;
|
||||
typedef impl::store_found_eof store_found_eof_t;
|
||||
typedef impl::store_found_directive store_found_directive_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
// non-parse_tree generating rule type
|
||||
typedef typename ScannerT::iteration_policy_t iteration_policy_t;
|
||||
typedef boost::spirit::match_policy match_policy_t;
|
||||
typedef typename ScannerT::action_policy_t action_policy_t;
|
||||
typedef
|
||||
boost::spirit::scanner_policies<
|
||||
iteration_policy_t, match_policy_t, action_policy_t>
|
||||
policies_t;
|
||||
typedef
|
||||
boost::spirit::scanner<typename ScannerT::iterator_t, policies_t>
|
||||
non_tree_scanner_t;
|
||||
typedef boost::spirit::rule<non_tree_scanner_t> no_tree_rule_t;
|
||||
|
||||
// 'normal' (parse_tree generating) rule type
|
||||
typedef boost::spirit::rule<ScannerT> rule_t;
|
||||
|
||||
rule_t pp_statement;
|
||||
rule_t include_file, system_include_file, macro_include_file;
|
||||
rule_t plain_define, macro_definition, macro_parameters;
|
||||
rule_t undefine;
|
||||
rule_t ppifdef, ppifndef, ppif, ppelse, ppelif, ppendif;
|
||||
rule_t ppline;
|
||||
rule_t pperror;
|
||||
rule_t ppwarning;
|
||||
rule_t pppragma;
|
||||
rule_t illformed;
|
||||
rule_t ppqualifiedname;
|
||||
rule_t eol_tokens;
|
||||
no_tree_rule_t ppsp;
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
rule_t ppregion;
|
||||
rule_t ppendregion;
|
||||
#endif
|
||||
|
||||
definition(cpp_grammar const &self)
|
||||
{
|
||||
// import the spirit and cpplexer namespaces here
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::wave;
|
||||
using namespace boost::wave::util;
|
||||
|
||||
// save the rule id's for later use
|
||||
self.rule_ids.pp_statement_id = pp_statement.id().to_long();
|
||||
self.rule_ids.include_file_id = include_file.id().to_long();
|
||||
self.rule_ids.sysinclude_file_id = system_include_file.id().to_long();
|
||||
self.rule_ids.macroinclude_file_id = macro_include_file.id().to_long();
|
||||
self.rule_ids.plain_define_id = plain_define.id().to_long();
|
||||
self.rule_ids.macro_parameters_id = macro_parameters.id().to_long();
|
||||
self.rule_ids.macro_definition_id = macro_definition.id().to_long();
|
||||
self.rule_ids.undefine_id = undefine.id().to_long();
|
||||
self.rule_ids.ifdef_id = ppifdef.id().to_long();
|
||||
self.rule_ids.ifndef_id = ppifndef.id().to_long();
|
||||
self.rule_ids.if_id = ppif.id().to_long();
|
||||
self.rule_ids.elif_id = ppelif.id().to_long();
|
||||
self.rule_ids.else_id = ppelse.id().to_long();
|
||||
self.rule_ids.endif_id = ppendif.id().to_long();
|
||||
self.rule_ids.line_id = ppline.id().to_long();
|
||||
self.rule_ids.error_id = pperror.id().to_long();
|
||||
self.rule_ids.warning_id = ppwarning.id().to_long();
|
||||
self.rule_ids.pragma_id = pppragma.id().to_long();
|
||||
self.rule_ids.illformed_id = illformed.id().to_long();
|
||||
self.rule_ids.ppspace_id = ppsp.id().to_long();
|
||||
self.rule_ids.ppqualifiedname_id = ppqualifiedname.id().to_long();
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
self.rule_ids.region_id = ppregion.id().to_long();
|
||||
self.rule_ids.endregion_id = ppendregion.id().to_long();
|
||||
#endif
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
self.map_rule_id_to_name.init_rule_id_to_name_map(self);
|
||||
#endif
|
||||
|
||||
// recognizes preprocessor directives only
|
||||
|
||||
// C++ standard 16.1: A preprocessing directive consists of a sequence
|
||||
// of preprocessing tokens. The first token in the sequence is #
|
||||
// preprocessing token that is either the first character in the source
|
||||
// file (optionally after white space containing no new-line
|
||||
// characters) or that follows white space containing at least one
|
||||
// new-line character. The last token in the sequence is the first
|
||||
// new-line character that follows the first token in the sequence.
|
||||
|
||||
pp_statement
|
||||
= ( include_file
|
||||
| system_include_file
|
||||
| macro_include_file
|
||||
| plain_define
|
||||
| undefine
|
||||
| ppifdef
|
||||
| ppifndef
|
||||
| ppif
|
||||
| ppelse
|
||||
| ppelif
|
||||
| ppendif
|
||||
| ppline
|
||||
| pperror
|
||||
| ppwarning
|
||||
| pppragma
|
||||
| illformed
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
| ppregion
|
||||
| ppendregion
|
||||
#endif
|
||||
)
|
||||
>> eol_tokens
|
||||
// In parser debug mode it is useful not to flush the underlying stream
|
||||
// to allow its investigation in the debugger and to see the correct
|
||||
// output in the printed debug log..
|
||||
// Note: this may break the parser, though.
|
||||
#if !(defined(BOOST_SPIRIT_DEBUG) && \
|
||||
(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
|
||||
)
|
||||
>> impl::flush_underlying_parser_p
|
||||
#endif // !(defined(BOOST_SPIRIT_DEBUG) &&
|
||||
;
|
||||
|
||||
// #include ...
|
||||
include_file // include "..."
|
||||
= ch_p(T_PP_QHEADER)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
| ch_p(T_PP_QHEADER_NEXT)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
#endif
|
||||
;
|
||||
|
||||
system_include_file // include <...>
|
||||
= ch_p(T_PP_HHEADER)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
| ch_p(T_PP_HHEADER_NEXT)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
#endif
|
||||
;
|
||||
|
||||
macro_include_file // include ...anything else...
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_INCLUDE)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
| ch_p(T_PP_INCLUDE_NEXT)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
#endif
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #define FOO foo (with optional parameters)
|
||||
plain_define
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_DEFINE)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask) // and, bit_and etc.
|
||||
)
|
||||
>> ( ( no_node_d[eps_p(ch_p(T_LEFTPAREN))]
|
||||
>> macro_parameters
|
||||
>> !macro_definition
|
||||
)
|
||||
| !( no_node_d[+ppsp]
|
||||
>> macro_definition
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
// parameter list
|
||||
// normal C++ mode
|
||||
macro_parameters
|
||||
= confix_p(
|
||||
no_node_d[ch_p(T_LEFTPAREN) >> *ppsp],
|
||||
!list_p(
|
||||
( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
| ch_p(T_ELLIPSIS)
|
||||
#endif
|
||||
),
|
||||
no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp]
|
||||
),
|
||||
no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)]
|
||||
)
|
||||
;
|
||||
|
||||
// macro body (anything left until eol)
|
||||
macro_definition
|
||||
= no_node_d[*ppsp]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #undef FOO
|
||||
undefine
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_UNDEF)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
)
|
||||
;
|
||||
|
||||
// #ifdef et.al.
|
||||
ppifdef
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_IFDEF)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ppqualifiedname
|
||||
;
|
||||
|
||||
ppifndef
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_IFNDEF)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ppqualifiedname
|
||||
;
|
||||
|
||||
ppif
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_IF)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> +( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
ppelse
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_ELSE)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
]
|
||||
;
|
||||
|
||||
ppelif
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_ELIF)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> +( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
ppendif
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_ENDIF)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
]
|
||||
;
|
||||
|
||||
// #line ...
|
||||
ppline
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_LINE)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> +( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
// #region ...
|
||||
ppregion
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_MSEXT_PP_REGION)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ppqualifiedname
|
||||
;
|
||||
|
||||
// #endregion
|
||||
ppendregion
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_MSEXT_PP_ENDREGION)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
]
|
||||
;
|
||||
#endif
|
||||
|
||||
// # something else (ill formed preprocessor directive)
|
||||
illformed // for error reporting
|
||||
= no_node_d
|
||||
[
|
||||
pattern_p(T_POUND, MainTokenMask)
|
||||
>> *ppsp
|
||||
]
|
||||
>> ( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
>> no_node_d
|
||||
[
|
||||
*( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
]
|
||||
;
|
||||
|
||||
// #error
|
||||
pperror
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_ERROR)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #warning
|
||||
ppwarning
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_WARNING)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #pragma ...
|
||||
pppragma
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_PRAGMA)
|
||||
[ store_found_directive_t(self.found_directive) ]
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
ppqualifiedname
|
||||
= no_node_d[*ppsp]
|
||||
>> ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
)
|
||||
;
|
||||
|
||||
// auxiliary helper rules
|
||||
ppsp // valid space in a line with a preprocessor directive
|
||||
= ch_p(T_SPACE) | ch_p(T_CCOMMENT)
|
||||
;
|
||||
|
||||
// end of line tokens
|
||||
eol_tokens
|
||||
= no_node_d
|
||||
[
|
||||
*ppsp
|
||||
>> ( ch_p(T_NEWLINE)
|
||||
[ store_pos_t(self.pos_of_newline) ]
|
||||
| ch_p(T_CPPCOMMENT)
|
||||
[ store_pos_t(self.pos_of_newline) ]
|
||||
| ch_p(T_EOF)
|
||||
[ store_pos_t(self.pos_of_newline) ]
|
||||
[ store_found_eof_t(self.found_eof) ]
|
||||
)
|
||||
]
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR);
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppregion, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendregion, TRACE_CPP_GRAMMAR);
|
||||
#endif
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_t const& start() const
|
||||
{ return pp_statement; }
|
||||
};
|
||||
|
||||
cpp_grammar_rule_ids &rule_ids;
|
||||
PositionT &pos_of_newline;
|
||||
bool &found_eof;
|
||||
boost::wave::token_id &found_directive;
|
||||
|
||||
cpp_grammar(cpp_grammar_rule_ids &rule_ids_, PositionT &pos_of_newline_,
|
||||
bool &found_eof_, boost::wave::token_id &found_directive_)
|
||||
: rule_ids(rule_ids_), pos_of_newline(pos_of_newline_),
|
||||
found_eof(found_eof_), found_directive(found_directive_)
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar",
|
||||
TRACE_CPP_GRAMMAR);
|
||||
}
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
// helper function and data to get readable names of the rules known to us
|
||||
struct map_ruleid_to_name :
|
||||
public std::map<boost::spirit::parser_id, std::string>
|
||||
{
|
||||
typedef std::map<boost::spirit::parser_id, std::string> base_t;
|
||||
|
||||
void init_rule_id_to_name_map(cpp_grammar const &self)
|
||||
{
|
||||
struct {
|
||||
int parser_id;
|
||||
char const *rule_name;
|
||||
}
|
||||
init_ruleid_name_map[] = {
|
||||
{ self.rule_ids.pp_statement_id, "pp_statement" },
|
||||
{ self.rule_ids.include_file_id, "include_file" },
|
||||
{ self.rule_ids.sysinclude_file_id, "system_include_file" },
|
||||
{ self.rule_ids.macroinclude_file_id, "macro_include_file" },
|
||||
{ self.rule_ids.plain_define_id, "plain_define" },
|
||||
{ self.rule_ids.macro_parameters_id, "macro_parameters" },
|
||||
{ self.rule_ids.macro_definition_id, "macro_definition" },
|
||||
{ self.rule_ids.undefine_id, "undefine" },
|
||||
{ self.rule_ids.ifdef_id, "ppifdef" },
|
||||
{ self.rule_ids.ifndef_id, "ppifndef" },
|
||||
{ self.rule_ids.if_id, "ppif" },
|
||||
{ self.rule_ids.elif_id, "ppelif" },
|
||||
{ self.rule_ids.else_id, "ppelse" },
|
||||
{ self.rule_ids.endif_id, "ppendif" },
|
||||
{ self.rule_ids.line_id, "ppline" },
|
||||
{ self.rule_ids.error_id, "pperror" },
|
||||
{ self.rule_ids.warning_id, "ppwarning" },
|
||||
{ self.rule_ids.pragma_id, "pppragma" },
|
||||
{ self.rule_ids.illformed_id, "illformed" },
|
||||
{ self.rule_ids.ppsp_id, "ppsp" },
|
||||
{ self.rule_ids.ppqualifiedname_id, "ppqualifiedname" },
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
{ self.rule_ids.region_id, "ppregion" },
|
||||
{ self.rule_ids.endregion_id, "ppendregion" },
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
// initialize parser_id to rule_name map
|
||||
for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i)
|
||||
base_t::insert(base_t::value_type(
|
||||
boost::spirit::parser_id(init_ruleid_name_map[i].parser_id),
|
||||
std::string(init_ruleid_name_map[i].rule_name))
|
||||
);
|
||||
}
|
||||
};
|
||||
mutable map_ruleid_to_name map_rule_id_to_name;
|
||||
#endif // WAVE_DUMP_PARSE_TREE != 0
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_CPP_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following parse function is defined here, to allow the separation of
|
||||
// the compilation of the cpp_grammar from the function using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_GRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_GRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
char const *get_directivename(boost::wave::token_id id)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch (id) {
|
||||
case T_PP_QHEADER:
|
||||
case T_PP_HHEADER:
|
||||
case T_PP_INCLUDE: return "#include";
|
||||
case T_PP_DEFINE: return "#define";
|
||||
case T_PP_UNDEF: return "#undef";
|
||||
case T_PP_IFDEF: return "#ifdef";
|
||||
case T_PP_IFNDEF: return "#ifndef";
|
||||
case T_PP_IF: return "#if";
|
||||
case T_PP_ELSE: return "#else";
|
||||
case T_PP_ELIF: return "#elif";
|
||||
case T_PP_ENDIF: return "#endif";
|
||||
case T_PP_LINE: return "#line";
|
||||
case T_PP_ERROR: return "#error";
|
||||
case T_PP_WARNING: return "#warning";
|
||||
case T_PP_PRAGMA: return "#pragma";
|
||||
default:
|
||||
return "#unknown directive";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename LexIteratorT>
|
||||
BOOST_WAVE_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::tree_parse_info<LexIteratorT>
|
||||
cpp_grammar_gen<LexIteratorT>::parse_cpp_grammar (
|
||||
LexIteratorT const &first, LexIteratorT const &last,
|
||||
bool &found_eof_, position_type const &act_pos)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::wave;
|
||||
|
||||
pos_of_newline = position_type(); // reset position
|
||||
found_eof = false; // reset flag
|
||||
found_directive = T_EOF; // reset found directive
|
||||
|
||||
static cpp_grammar<position_type> g(
|
||||
rule_ids, pos_of_newline, found_eof, found_directive);
|
||||
|
||||
tree_parse_info<LexIteratorT> hit = pt_parse (first, last, g);
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
if (hit.match) {
|
||||
tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "",
|
||||
g.map_rule_id_to_name, &TokenT::get_token_id,
|
||||
&TokenT::get_token_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!hit.match && found_directive != T_EOF) {
|
||||
// recognized invalid directive
|
||||
std::string directive = get_directivename(found_directive);
|
||||
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_directive,
|
||||
directive, act_pos);
|
||||
}
|
||||
|
||||
found_eof_ = found_eof;
|
||||
return hit;
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_GRAMMAR_GEN_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
|
||||
117
include/boost/wave/grammars/cpp_grammar_gen.hpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED)
|
||||
#define CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED
|
||||
|
||||
#include <boost/spirit/tree/parse_tree.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store parser_id's of all rules of the cpp_grammar here for later access
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct cpp_grammar_rule_ids {
|
||||
std::size_t pp_statement_id;
|
||||
std::size_t include_file_id; // #include "..."
|
||||
std::size_t sysinclude_file_id; // #include <...>
|
||||
std::size_t macroinclude_file_id; // #include ...
|
||||
std::size_t plain_define_id; // #define
|
||||
std::size_t macro_parameters_id;
|
||||
std::size_t macro_definition_id;
|
||||
std::size_t undefine_id; // #undef
|
||||
std::size_t ifdef_id; // #ifdef
|
||||
std::size_t ifndef_id; // #ifndef
|
||||
std::size_t if_id; // #if
|
||||
std::size_t elif_id; // #elif
|
||||
std::size_t else_id; // #else
|
||||
std::size_t endif_id; // #endif
|
||||
std::size_t line_id; // #line
|
||||
std::size_t error_id; // #error
|
||||
std::size_t warning_id; // #warning
|
||||
std::size_t pragma_id; // #pragma
|
||||
std::size_t illformed_id;
|
||||
std::size_t ppspace_id;
|
||||
std::size_t ppqualifiedname_id;
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
std::size_t region_id; // #region
|
||||
std::size_t endregion_id; // #endregion
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// cpp_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the cpp_grammar
|
||||
// class from the compilation of the main pp_iterator. This is done to
|
||||
// safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename LexIteratorT>
|
||||
struct cpp_grammar_gen
|
||||
{
|
||||
typedef LexIteratorT iterator_type;
|
||||
typedef typename LexIteratorT::token_type token_type;
|
||||
typedef typename token_type::position_type position_type;
|
||||
|
||||
// the parser_id's of all rules of the cpp_grammar are stored here
|
||||
// note: these are valid only after the first call to parse_cpp_grammar
|
||||
static cpp_grammar_rule_ids rule_ids;
|
||||
|
||||
// the actual position of the last matched T_NEWLINE is stored here into the
|
||||
// member 'pos_of_newline'
|
||||
static position_type pos_of_newline;
|
||||
|
||||
// the found_eof flag is set to true during the parsing, if the directive
|
||||
// under inspection terminates with a T__EOF token
|
||||
static bool found_eof;
|
||||
|
||||
// the found_directive contains the token_id of the recognized pp directive
|
||||
static boost::wave::token_id found_directive;
|
||||
|
||||
// parse the cpp_grammar and return the resulting parse tree
|
||||
static boost::spirit::tree_parse_info<iterator_type>
|
||||
parse_cpp_grammar (iterator_type const &first, iterator_type const &last,
|
||||
bool &found_eof_, position_type const &act_pos);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// definitions of the static members
|
||||
template <typename LexIteratorT>
|
||||
cpp_grammar_rule_ids
|
||||
cpp_grammar_gen<LexIteratorT>::rule_ids;
|
||||
|
||||
template <typename LexIteratorT>
|
||||
typename LexIteratorT::token_type::position_type
|
||||
cpp_grammar_gen<LexIteratorT>::pos_of_newline;
|
||||
|
||||
template <typename LexIteratorT>
|
||||
bool cpp_grammar_gen<LexIteratorT>::found_eof = false;
|
||||
|
||||
template <typename LexIteratorT>
|
||||
boost::wave::token_id cpp_grammar_gen<LexIteratorT>::found_directive =
|
||||
boost::wave::T_EOF;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED)
|
||||
183
include/boost/wave/grammars/cpp_intlit_grammar.hpp
Normal file
@@ -0,0 +1,183 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)
|
||||
#define CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED
|
||||
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/attribute/closure.hpp>
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#include <boost/spirit/actor/assign_actor.hpp>
|
||||
#include <boost/spirit/actor/push_back_actor.hpp>
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
|
||||
#include <boost/spirit/phoenix/operators.hpp>
|
||||
#include <boost/spirit/phoenix/primitives.hpp>
|
||||
#include <boost/spirit/phoenix/statements.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
|
||||
|
||||
#if !defined(spirit_append_actor)
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
|
||||
#else
|
||||
#define spirit_append_actor(actor) boost::spirit::append(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
#endif // !defined(spirit_append_actor)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reusable grammar for parsing of C++ style integer literals
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
namespace closures {
|
||||
|
||||
struct intlit_closure
|
||||
: boost::spirit::closure<intlit_closure, unsigned long>
|
||||
{
|
||||
member1 val;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_INTLIT_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
struct intlit_grammar :
|
||||
boost::spirit::grammar<intlit_grammar, closures::intlit_closure::context_t>
|
||||
{
|
||||
intlit_grammar(bool &is_unsigned_) : is_unsigned(is_unsigned_)
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "intlit_grammar",
|
||||
TRACE_INTLIT_GRAMMAR);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
typedef boost::spirit::rule<ScannerT> rule_t;
|
||||
|
||||
rule_t int_lit;
|
||||
boost::spirit::subrule<0> sub_int_lit;
|
||||
boost::spirit::subrule<1> oct_lit;
|
||||
boost::spirit::subrule<2> hex_lit;
|
||||
boost::spirit::subrule<3> dec_lit;
|
||||
|
||||
definition(intlit_grammar const &self)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
using namespace phoenix;
|
||||
|
||||
int_lit = (
|
||||
sub_int_lit =
|
||||
( ch_p('0')[self.val = 0] >> (hex_lit | oct_lit)
|
||||
| dec_lit
|
||||
)
|
||||
>> !as_lower_d[
|
||||
(ch_p('u')[var(self.is_unsigned) = true] || ch_p('l'))
|
||||
| (ch_p('l') || ch_p('u')[var(self.is_unsigned) = true])
|
||||
]
|
||||
,
|
||||
|
||||
hex_lit =
|
||||
(ch_p('X') | ch_p('x'))
|
||||
>> uint_parser<unsigned long, 16>()
|
||||
[
|
||||
self.val = arg1,
|
||||
var(self.is_unsigned) = true
|
||||
]
|
||||
,
|
||||
|
||||
oct_lit =
|
||||
!uint_parser<unsigned long, 8>()
|
||||
[
|
||||
self.val = arg1,
|
||||
var(self.is_unsigned) = true
|
||||
]
|
||||
,
|
||||
|
||||
dec_lit =
|
||||
int_parser<long, 10>()
|
||||
[
|
||||
self.val = arg1
|
||||
]
|
||||
|
||||
)
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(int_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(sub_int_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(hex_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(oct_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(dec_lit, TRACE_INTLIT_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_t const& start() const
|
||||
{ return int_lit; }
|
||||
};
|
||||
|
||||
bool &is_unsigned;
|
||||
};
|
||||
|
||||
#undef TRACE_INTLIT_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following function is defined here, to allow the separation of
|
||||
// the compilation of the intlit_grammap from the function using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename TokenT>
|
||||
BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
|
||||
unsigned long
|
||||
intlit_grammar_gen<TokenT>::evaluate(TokenT const &token,
|
||||
bool &is_unsigned)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
|
||||
intlit_grammar g(is_unsigned);
|
||||
unsigned long result = 0;
|
||||
typename TokenT::string_type const &token_val = token.get_value();
|
||||
parse_info<typename TokenT::string_type::const_iterator> hit =
|
||||
parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
|
||||
|
||||
if (!hit.hit) {
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
||||
token_val, token.get_position());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)
|
||||
54
include/boost/wave/grammars/cpp_literal_grammar_gen.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED)
|
||||
#define CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// cpp_intlit_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the intlit_grammar
|
||||
// class from the compilation of the expression_grammar. This is done
|
||||
// to safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT>
|
||||
struct intlit_grammar_gen {
|
||||
|
||||
static unsigned long evaluate(TokenT const &tok, bool &is_unsigned);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// cpp_chlit_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the chlit_grammar
|
||||
// class from the compilation of the expression_grammar. This is done
|
||||
// to safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT>
|
||||
struct chlit_grammar_gen {
|
||||
|
||||
static unsigned int evaluate(TokenT const &tok);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED)
|
||||
73
include/boost/wave/grammars/cpp_predef_macros_gen.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*=============================================================================
|
||||
A Standard compliant C++ preprocessor
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED)
|
||||
#define CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED
|
||||
|
||||
#include <boost/spirit/tree/parse_tree.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store parser_id's of all rules of the predefined_macros_grammar here
|
||||
// for later access
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct predefined_macros_grammar_rule_ids {
|
||||
std::size_t plain_define_id; // #define
|
||||
std::size_t macro_parameters_id;
|
||||
std::size_t macro_definition_id;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// predefined_macros_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the
|
||||
// predefined_macros_grammar class from the compilation of the
|
||||
// main pp_iterator. This is done to safe compilation time.
|
||||
//
|
||||
// This class helps parsing command line given macro definitions in a
|
||||
// similar way, as macros are parsed by the cpp_grammar class.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename LexIteratorT>
|
||||
struct predefined_macros_grammar_gen
|
||||
{
|
||||
typedef LexIteratorT iterator_type;
|
||||
|
||||
// the parser_id's of all rules of the cpp_grammar are stored here
|
||||
// note: these are valid only after the first call to parse_cpp_grammar
|
||||
static predefined_macros_grammar_rule_ids rule_ids;
|
||||
|
||||
// parse the cpp_grammar and return the resulting parse tree
|
||||
static boost::spirit::tree_parse_info<iterator_type>
|
||||
parse_predefined_macro (iterator_type const &first, iterator_type const &last);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// definitions of the static members
|
||||
template <typename LexIteratorT>
|
||||
predefined_macros_grammar_rule_ids
|
||||
predefined_macros_grammar_gen<LexIteratorT>::rule_ids;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED)
|
||||
156
include/boost/wave/grammars/cpp_predef_macros_grammar.hpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
|
||||
#define CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED
|
||||
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/tree/parse_tree.hpp>
|
||||
#include <boost/spirit/utility/confix.hpp>
|
||||
#include <boost/spirit/utility/lists.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/grammars/cpp_predef_macros_gen.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_PREDEF_MACROS_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Encapsulation of the grammar for command line driven predefined macros.
|
||||
struct predefined_macros_grammar :
|
||||
public boost::spirit::grammar<predefined_macros_grammar>
|
||||
{
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
// 'normal' (parse_tree generating) rule type
|
||||
typedef boost::spirit::rule<ScannerT> rule_t;
|
||||
|
||||
rule_t plain_define, macro_definition, macro_parameters;
|
||||
|
||||
definition(predefined_macros_grammar const &self)
|
||||
{
|
||||
// import the spirit and cpplexer namespaces here
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::wave;
|
||||
using namespace boost::wave::util;
|
||||
|
||||
// save the rule id's for later use
|
||||
self.rule_ids.plain_define_id = plain_define.id().to_long();
|
||||
self.rule_ids.macro_parameters_id = macro_parameters.id().to_long();
|
||||
self.rule_ids.macro_definition_id = macro_definition.id().to_long();
|
||||
|
||||
// recognizes command line defined macro syntax, i.e.
|
||||
// -DMACRO
|
||||
// -DMACRO=
|
||||
// -DMACRO=value
|
||||
// -DMACRO(x)
|
||||
// -DMACRO(x)=
|
||||
// -DMACRO(x)=value
|
||||
|
||||
// This grammar resembles the overall structure of the cpp_grammar to
|
||||
// make it possible to reuse the parse tree traversal code
|
||||
plain_define
|
||||
= ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
)
|
||||
>> !macro_parameters
|
||||
>> !macro_definition
|
||||
;
|
||||
|
||||
// parameter list
|
||||
macro_parameters
|
||||
= confix_p(
|
||||
no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)],
|
||||
!list_p(
|
||||
( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
),
|
||||
no_node_d
|
||||
[
|
||||
*ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE)
|
||||
]
|
||||
),
|
||||
no_node_d[*ch_p(T_SPACE) >> ch_p(T_RIGHTPAREN)]
|
||||
)
|
||||
;
|
||||
|
||||
// macro body (anything left until eol)
|
||||
macro_definition
|
||||
= no_node_d[ch_p(T_ASSIGN)]
|
||||
>> *anychar_p
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_t const& start() const
|
||||
{ return plain_define; }
|
||||
};
|
||||
|
||||
predefined_macros_grammar_rule_ids &rule_ids;
|
||||
|
||||
predefined_macros_grammar(predefined_macros_grammar_rule_ids &rule_ids_)
|
||||
: rule_ids(rule_ids_)
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
|
||||
"predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_PREDEF_MACROS_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following parse function is defined here, to allow the separation of
|
||||
// the compilation of the cpp_predefined_macros_grammar from the function
|
||||
// using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename LexIteratorT>
|
||||
BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::tree_parse_info<LexIteratorT>
|
||||
predefined_macros_grammar_gen<LexIteratorT>::parse_predefined_macro (
|
||||
LexIteratorT const &first, LexIteratorT const &last)
|
||||
{
|
||||
static predefined_macros_grammar g(rule_ids);
|
||||
return boost::spirit::pt_parse (first, last, g);
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
|
||||
137
include/boost/wave/language_support.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
Definition of the various language support constants
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
#if !defined(LANGUAGE_SUPPORT_HPP_93EDD057_2DEF_44BC_BC9F_FDABB9F51AFA_INCLUDED)
|
||||
#define LANGUAGE_SUPPORT_HPP_93EDD057_2DEF_44BC_BC9F_FDABB9F51AFA_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
|
||||
enum language_support {
|
||||
// support flags for C++98
|
||||
support_normal = 0x01,
|
||||
support_cpp = support_normal,
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
// support flags for C99
|
||||
support_variadics = 0x02,
|
||||
support_c99 = support_variadics,
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// need_cpp
|
||||
//
|
||||
// Extract, if the language to support is C++98
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline bool
|
||||
need_cpp(language_support language)
|
||||
{
|
||||
return language == support_cpp;
|
||||
}
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// need_variadics
|
||||
//
|
||||
// Extract, if the language to support needs variadics support
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline bool
|
||||
need_variadics(language_support language)
|
||||
{
|
||||
return (language & support_variadics) ? true : false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// enable_variadics
|
||||
//
|
||||
// Set variadics support in the language to support
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline language_support
|
||||
enable_variadics(language_support language, bool enable = true)
|
||||
{
|
||||
if (enable)
|
||||
return static_cast<language_support>(language | support_variadics);
|
||||
return static_cast<language_support>(language & ~support_variadics);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// need_c99
|
||||
//
|
||||
// Extract, if the language to support is C99
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline bool
|
||||
need_c99(language_support language)
|
||||
{
|
||||
return language == support_c99;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// enable_c99
|
||||
//
|
||||
// Set, whether to support C99 (alternatively C++98 is supported)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline language_support
|
||||
enable_c99(bool enable = true)
|
||||
{
|
||||
return enable ? support_c99 : support_cpp;
|
||||
}
|
||||
|
||||
#else // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline bool
|
||||
need_variadics(language_support language)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline language_support
|
||||
enable_variadics(language_support language, bool enable = true)
|
||||
{
|
||||
return language;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
inline bool
|
||||
need_c99(language_support language)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline language_support
|
||||
enable_c99(bool enable = true)
|
||||
{
|
||||
return support_cpp;
|
||||
}
|
||||
|
||||
#endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(LANGUAGE_SUPPORT_HPP_93EDD057_2DEF_44BC_BC9F_FDABB9F51AFA_INCLUDED)
|
||||
210
include/boost/wave/preprocessing_hooks.hpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED)
|
||||
#define PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace context_policies {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The default_preprocessing_hooks class is a placeholder for all
|
||||
// preprocessing hooks called from inside the preprocessing engine
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct default_preprocessing_hooks {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'expanding_function_like_macro' is called, whenever a
|
||||
// function-like macro is to be expanded.
|
||||
//
|
||||
// The macroname parameter marks the position, where the macro to expand
|
||||
// is defined.
|
||||
// The formal_args parameter holds the formal arguments used during the
|
||||
// definition of the macro.
|
||||
// The definition parameter holds the macro definition for the macro to
|
||||
// trace.
|
||||
//
|
||||
// The macro call parameter marks the position, where this macro invoked.
|
||||
// The arguments parameter holds the macro arguments used during the
|
||||
// invocation of the macro
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT, typename ContainerT>
|
||||
void expanding_function_like_macro(
|
||||
TokenT const ¯odef, std::vector<TokenT> const &formal_args,
|
||||
ContainerT const &definition,
|
||||
TokenT const ¯ocall, std::vector<ContainerT> const &arguments)
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'expanding_object_like_macro' is called, whenever a
|
||||
// object-like macro is to be expanded .
|
||||
//
|
||||
// The macroname parameter marks the position, where the macro to expand
|
||||
// is defined.
|
||||
// The definition parameter holds the macro definition for the macro to
|
||||
// trace.
|
||||
//
|
||||
// The macro call parameter marks the position, where this macro invoked.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT, typename ContainerT>
|
||||
void expanding_object_like_macro(TokenT const ¯o,
|
||||
ContainerT const &definition, TokenT const ¯ocall)
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'expanded_macro' is called, whenever the expansion of a
|
||||
// macro is finished but before the rescanning process starts.
|
||||
//
|
||||
// The parameter 'result' contains the token sequence generated as the
|
||||
// result of the macro expansion.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
void expanded_macro(ContainerT const &result)
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'rescanned_macro' is called, whenever the rescanning of a
|
||||
// macro is finished.
|
||||
//
|
||||
// The parameter 'result' contains the token sequence generated as the
|
||||
// result of the rescanning.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
void rescanned_macro(ContainerT const &result)
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'opened_include_file' is called, whenever a file referred
|
||||
// by an #include directive was successfully located and opened.
|
||||
//
|
||||
// The parameter 'filename' contains the full file system path of the
|
||||
// opened file.
|
||||
//
|
||||
// The include_depth parameter contains the current include file depth.
|
||||
//
|
||||
// The is_system_include parameter denotes, if the given file was found
|
||||
// as a result of a #include <...> directive.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
opened_include_file(std::string const &filename, std::size_t include_depth,
|
||||
bool is_system_include)
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'returning_from_include_file' is called, whenever an
|
||||
// included file is about to be closed after it's processing is complete.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
returning_from_include_file()
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'interpret_pragma' is called, whenever a #pragma wave
|
||||
// directive is found, which isn't known to the core Wave library.
|
||||
//
|
||||
// The parameter 'ctx' is a reference to the context object used for
|
||||
// instantiating the preprocessing iterators by the user.
|
||||
//
|
||||
// The parameter 'pending' may be used to push tokens back into the input
|
||||
// stream, which are to be used as the replacement text for the whole
|
||||
// #pragma wave() directive.
|
||||
//
|
||||
// The parameter 'option' contains the name of the interpreted pragma.
|
||||
//
|
||||
// The parameter 'values' holds the values of the parameter provided to
|
||||
// the pragma operator.
|
||||
//
|
||||
// The parameter 'act_token' contains the actual #pragma token, which may
|
||||
// be used for error output.
|
||||
//
|
||||
// If the return value is 'false', the whole #pragma directive is
|
||||
// interpreted as unknown and a corresponding error message is issued. A
|
||||
// return value of 'true' signs a successful interpretation of the given
|
||||
// #pragma.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContextT, typename ContainerT>
|
||||
bool
|
||||
interpret_pragma(ContextT const &ctx, ContainerT &pending,
|
||||
typename ContextT::token_type const &option, ContainerT const &values,
|
||||
typename ContextT::token_type const &act_token)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'defined_macro' is called, whenever a macro was defined
|
||||
// successfully.
|
||||
//
|
||||
// The parameter 'name' is a reference to the token holding the macro name.
|
||||
//
|
||||
// The parameter 'is_functionlike' is set to true, whenever the newly
|
||||
// defined macro is defined as a function like macro.
|
||||
//
|
||||
// The parameter 'parameters' holds the parameter tokens for the macro
|
||||
// definition. If the macro has no parameters or if it is a object like
|
||||
// macro, then this container is empty.
|
||||
//
|
||||
// The parameter 'definition' contains the token sequence given as the
|
||||
// replacement sequence (definition part) of the newly defined macro.
|
||||
//
|
||||
// The parameter 'is_predefined' is set to true for all macros predefined
|
||||
// during the initialisation pahase of the library.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT, typename ParametersT, typename DefinitionT>
|
||||
void
|
||||
defined_macro(TokenT const ¯o_name, bool is_functionlike,
|
||||
ParametersT const ¶meters, DefinitionT const &definition,
|
||||
bool is_predefined)
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function 'undefined_macro' is called, whenever a macro definition
|
||||
// was removed successfully.
|
||||
//
|
||||
// The parameter 'name' holds the name of the macro, which definition was
|
||||
// removed.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename StringT>
|
||||
void
|
||||
undefined_macro(StringT const ¯o_name)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace context_policies
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED)
|
||||
673
include/boost/wave/token_ids.hpp
Normal file
@@ -0,0 +1,673 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
The definition of a default set of token identifiers and related
|
||||
functions.
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(TOKEN_IDS_HPP_414E9A58_F079_4789_8AFF_513815CE475B_INCLUDED)
|
||||
#define TOKEN_IDS_HPP_414E9A58_F079_4789_8AFF_513815CE475B_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allow external redefinition of the token identifiers to use
|
||||
#if !defined(BOOST_WAVE_TOKEN_IDS_DEFINED)
|
||||
#define BOOST_WAVE_TOKEN_IDS_DEFINED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assemble tokenid's
|
||||
#define TOKEN_FROM_ID(id, cat) ((id) | (cat))
|
||||
#define ID_FROM_TOKEN(tok) ((tok) & ~TokenTypeMask)
|
||||
#define BASEID_FROM_TOKEN(tok) ((tok) & ~ExtTokenTypeMask)
|
||||
#define CATEGORY_FROM_TOKEN(tok) ((tok) & TokenTypeMask)
|
||||
#define EXTCATEGORY_FROM_TOKEN(tok) ((tok) & ExtTokenTypeMask)
|
||||
#define IS_CATEGORY(tok, cat) \
|
||||
((CATEGORY_FROM_TOKEN(tok) == (cat)) ? true : false) \
|
||||
/**/
|
||||
#define IS_EXTCATEGORY(tok, cat) \
|
||||
((EXTCATEGORY_FROM_TOKEN(tok) == (cat)) ? true : false) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// the token_category helps to classify the different token types
|
||||
enum token_category {
|
||||
IdentifierTokenType = 0x10000000,
|
||||
ParameterTokenType = 0x11000000,
|
||||
ExtParameterTokenType = 0x11100000,
|
||||
KeywordTokenType = 0x20000000,
|
||||
OperatorTokenType = 0x30000000,
|
||||
LiteralTokenType = 0x40000000,
|
||||
IntegerLiteralTokenType = 0x41000000,
|
||||
FloatingLiteralTokenType = 0x42000000,
|
||||
StringLiteralTokenType = 0x43000000,
|
||||
CharacterLiteralTokenType = 0x44000000,
|
||||
BoolLiteralTokenType = 0x45000000,
|
||||
PPTokenType = 0x50000000,
|
||||
PPConditionalTokenType = 0x50100000,
|
||||
|
||||
UnknownTokenType = 0xA0000000,
|
||||
EOLTokenType = 0xB0000000,
|
||||
EOFTokenType = 0xC0000000,
|
||||
WhiteSpaceTokenType = 0xD0000000,
|
||||
InternalTokenType = 0xE0000000,
|
||||
|
||||
TokenTypeMask = 0xFF000000,
|
||||
AltTokenType = 0x00100000,
|
||||
TriGraphTokenType = 0x00200000,
|
||||
AltExtTokenType = 0x00500000, // and, bit_and etc.
|
||||
ExtTokenTypeMask = 0xFFF00000,
|
||||
TokenValueMask = 0x000FFFFF,
|
||||
MainTokenMask = TokenTypeMask|TokenValueMask,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// the token_id assigns unique numbers to the different C++ lexemes
|
||||
enum token_id {
|
||||
T_FIRST_TOKEN = 256,
|
||||
T_AND = TOKEN_FROM_ID(T_FIRST_TOKEN, OperatorTokenType),
|
||||
T_AND_ALT = TOKEN_FROM_ID(T_FIRST_TOKEN, OperatorTokenType|AltExtTokenType),
|
||||
T_ANDAND = TOKEN_FROM_ID(257, OperatorTokenType),
|
||||
T_ANDAND_ALT = TOKEN_FROM_ID(257, OperatorTokenType|AltExtTokenType),
|
||||
T_ASSIGN = TOKEN_FROM_ID(258, OperatorTokenType),
|
||||
T_ANDASSIGN = TOKEN_FROM_ID(259, OperatorTokenType),
|
||||
T_ANDASSIGN_ALT = TOKEN_FROM_ID(259, OperatorTokenType|AltExtTokenType),
|
||||
T_OR = TOKEN_FROM_ID(260, OperatorTokenType),
|
||||
T_OR_ALT = TOKEN_FROM_ID(260, OperatorTokenType|AltExtTokenType),
|
||||
T_OR_TRIGRAPH = TOKEN_FROM_ID(260, OperatorTokenType|TriGraphTokenType),
|
||||
T_ORASSIGN = TOKEN_FROM_ID(261, OperatorTokenType),
|
||||
T_ORASSIGN_ALT = TOKEN_FROM_ID(261, OperatorTokenType|AltExtTokenType),
|
||||
T_XOR = TOKEN_FROM_ID(262, OperatorTokenType),
|
||||
T_XOR_ALT = TOKEN_FROM_ID(262, OperatorTokenType|AltExtTokenType),
|
||||
T_XOR_TRIGRAPH = TOKEN_FROM_ID(262, OperatorTokenType|TriGraphTokenType),
|
||||
T_XORASSIGN = TOKEN_FROM_ID(263, OperatorTokenType),
|
||||
T_XORASSIGN_ALT = TOKEN_FROM_ID(263, OperatorTokenType|AltExtTokenType),
|
||||
T_COMMA = TOKEN_FROM_ID(264, OperatorTokenType),
|
||||
T_COLON = TOKEN_FROM_ID(265, OperatorTokenType),
|
||||
T_DIVIDE = TOKEN_FROM_ID(266, OperatorTokenType),
|
||||
T_DIVIDEASSIGN = TOKEN_FROM_ID(267, OperatorTokenType),
|
||||
T_DOT = TOKEN_FROM_ID(268, OperatorTokenType),
|
||||
T_DOTSTAR = TOKEN_FROM_ID(269, OperatorTokenType),
|
||||
T_ELLIPSIS = TOKEN_FROM_ID(270, OperatorTokenType),
|
||||
T_EQUAL = TOKEN_FROM_ID(271, OperatorTokenType),
|
||||
T_GREATER = TOKEN_FROM_ID(272, OperatorTokenType),
|
||||
T_GREATEREQUAL = TOKEN_FROM_ID(273, OperatorTokenType),
|
||||
T_LEFTBRACE = TOKEN_FROM_ID(274, OperatorTokenType),
|
||||
T_LEFTBRACE_ALT = TOKEN_FROM_ID(274, OperatorTokenType|AltTokenType),
|
||||
T_LEFTBRACE_TRIGRAPH = TOKEN_FROM_ID(274, OperatorTokenType|TriGraphTokenType),
|
||||
T_LESS = TOKEN_FROM_ID(275, OperatorTokenType),
|
||||
T_LESSEQUAL = TOKEN_FROM_ID(276, OperatorTokenType),
|
||||
T_LEFTPAREN = TOKEN_FROM_ID(277, OperatorTokenType),
|
||||
T_LEFTBRACKET = TOKEN_FROM_ID(278, OperatorTokenType),
|
||||
T_LEFTBRACKET_ALT = TOKEN_FROM_ID(278, OperatorTokenType|AltTokenType),
|
||||
T_LEFTBRACKET_TRIGRAPH = TOKEN_FROM_ID(278, OperatorTokenType|TriGraphTokenType),
|
||||
T_MINUS = TOKEN_FROM_ID(279, OperatorTokenType),
|
||||
T_MINUSASSIGN = TOKEN_FROM_ID(280, OperatorTokenType),
|
||||
T_MINUSMINUS = TOKEN_FROM_ID(281, OperatorTokenType),
|
||||
T_PERCENT = TOKEN_FROM_ID(282, OperatorTokenType),
|
||||
T_PERCENTASSIGN = TOKEN_FROM_ID(283, OperatorTokenType),
|
||||
T_NOT = TOKEN_FROM_ID(284, OperatorTokenType),
|
||||
T_NOT_ALT = TOKEN_FROM_ID(284, OperatorTokenType|AltExtTokenType),
|
||||
T_NOTEQUAL = TOKEN_FROM_ID(285, OperatorTokenType),
|
||||
T_NOTEQUAL_ALT = TOKEN_FROM_ID(285, OperatorTokenType|AltExtTokenType),
|
||||
T_OROR = TOKEN_FROM_ID(286, OperatorTokenType),
|
||||
T_OROR_ALT = TOKEN_FROM_ID(286, OperatorTokenType|AltExtTokenType),
|
||||
T_PLUS = TOKEN_FROM_ID(287, OperatorTokenType),
|
||||
T_PLUSASSIGN = TOKEN_FROM_ID(288, OperatorTokenType),
|
||||
T_PLUSPLUS = TOKEN_FROM_ID(289, OperatorTokenType),
|
||||
T_ARROW = TOKEN_FROM_ID(290, OperatorTokenType),
|
||||
T_ARROWSTAR = TOKEN_FROM_ID(291, OperatorTokenType),
|
||||
T_QUESTION_MARK = TOKEN_FROM_ID(292, OperatorTokenType),
|
||||
T_RIGHTBRACE = TOKEN_FROM_ID(293, OperatorTokenType),
|
||||
T_RIGHTBRACE_ALT = TOKEN_FROM_ID(293, OperatorTokenType|AltTokenType),
|
||||
T_RIGHTBRACE_TRIGRAPH = TOKEN_FROM_ID(293, OperatorTokenType|TriGraphTokenType),
|
||||
T_RIGHTPAREN = TOKEN_FROM_ID(294, OperatorTokenType),
|
||||
T_RIGHTBRACKET = TOKEN_FROM_ID(295, OperatorTokenType),
|
||||
T_RIGHTBRACKET_ALT = TOKEN_FROM_ID(295, OperatorTokenType|AltTokenType),
|
||||
T_RIGHTBRACKET_TRIGRAPH = TOKEN_FROM_ID(295, OperatorTokenType|TriGraphTokenType),
|
||||
T_COLON_COLON = TOKEN_FROM_ID(296, OperatorTokenType),
|
||||
T_SEMICOLON = TOKEN_FROM_ID(297, OperatorTokenType),
|
||||
T_SHIFTLEFT = TOKEN_FROM_ID(298, OperatorTokenType),
|
||||
T_SHIFTLEFTASSIGN = TOKEN_FROM_ID(299, OperatorTokenType),
|
||||
T_SHIFTRIGHT = TOKEN_FROM_ID(300, OperatorTokenType),
|
||||
T_SHIFTRIGHTASSIGN = TOKEN_FROM_ID(301, OperatorTokenType),
|
||||
T_STAR = TOKEN_FROM_ID(302, OperatorTokenType),
|
||||
T_COMPL = TOKEN_FROM_ID(303, OperatorTokenType),
|
||||
T_COMPL_ALT = TOKEN_FROM_ID(303, OperatorTokenType|AltExtTokenType),
|
||||
T_COMPL_TRIGRAPH = TOKEN_FROM_ID(303, OperatorTokenType|TriGraphTokenType),
|
||||
T_STARASSIGN = TOKEN_FROM_ID(304, OperatorTokenType),
|
||||
T_ASM = TOKEN_FROM_ID(305, KeywordTokenType),
|
||||
T_AUTO = TOKEN_FROM_ID(306, KeywordTokenType),
|
||||
T_BOOL = TOKEN_FROM_ID(307, KeywordTokenType),
|
||||
T_FALSE = TOKEN_FROM_ID(308, BoolLiteralTokenType),
|
||||
T_TRUE = TOKEN_FROM_ID(309, BoolLiteralTokenType),
|
||||
T_BREAK = TOKEN_FROM_ID(310, KeywordTokenType),
|
||||
T_CASE = TOKEN_FROM_ID(311, KeywordTokenType),
|
||||
T_CATCH = TOKEN_FROM_ID(312, KeywordTokenType),
|
||||
T_CHAR = TOKEN_FROM_ID(313, KeywordTokenType),
|
||||
T_CLASS = TOKEN_FROM_ID(314, KeywordTokenType),
|
||||
T_CONST = TOKEN_FROM_ID(315, KeywordTokenType),
|
||||
T_CONSTCAST = TOKEN_FROM_ID(316, KeywordTokenType),
|
||||
T_CONTINUE = TOKEN_FROM_ID(317, KeywordTokenType),
|
||||
T_DEFAULT = TOKEN_FROM_ID(318, KeywordTokenType),
|
||||
T_DEFINED = TOKEN_FROM_ID(319, KeywordTokenType),
|
||||
T_DELETE = TOKEN_FROM_ID(320, KeywordTokenType),
|
||||
T_DO = TOKEN_FROM_ID(321, KeywordTokenType),
|
||||
T_DOUBLE = TOKEN_FROM_ID(322, KeywordTokenType),
|
||||
T_DYNAMICCAST = TOKEN_FROM_ID(323, KeywordTokenType),
|
||||
T_ELSE = TOKEN_FROM_ID(324, KeywordTokenType),
|
||||
T_ENUM = TOKEN_FROM_ID(325, KeywordTokenType),
|
||||
T_EXPLICIT = TOKEN_FROM_ID(326, KeywordTokenType),
|
||||
T_EXPORT = TOKEN_FROM_ID(327, KeywordTokenType),
|
||||
T_EXTERN = TOKEN_FROM_ID(328, KeywordTokenType),
|
||||
T_FLOAT = TOKEN_FROM_ID(329, KeywordTokenType),
|
||||
T_FOR = TOKEN_FROM_ID(330, KeywordTokenType),
|
||||
T_FRIEND = TOKEN_FROM_ID(331, KeywordTokenType),
|
||||
T_GOTO = TOKEN_FROM_ID(332, KeywordTokenType),
|
||||
T_IF = TOKEN_FROM_ID(333, KeywordTokenType),
|
||||
T_INLINE = TOKEN_FROM_ID(334, KeywordTokenType),
|
||||
T_INT = TOKEN_FROM_ID(335, KeywordTokenType),
|
||||
T_LONG = TOKEN_FROM_ID(336, KeywordTokenType),
|
||||
T_MUTABLE = TOKEN_FROM_ID(337, KeywordTokenType),
|
||||
T_NAMESPACE = TOKEN_FROM_ID(338, KeywordTokenType),
|
||||
T_NEW = TOKEN_FROM_ID(339, KeywordTokenType),
|
||||
T_OPERATOR = TOKEN_FROM_ID(340, KeywordTokenType),
|
||||
T_PRIVATE = TOKEN_FROM_ID(341, KeywordTokenType),
|
||||
T_PROTECTED = TOKEN_FROM_ID(342, KeywordTokenType),
|
||||
T_PUBLIC = TOKEN_FROM_ID(343, KeywordTokenType),
|
||||
T_REGISTER = TOKEN_FROM_ID(344, KeywordTokenType),
|
||||
T_REINTERPRETCAST = TOKEN_FROM_ID(345, KeywordTokenType),
|
||||
T_RETURN = TOKEN_FROM_ID(346, KeywordTokenType),
|
||||
T_SHORT = TOKEN_FROM_ID(347, KeywordTokenType),
|
||||
T_SIGNED = TOKEN_FROM_ID(348, KeywordTokenType),
|
||||
T_SIZEOF = TOKEN_FROM_ID(349, KeywordTokenType),
|
||||
T_STATIC = TOKEN_FROM_ID(350, KeywordTokenType),
|
||||
T_STATICCAST = TOKEN_FROM_ID(351, KeywordTokenType),
|
||||
T_STRUCT = TOKEN_FROM_ID(352, KeywordTokenType),
|
||||
T_SWITCH = TOKEN_FROM_ID(353, KeywordTokenType),
|
||||
T_TEMPLATE = TOKEN_FROM_ID(354, KeywordTokenType),
|
||||
T_THIS = TOKEN_FROM_ID(355, KeywordTokenType),
|
||||
T_THROW = TOKEN_FROM_ID(356, KeywordTokenType),
|
||||
T_TRY = TOKEN_FROM_ID(357, KeywordTokenType),
|
||||
T_TYPEDEF = TOKEN_FROM_ID(358, KeywordTokenType),
|
||||
T_TYPEID = TOKEN_FROM_ID(359, KeywordTokenType),
|
||||
T_TYPENAME = TOKEN_FROM_ID(360, KeywordTokenType),
|
||||
T_UNION = TOKEN_FROM_ID(361, KeywordTokenType),
|
||||
T_UNSIGNED = TOKEN_FROM_ID(362, KeywordTokenType),
|
||||
T_USING = TOKEN_FROM_ID(363, KeywordTokenType),
|
||||
T_VIRTUAL = TOKEN_FROM_ID(364, KeywordTokenType),
|
||||
T_VOID = TOKEN_FROM_ID(365, KeywordTokenType),
|
||||
T_VOLATILE = TOKEN_FROM_ID(366, KeywordTokenType),
|
||||
T_WCHART = TOKEN_FROM_ID(367, KeywordTokenType),
|
||||
T_WHILE = TOKEN_FROM_ID(368, KeywordTokenType),
|
||||
T_PP_DEFINE = TOKEN_FROM_ID(369, PPTokenType),
|
||||
T_PP_IF = TOKEN_FROM_ID(370, PPConditionalTokenType),
|
||||
T_PP_IFDEF = TOKEN_FROM_ID(371, PPConditionalTokenType),
|
||||
T_PP_IFNDEF = TOKEN_FROM_ID(372, PPConditionalTokenType),
|
||||
T_PP_ELSE = TOKEN_FROM_ID(373, PPConditionalTokenType),
|
||||
T_PP_ELIF = TOKEN_FROM_ID(374, PPConditionalTokenType),
|
||||
T_PP_ENDIF = TOKEN_FROM_ID(375, PPConditionalTokenType),
|
||||
T_PP_ERROR = TOKEN_FROM_ID(376, PPTokenType),
|
||||
T_PP_LINE = TOKEN_FROM_ID(377, PPTokenType),
|
||||
T_PP_PRAGMA = TOKEN_FROM_ID(378, PPTokenType),
|
||||
T_PP_UNDEF = TOKEN_FROM_ID(379, PPTokenType),
|
||||
T_PP_WARNING = TOKEN_FROM_ID(380, PPTokenType),
|
||||
T_IDENTIFIER = TOKEN_FROM_ID(381, IdentifierTokenType),
|
||||
T_OCTALINT = TOKEN_FROM_ID(382, IntegerLiteralTokenType),
|
||||
T_DECIMALINT = TOKEN_FROM_ID(383, IntegerLiteralTokenType),
|
||||
T_HEXAINT = TOKEN_FROM_ID(384, IntegerLiteralTokenType),
|
||||
T_INTLIT = TOKEN_FROM_ID(385, IntegerLiteralTokenType),
|
||||
T_FLOATLIT = TOKEN_FROM_ID(386, FloatingLiteralTokenType),
|
||||
T_FIXEDPOINTLIT = TOKEN_FROM_ID(386, FloatingLiteralTokenType|AltTokenType), // IDL specific
|
||||
T_CCOMMENT = TOKEN_FROM_ID(387, WhiteSpaceTokenType),
|
||||
T_CPPCOMMENT = TOKEN_FROM_ID(388, WhiteSpaceTokenType),
|
||||
T_CHARLIT = TOKEN_FROM_ID(389, CharacterLiteralTokenType),
|
||||
T_STRINGLIT = TOKEN_FROM_ID(390, StringLiteralTokenType),
|
||||
T_CONTLINE = TOKEN_FROM_ID(391, EOLTokenType),
|
||||
T_SPACE = TOKEN_FROM_ID(392, WhiteSpaceTokenType),
|
||||
T_SPACE2 = TOKEN_FROM_ID(393, WhiteSpaceTokenType),
|
||||
T_NEWLINE = TOKEN_FROM_ID(394, EOLTokenType),
|
||||
T_POUND_POUND = TOKEN_FROM_ID(395, OperatorTokenType),
|
||||
T_POUND_POUND_ALT = TOKEN_FROM_ID(395, OperatorTokenType|AltTokenType),
|
||||
T_POUND_POUND_TRIGRAPH = TOKEN_FROM_ID(395, OperatorTokenType|TriGraphTokenType),
|
||||
T_POUND = TOKEN_FROM_ID(396, OperatorTokenType),
|
||||
T_POUND_ALT = TOKEN_FROM_ID(396, OperatorTokenType|AltTokenType),
|
||||
T_POUND_TRIGRAPH = TOKEN_FROM_ID(396, OperatorTokenType|TriGraphTokenType),
|
||||
T_ANY = TOKEN_FROM_ID(397, UnknownTokenType),
|
||||
T_PP_INCLUDE = TOKEN_FROM_ID(398, PPTokenType),
|
||||
T_PP_QHEADER = TOKEN_FROM_ID(399, PPTokenType),
|
||||
T_PP_HHEADER = TOKEN_FROM_ID(400, PPTokenType),
|
||||
T_PP_INCLUDE_NEXT = TOKEN_FROM_ID(398, PPTokenType|AltTokenType),
|
||||
T_PP_QHEADER_NEXT = TOKEN_FROM_ID(399, PPTokenType|AltTokenType),
|
||||
T_PP_HHEADER_NEXT = TOKEN_FROM_ID(400, PPTokenType|AltTokenType),
|
||||
T_EOF = TOKEN_FROM_ID(401, EOFTokenType), // end of file reached
|
||||
T_EOI = TOKEN_FROM_ID(402, EOFTokenType), // end of input reached
|
||||
|
||||
// MS extensions
|
||||
T_MSEXT_INT8 = TOKEN_FROM_ID(403, KeywordTokenType),
|
||||
T_MSEXT_INT16 = TOKEN_FROM_ID(404, KeywordTokenType),
|
||||
T_MSEXT_INT32 = TOKEN_FROM_ID(405, KeywordTokenType),
|
||||
T_MSEXT_INT64 = TOKEN_FROM_ID(406, KeywordTokenType),
|
||||
T_MSEXT_BASED = TOKEN_FROM_ID(407, KeywordTokenType),
|
||||
T_MSEXT_DECLSPEC = TOKEN_FROM_ID(408, KeywordTokenType),
|
||||
T_MSEXT_CDECL = TOKEN_FROM_ID(409, KeywordTokenType),
|
||||
T_MSEXT_FASTCALL = TOKEN_FROM_ID(410, KeywordTokenType),
|
||||
T_MSEXT_STDCALL = TOKEN_FROM_ID(411, KeywordTokenType),
|
||||
T_MSEXT_TRY = TOKEN_FROM_ID(412, KeywordTokenType),
|
||||
T_MSEXT_EXCEPT = TOKEN_FROM_ID(413, KeywordTokenType),
|
||||
T_MSEXT_FINALLY = TOKEN_FROM_ID(414, KeywordTokenType),
|
||||
T_MSEXT_LEAVE = TOKEN_FROM_ID(415, KeywordTokenType),
|
||||
T_MSEXT_INLINE = TOKEN_FROM_ID(416, KeywordTokenType),
|
||||
T_MSEXT_ASM = TOKEN_FROM_ID(417, KeywordTokenType),
|
||||
|
||||
T_MSEXT_PP_REGION = TOKEN_FROM_ID(418, PPTokenType),
|
||||
T_MSEXT_PP_ENDREGION = TOKEN_FROM_ID(419, PPTokenType),
|
||||
|
||||
T_LAST_TOKEN_ID,
|
||||
T_LAST_TOKEN = ID_FROM_TOKEN(T_LAST_TOKEN_ID),
|
||||
|
||||
// pseudo tokens to help streamlining macro replacement, these should not
|
||||
// returned from the lexer nor should these be returned from the pp-iterator
|
||||
T_NONREPLACABLE_IDENTIFIER = TOKEN_FROM_ID(T_LAST_TOKEN+1, IdentifierTokenType),
|
||||
T_PLACEHOLDER = TOKEN_FROM_ID(T_LAST_TOKEN+2, WhiteSpaceTokenType),
|
||||
T_PLACEMARKER = TOKEN_FROM_ID(T_LAST_TOKEN+3, InternalTokenType),
|
||||
T_PARAMETERBASE = TOKEN_FROM_ID(T_LAST_TOKEN+4, ParameterTokenType),
|
||||
T_EXTPARAMETERBASE = TOKEN_FROM_ID(T_LAST_TOKEN+5, ExtParameterTokenType),
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// redefine the TOKEN_FROM_ID macro to be more type safe
|
||||
#undef TOKEN_FROM_ID
|
||||
#define TOKEN_FROM_ID(id, cat) boost::wave::token_id((id) | (cat))
|
||||
#define BASE_TOKEN(tok) \
|
||||
boost::wave::token_id((tok) & MainTokenMask) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// return a token name
|
||||
inline BOOST_WAVE_STRINGTYPE
|
||||
get_token_name(token_id tokid)
|
||||
{
|
||||
// Table of token names
|
||||
//
|
||||
// Please note that the sequence of token names must match the sequence of
|
||||
// token id's defined in then enum token_id above.
|
||||
static char const *tok_names[] = {
|
||||
/* 256 */ "AND",
|
||||
/* 257 */ "ANDAND",
|
||||
/* 258 */ "ASSIGN",
|
||||
/* 259 */ "ANDASSIGN",
|
||||
/* 260 */ "OR",
|
||||
/* 261 */ "ORASSIGN",
|
||||
/* 262 */ "XOR",
|
||||
/* 263 */ "XORASSIGN",
|
||||
/* 264 */ "COMMA",
|
||||
/* 265 */ "COLON",
|
||||
/* 266 */ "DIVIDE",
|
||||
/* 267 */ "DIVIDEASSIGN",
|
||||
/* 268 */ "DOT",
|
||||
/* 269 */ "DOTSTAR",
|
||||
/* 270 */ "ELLIPSIS",
|
||||
/* 271 */ "EQUAL",
|
||||
/* 272 */ "GREATER",
|
||||
/* 273 */ "GREATEREQUAL",
|
||||
/* 274 */ "LEFTBRACE",
|
||||
/* 275 */ "LESS",
|
||||
/* 276 */ "LESSEQUAL",
|
||||
/* 277 */ "LEFTPAREN",
|
||||
/* 278 */ "LEFTBRACKET",
|
||||
/* 279 */ "MINUS",
|
||||
/* 280 */ "MINUSASSIGN",
|
||||
/* 281 */ "MINUSMINUS",
|
||||
/* 282 */ "PERCENT",
|
||||
/* 283 */ "PERCENTASSIGN",
|
||||
/* 284 */ "NOT",
|
||||
/* 285 */ "NOTEQUAL",
|
||||
/* 286 */ "OROR",
|
||||
/* 287 */ "PLUS",
|
||||
/* 288 */ "PLUSASSIGN",
|
||||
/* 289 */ "PLUSPLUS",
|
||||
/* 290 */ "ARROW",
|
||||
/* 291 */ "ARROWSTAR",
|
||||
/* 292 */ "QUESTION_MARK",
|
||||
/* 293 */ "RIGHTBRACE",
|
||||
/* 294 */ "RIGHTPAREN",
|
||||
/* 295 */ "RIGHTBRACKET",
|
||||
/* 296 */ "COLON_COLON",
|
||||
/* 297 */ "SEMICOLON",
|
||||
/* 298 */ "SHIFTLEFT",
|
||||
/* 299 */ "SHIFTLEFTASSIGN",
|
||||
/* 300 */ "SHIFTRIGHT",
|
||||
/* 301 */ "SHIFTRIGHTASSIGN",
|
||||
/* 302 */ "STAR",
|
||||
/* 303 */ "COMPL",
|
||||
/* 304 */ "STARASSIGN",
|
||||
/* 305 */ "ASM",
|
||||
/* 306 */ "AUTO",
|
||||
/* 307 */ "BOOL",
|
||||
/* 308 */ "FALSE",
|
||||
/* 309 */ "TRUE",
|
||||
/* 310 */ "BREAK",
|
||||
/* 311 */ "CASE",
|
||||
/* 312 */ "CATCH",
|
||||
/* 313 */ "CHAR",
|
||||
/* 314 */ "CLASS",
|
||||
/* 315 */ "CONST",
|
||||
/* 316 */ "CONSTCAST",
|
||||
/* 317 */ "CONTINUE",
|
||||
/* 318 */ "DEFAULT",
|
||||
/* 319 */ "DEFINED",
|
||||
/* 320 */ "DELETE",
|
||||
/* 321 */ "DO",
|
||||
/* 322 */ "DOUBLE",
|
||||
/* 323 */ "DYNAMICCAST",
|
||||
/* 324 */ "ELSE",
|
||||
/* 325 */ "ENUM",
|
||||
/* 326 */ "EXPLICIT",
|
||||
/* 327 */ "EXPORT",
|
||||
/* 328 */ "EXTERN",
|
||||
/* 329 */ "FLOAT",
|
||||
/* 330 */ "FOR",
|
||||
/* 331 */ "FRIEND",
|
||||
/* 332 */ "GOTO",
|
||||
/* 333 */ "IF",
|
||||
/* 334 */ "INLINE",
|
||||
/* 335 */ "INT",
|
||||
/* 336 */ "LONG",
|
||||
/* 337 */ "MUTABLE",
|
||||
/* 338 */ "NAMESPACE",
|
||||
/* 339 */ "NEW",
|
||||
/* 340 */ "OPERATOR",
|
||||
/* 341 */ "PRIVATE",
|
||||
/* 342 */ "PROTECTED",
|
||||
/* 343 */ "PUBLIC",
|
||||
/* 344 */ "REGISTER",
|
||||
/* 345 */ "REINTERPRETCAST",
|
||||
/* 346 */ "RETURN",
|
||||
/* 347 */ "SHORT",
|
||||
/* 348 */ "SIGNED",
|
||||
/* 349 */ "SIZEOF",
|
||||
/* 350 */ "STATIC",
|
||||
/* 351 */ "STATICCAST",
|
||||
/* 352 */ "STRUCT",
|
||||
/* 353 */ "SWITCH",
|
||||
/* 354 */ "TEMPLATE",
|
||||
/* 355 */ "THIS",
|
||||
/* 356 */ "THROW",
|
||||
/* 357 */ "TRY",
|
||||
/* 358 */ "TYPEDEF",
|
||||
/* 359 */ "TYPEID",
|
||||
/* 360 */ "TYPENAME",
|
||||
/* 361 */ "UNION",
|
||||
/* 362 */ "UNSIGNED",
|
||||
/* 363 */ "USING",
|
||||
/* 364 */ "VIRTUAL",
|
||||
/* 365 */ "VOID",
|
||||
/* 366 */ "VOLATILE",
|
||||
/* 367 */ "WCHART",
|
||||
/* 368 */ "WHILE",
|
||||
/* 369 */ "PP_DEFINE",
|
||||
/* 370 */ "PP_IF",
|
||||
/* 371 */ "PP_IFDEF",
|
||||
/* 372 */ "PP_IFNDEF",
|
||||
/* 373 */ "PP_ELSE",
|
||||
/* 374 */ "PP_ELIF",
|
||||
/* 375 */ "PP_ENDIF",
|
||||
/* 376 */ "PP_ERROR",
|
||||
/* 377 */ "PP_LINE",
|
||||
/* 378 */ "PP_PRAGMA",
|
||||
/* 379 */ "PP_UNDEF",
|
||||
/* 380 */ "PP_WARNING",
|
||||
/* 381 */ "IDENTIFIER",
|
||||
/* 382 */ "OCTALINT",
|
||||
/* 383 */ "DECIMALINT",
|
||||
/* 384 */ "HEXAINT",
|
||||
/* 385 */ "INTLIT",
|
||||
/* 386 */ "FLOATLIT",
|
||||
/* 387 */ "CCOMMENT",
|
||||
/* 388 */ "CPPCOMMENT",
|
||||
/* 389 */ "CHARLIT",
|
||||
/* 390 */ "STRINGLIT",
|
||||
/* 391 */ "CONTLINE",
|
||||
/* 392 */ "SPACE",
|
||||
/* 393 */ "SPACE2",
|
||||
/* 394 */ "NEWLINE",
|
||||
/* 395 */ "POUND_POUND",
|
||||
/* 396 */ "POUND",
|
||||
/* 397 */ "ANY",
|
||||
/* 398 */ "PP_INCLUDE",
|
||||
/* 399 */ "PP_QHEADER",
|
||||
/* 400 */ "PP_HHEADER",
|
||||
/* 401 */ "EOF",
|
||||
/* 402 */ "EOI",
|
||||
|
||||
// MS extensions
|
||||
/* 403 */ "MSEXT_INT8",
|
||||
/* 404 */ "MSEXT_INT16",
|
||||
/* 405 */ "MSEXT_INT32",
|
||||
/* 406 */ "MSEXT_INT64",
|
||||
/* 407 */ "MSEXT_BASED",
|
||||
/* 408 */ "MSEXT_DECLSPEC",
|
||||
/* 409 */ "MSEXT_CDECL",
|
||||
/* 410 */ "MSEXT_FASTCALL",
|
||||
/* 411 */ "MSEXT_STDCALL",
|
||||
/* 412 */ "MSEXT_TRY",
|
||||
/* 413 */ "MSEXT_EXCEPT",
|
||||
/* 414 */ "MSEXT_FINALLY",
|
||||
/* 415 */ "MSEXT_LEAVE",
|
||||
/* 416 */ "MSEXT_INLINE",
|
||||
/* 417 */ "MSEXT_ASM",
|
||||
/* 418 */ "MSEXT_REGION",
|
||||
/* 419 */ "MSEXT_ENDREGION",
|
||||
};
|
||||
|
||||
unsigned int id = BASEID_FROM_TOKEN(tokid)-T_FIRST_TOKEN;
|
||||
|
||||
BOOST_ASSERT(id < T_LAST_TOKEN-T_FIRST_TOKEN);
|
||||
return tok_names[id];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// return a token name
|
||||
inline char const *
|
||||
get_token_value(token_id tokid)
|
||||
{
|
||||
// Table of token values
|
||||
//
|
||||
// Please note that the sequence of token names must match the sequence of
|
||||
// token id's defined in then enum token_id above.
|
||||
static char const *tok_names[] = {
|
||||
/* 256 */ "&",
|
||||
/* 257 */ "&&",
|
||||
/* 258 */ "=",
|
||||
/* 259 */ "&=",
|
||||
/* 260 */ "|",
|
||||
/* 261 */ "|=",
|
||||
/* 262 */ "^",
|
||||
/* 263 */ "^=",
|
||||
/* 264 */ ",",
|
||||
/* 265 */ ":",
|
||||
/* 266 */ "/",
|
||||
/* 267 */ "/=",
|
||||
/* 268 */ ".",
|
||||
/* 269 */ ".*",
|
||||
/* 270 */ "...",
|
||||
/* 271 */ "==",
|
||||
/* 272 */ ">",
|
||||
/* 273 */ ">=",
|
||||
/* 274 */ "{",
|
||||
/* 275 */ "<",
|
||||
/* 276 */ "<=",
|
||||
/* 277 */ "(",
|
||||
/* 278 */ "[",
|
||||
/* 279 */ "-",
|
||||
/* 280 */ "-=",
|
||||
/* 281 */ "--",
|
||||
/* 282 */ "%",
|
||||
/* 283 */ "%=",
|
||||
/* 284 */ "!",
|
||||
/* 285 */ "!=",
|
||||
/* 286 */ "||",
|
||||
/* 287 */ "+",
|
||||
/* 288 */ "+=",
|
||||
/* 289 */ "++",
|
||||
/* 290 */ "->",
|
||||
/* 291 */ "->*",
|
||||
/* 292 */ "?",
|
||||
/* 293 */ "}",
|
||||
/* 294 */ ")",
|
||||
/* 295 */ "]",
|
||||
/* 296 */ "::",
|
||||
/* 297 */ ";",
|
||||
/* 298 */ "<<",
|
||||
/* 299 */ "<<=",
|
||||
/* 300 */ ">>",
|
||||
/* 301 */ ">>=",
|
||||
/* 302 */ "*",
|
||||
/* 303 */ "~",
|
||||
/* 304 */ "*=",
|
||||
/* 305 */ "asm",
|
||||
/* 306 */ "auto",
|
||||
/* 307 */ "bool",
|
||||
/* 308 */ "false",
|
||||
/* 309 */ "true",
|
||||
/* 310 */ "break",
|
||||
/* 311 */ "case",
|
||||
/* 312 */ "catch",
|
||||
/* 313 */ "char",
|
||||
/* 314 */ "class",
|
||||
/* 315 */ "const",
|
||||
/* 316 */ "const_cast",
|
||||
/* 317 */ "continue",
|
||||
/* 318 */ "default",
|
||||
/* 319 */ "defined",
|
||||
/* 320 */ "delete",
|
||||
/* 321 */ "do",
|
||||
/* 322 */ "double",
|
||||
/* 323 */ "dynamic_cast",
|
||||
/* 324 */ "else",
|
||||
/* 325 */ "enum",
|
||||
/* 326 */ "explicit",
|
||||
/* 327 */ "export",
|
||||
/* 328 */ "extern",
|
||||
/* 329 */ "float",
|
||||
/* 330 */ "for",
|
||||
/* 331 */ "friend",
|
||||
/* 332 */ "goto",
|
||||
/* 333 */ "if",
|
||||
/* 334 */ "inline",
|
||||
/* 335 */ "int",
|
||||
/* 336 */ "long",
|
||||
/* 337 */ "mutable",
|
||||
/* 338 */ "namespace",
|
||||
/* 339 */ "new",
|
||||
/* 340 */ "operator",
|
||||
/* 341 */ "private",
|
||||
/* 342 */ "protected",
|
||||
/* 343 */ "public",
|
||||
/* 344 */ "register",
|
||||
/* 345 */ "reinterpret_cast",
|
||||
/* 346 */ "return",
|
||||
/* 347 */ "short",
|
||||
/* 348 */ "signed",
|
||||
/* 349 */ "sizeof",
|
||||
/* 350 */ "static",
|
||||
/* 351 */ "static_cast",
|
||||
/* 352 */ "struct",
|
||||
/* 353 */ "switch",
|
||||
/* 354 */ "template",
|
||||
/* 355 */ "this",
|
||||
/* 356 */ "throw",
|
||||
/* 357 */ "try",
|
||||
/* 358 */ "typedef",
|
||||
/* 359 */ "typeid",
|
||||
/* 360 */ "typename",
|
||||
/* 361 */ "union",
|
||||
/* 362 */ "unsigned",
|
||||
/* 363 */ "using",
|
||||
/* 364 */ "virtual",
|
||||
/* 365 */ "void",
|
||||
/* 366 */ "volatile",
|
||||
/* 367 */ "wchar_t",
|
||||
/* 368 */ "while",
|
||||
/* 369 */ "#define",
|
||||
/* 370 */ "#if",
|
||||
/* 371 */ "#ifdef",
|
||||
/* 372 */ "#ifndef",
|
||||
/* 373 */ "#else",
|
||||
/* 374 */ "#elif",
|
||||
/* 375 */ "#endif",
|
||||
/* 376 */ "#error",
|
||||
/* 377 */ "#line",
|
||||
/* 378 */ "#pragma ",
|
||||
/* 379 */ "#undef ",
|
||||
/* 380 */ "#warning",
|
||||
/* 381 */ "", // identifier
|
||||
/* 382 */ "", // octalint
|
||||
/* 383 */ "", // decimalint
|
||||
/* 384 */ "", // hexlit
|
||||
/* 385 */ "", // intlit
|
||||
/* 386 */ "", // floatlit
|
||||
/* 387 */ "", // ccomment
|
||||
/* 388 */ "", // cppcomment
|
||||
/* 389 */ "", // charlit
|
||||
/* 390 */ "", // stringlit
|
||||
/* 391 */ "", // contline
|
||||
/* 392 */ "", // space
|
||||
/* 393 */ "", // space2
|
||||
/* 394 */ "\n",
|
||||
/* 395 */ "##",
|
||||
/* 396 */ "#",
|
||||
/* 397 */ "", // any
|
||||
/* 398 */ "#include",
|
||||
/* 399 */ "#include",
|
||||
/* 400 */ "#include",
|
||||
/* 401 */ "", // eof
|
||||
/* 402 */ "", // eoi
|
||||
|
||||
// MS extensions
|
||||
/* 403 */ "__int8",
|
||||
/* 404 */ "__int16",
|
||||
/* 405 */ "__int32",
|
||||
/* 406 */ "__int64",
|
||||
/* 407 */ "__based",
|
||||
/* 408 */ "__declspec",
|
||||
/* 409 */ "__cdecl",
|
||||
/* 410 */ "__fastcall",
|
||||
/* 411 */ "__stdcall",
|
||||
/* 412 */ "__try",
|
||||
/* 413 */ "__except",
|
||||
/* 414 */ "__finally",
|
||||
/* 415 */ "__leave",
|
||||
/* 416 */ "__inline",
|
||||
/* 417 */ "__asm",
|
||||
/* 418 */ "#region",
|
||||
/* 419 */ "#endregion",
|
||||
};
|
||||
|
||||
unsigned int id = BASEID_FROM_TOKEN(tokid)-T_FIRST_TOKEN;
|
||||
|
||||
BOOST_ASSERT(id < T_LAST_TOKEN-T_FIRST_TOKEN);
|
||||
return tok_names[id];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if !defined(BOOST_WAVE_TOKEN_IDS_DEFINED)
|
||||
|
||||
#endif // !defined(TOKEN_IDS_HPP_414E9A58_F079_4789_8AFF_513815CE475B_INCLUDED)
|
||||
|
||||
147
include/boost/wave/util/cpp_ifblock.hpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED)
|
||||
#define CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED
|
||||
|
||||
#include <stack>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// the class if_blocks handles recursive conditional compilation contexts
|
||||
class if_block
|
||||
{
|
||||
public:
|
||||
if_block() :
|
||||
status(true), some_part_status(true),
|
||||
enclosing_status(true), is_in_else(false)
|
||||
{
|
||||
}
|
||||
if_block(bool status_, bool enclosing_status_) :
|
||||
status(status_),
|
||||
some_part_status(status_),
|
||||
enclosing_status(enclosing_status_),
|
||||
is_in_else(false)
|
||||
{
|
||||
}
|
||||
|
||||
void set_status(bool status_)
|
||||
{
|
||||
status = status_;
|
||||
if (status_)
|
||||
some_part_status = true;
|
||||
}
|
||||
bool get_status() const { return status; }
|
||||
bool get_some_part_status() const { return some_part_status; }
|
||||
bool get_enclosing_status() const { return enclosing_status; }
|
||||
bool get_in_else() const { return is_in_else; }
|
||||
void set_in_else() { is_in_else = true; }
|
||||
|
||||
private:
|
||||
bool status; // Current block is true
|
||||
bool some_part_status; // One of the preceeding or current #if/#elif was true
|
||||
bool enclosing_status; // Enclosing #if block is true
|
||||
bool is_in_else; // Inside the #else part
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// stack of conditional compilation contexts
|
||||
class if_block_stack
|
||||
: private std::stack<if_block>
|
||||
{
|
||||
public:
|
||||
typedef std::stack<if_block>::size_type size_type;
|
||||
|
||||
void enter_if_block(bool new_status)
|
||||
{
|
||||
// If enclosing block is false, then this block is also false
|
||||
bool enclosing_status = get_status();
|
||||
this->push (value_type (new_status && enclosing_status, enclosing_status));
|
||||
}
|
||||
bool enter_elif_block(bool new_status)
|
||||
{
|
||||
if (!is_inside_ifpart())
|
||||
return false; // #elif without matching #if
|
||||
|
||||
if (get_enclosing_status()) {
|
||||
if (get_status()) {
|
||||
// entered a (false) #elif block from a true block
|
||||
this->top().set_status(false);
|
||||
}
|
||||
else if (new_status && !this->top().get_some_part_status()) {
|
||||
// Entered true #elif block and no previous block was true
|
||||
this->top().set_status(new_status);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool enter_else_block()
|
||||
{
|
||||
if (!is_inside_ifpart())
|
||||
return false; // #else without matching #if
|
||||
|
||||
if (get_enclosing_status()) {
|
||||
if (!this->top().get_some_part_status()) {
|
||||
// Entered (true) #else block and no previous block was true
|
||||
this->top().set_status(true);
|
||||
}
|
||||
else if (get_status()) {
|
||||
// Entered (false) #else block from true block
|
||||
this->top().set_status(false);
|
||||
}
|
||||
|
||||
// Set else flag
|
||||
this->top().set_in_else();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool exit_if_block()
|
||||
{
|
||||
if (0 == this->size())
|
||||
return false; // #endif without matching #if
|
||||
|
||||
this->pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
// return, wether the top (innermost) condition is true or false
|
||||
bool get_status() const
|
||||
{
|
||||
return 0 == this->size() || this->top().get_status();
|
||||
}
|
||||
|
||||
size_type get_if_block_depth() const { return this->size(); }
|
||||
|
||||
protected:
|
||||
bool get_enclosing_status() const
|
||||
{
|
||||
return 0 == this->size() || this->top().get_enclosing_status();
|
||||
}
|
||||
|
||||
bool is_inside_ifpart() const
|
||||
{
|
||||
return 0 != this->size() && !this->top().get_in_else();
|
||||
}
|
||||
bool is_inside_elsepart() const
|
||||
{
|
||||
return 0 != this->size() && this->top().get_in_else();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED)
|
||||
218
include/boost/wave/util/cpp_include_pathes.hpp
Normal file
@@ -0,0 +1,218 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_INCLUDE_PATHES_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)
|
||||
#define CPP_INCLUDE_PATHES_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// include_pathes - controlling the include path search order
|
||||
//
|
||||
// General notes:
|
||||
//
|
||||
// Any directories specified with the 'add_include_path()' function before
|
||||
// the function 'set_sys_include_delimiter()' is called are searched only
|
||||
// for the case of '#include "file"' directives, they are not searched for
|
||||
// '#include <file>' directives. If additional directories are specified
|
||||
// with the 'add_include_path()' function after a call to the function
|
||||
// 'set_sys_include_delimiter()', these directories are searched for all
|
||||
// '#include' directives.
|
||||
//
|
||||
// In addition, a call to the function 'set_sys_include_delimiter()'
|
||||
// inhibits the use of the current directory as the first search directory
|
||||
// for '#include "file"' directives. Therefore, the current directory is
|
||||
// searched only if it is requested explicitly with a call to the function
|
||||
// 'add_include_path(".")'.
|
||||
//
|
||||
// Calling both functions, the 'set_sys_include_delimiter()' and
|
||||
// 'add_include_path(".")' allows you to control precisely which
|
||||
// directories are searched before the current one and which are searched
|
||||
// after.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class include_pathes
|
||||
{
|
||||
typedef std::list<boost::filesystem::path> include_list_t;
|
||||
typedef std::set<std::string> pragma_once_set_t;
|
||||
|
||||
public:
|
||||
include_pathes()
|
||||
: was_sys_include_path(false),
|
||||
current_dir(boost::filesystem::initial_path())
|
||||
{}
|
||||
|
||||
bool add_include_path(char const *path_, bool is_system = false)
|
||||
{
|
||||
return add_include_path(path_, (is_system || was_sys_include_path) ?
|
||||
system_include_pathes : user_include_pathes);
|
||||
}
|
||||
void set_sys_include_delimiter() { was_sys_include_path = true; }
|
||||
bool find_include_file (std::string &s, bool is_system,
|
||||
char const *current_file) const;
|
||||
void set_current_directory(char const *path_);
|
||||
|
||||
void init_initial_path() { boost::filesystem::initial_path(); }
|
||||
|
||||
protected:
|
||||
bool find_include_file (std::string &s, include_list_t const &pathes,
|
||||
char const *) const;
|
||||
bool add_include_path(char const *path_, include_list_t &pathes_);
|
||||
|
||||
private:
|
||||
include_list_t user_include_pathes;
|
||||
include_list_t system_include_pathes;
|
||||
bool was_sys_include_path; // saw a set_sys_include_delimiter()
|
||||
boost::filesystem::path current_dir;
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
|
||||
public:
|
||||
bool has_pragma_once(std::string const &filename)
|
||||
{
|
||||
return pragma_once_files.find(filename) != pragma_once_files.end();
|
||||
}
|
||||
bool add_pragma_once_header(std::string const &filename)
|
||||
{
|
||||
return pragma_once_files.insert(filename).second;
|
||||
}
|
||||
|
||||
private:
|
||||
pragma_once_set_t pragma_once_files;
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Add an include path to one of the search lists (user include path or system
|
||||
// include path).
|
||||
inline
|
||||
bool include_pathes::add_include_path (
|
||||
char const *path_, include_list_t &pathes_)
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
if (path_) {
|
||||
fs::path newpath = fs::complete(fs::path(path_, fs::native), current_dir);
|
||||
|
||||
if (!fs::exists(newpath) || !fs::is_directory(newpath)) {
|
||||
// the given path does not form a name of a valid file system directory
|
||||
// item
|
||||
return false;
|
||||
}
|
||||
|
||||
pathes_.push_back (newpath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Find an include file by traversing the list of include directories
|
||||
inline
|
||||
bool include_pathes::find_include_file (std::string &s,
|
||||
include_list_t const &pathes, char const *current_file) const
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
typedef include_list_t::const_iterator const_include_list_iter_t;
|
||||
|
||||
const_include_list_iter_t include_pathes_end = pathes.end();
|
||||
for (const_include_list_iter_t it = pathes.begin();
|
||||
it != include_pathes_end; ++it)
|
||||
{
|
||||
fs::path currpath ((*it).string(), fs::native);
|
||||
currpath /= fs::path(s, fs::native); // append filename
|
||||
|
||||
if (fs::exists(currpath) &&
|
||||
( 0 == current_file ||
|
||||
strcmp(currpath.native_file_string().c_str(), current_file)
|
||||
)
|
||||
)
|
||||
{
|
||||
// found the required file
|
||||
s = currpath.string();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Find an include file by searching the user and system includes in the
|
||||
// correct sequence (as it was configured by the user of the driver program)
|
||||
inline bool
|
||||
include_pathes::find_include_file (std::string &s, bool is_system,
|
||||
char const *current_file) const
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
// if not system include (<...>), then search current directory first
|
||||
if (!is_system) {
|
||||
if (!was_sys_include_path) { // set_sys_include_delimiter() not called
|
||||
// first look in the current directory
|
||||
fs::path currpath (current_dir.string(), fs::native);
|
||||
currpath /= fs::path(s, fs::native);
|
||||
if (fs::exists(currpath) &&
|
||||
( 0 == current_file ||
|
||||
strcmp(currpath.native_file_string().c_str(), current_file)
|
||||
)
|
||||
)
|
||||
{
|
||||
s = currpath.string(); // found in local directory
|
||||
return true;
|
||||
}
|
||||
|
||||
// iterate all user include file directories to find the file
|
||||
return find_include_file(s, user_include_pathes, current_file);
|
||||
}
|
||||
|
||||
// iterate all user include file directories to find the file
|
||||
if (find_include_file(s, user_include_pathes, current_file))
|
||||
return true;
|
||||
|
||||
// if nothing found, fall through
|
||||
// ...
|
||||
}
|
||||
|
||||
// iterate all system include file directories to find the file
|
||||
return find_include_file (s, system_include_pathes, current_file);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Set current directory from a given file name
|
||||
|
||||
inline
|
||||
void include_pathes::set_current_directory(char const *path_)
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
fs::path filename = fs::complete(fs::path(path_, fs::native), current_dir);
|
||||
if (fs::exists(filename) && fs::is_directory(filename))
|
||||
current_dir = filename;
|
||||
else
|
||||
current_dir = filename.branch_path();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_INCLUDE_PATHES_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)
|
||||
1729
include/boost/wave/util/cpp_iterator.hpp
Normal file
1643
include/boost/wave/util/cpp_macromap.hpp
Normal file
252
include/boost/wave/util/cpp_macromap_predef.hpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Definition of the predefined macros
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_MACROMAP_PREDEF_HPP_HK041119)
|
||||
#define CPP_MACROMAP_PREDEF_HPP_HK041119
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file contains the definition of functions needed for the management
|
||||
// of static and dynamic predefined macros, such as __DATE__, __TIME__ etc.
|
||||
//
|
||||
// Note: __FILE__, __LINE__ and __INCLUDE_LEVEL__ are handled in the file
|
||||
// cpp_macromap.hpp.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
namespace predefined_macros {
|
||||
|
||||
// list of static predefined macros
|
||||
struct static_macros {
|
||||
char const *name;
|
||||
boost::wave::token_id token_id;
|
||||
char const *value;
|
||||
};
|
||||
|
||||
// C++ mode
|
||||
inline static_macros const &
|
||||
static_data_cpp(std::size_t i)
|
||||
{
|
||||
static static_macros data[] = {
|
||||
{ "__STDC__", T_INTLIT, "1" },
|
||||
{ "__cplusplus", T_INTLIT, "199711L" },
|
||||
{ 0, T_EOF, 0 }
|
||||
};
|
||||
BOOST_ASSERT(i < sizeof(data)/sizeof(data[0]));
|
||||
return data[i];
|
||||
}
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
// C99 mode
|
||||
inline static_macros const &
|
||||
static_data_c99(std::size_t i)
|
||||
{
|
||||
static static_macros data[] = {
|
||||
{ "__STDC__", T_INTLIT, "1" },
|
||||
{ "__STDC_VERSION__", T_INTLIT, "199901L" },
|
||||
{ "__STDC_HOSTED__", T_INTLIT, "0" },
|
||||
{ "__WAVE_HAS_VARIADICS__", T_INTLIT, "1" },
|
||||
{ 0, T_EOF, 0 }
|
||||
};
|
||||
BOOST_ASSERT(i < sizeof(data)/sizeof(data[0]));
|
||||
return data[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
// list of dynamic predefined macros
|
||||
typedef char const * (* get_dynamic_value)(bool);
|
||||
|
||||
// __DATE__
|
||||
inline
|
||||
char const *get_date(bool reset)
|
||||
{
|
||||
static std::string datestr;
|
||||
static const char *const monthnames[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
if (reset) {
|
||||
datestr.erase();
|
||||
}
|
||||
else {
|
||||
// for some systems sprintf, time_t etc. is in namespace std
|
||||
using namespace std;
|
||||
|
||||
time_t tt = time(0);
|
||||
struct tm *tb = 0;
|
||||
|
||||
if (tt != (time_t)-1) {
|
||||
char buffer[sizeof("\"Oct 11 1347\"")+1];
|
||||
|
||||
tb = localtime (&tt);
|
||||
sprintf (buffer, "\"%s %2d %4d\"",
|
||||
monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
|
||||
datestr = buffer;
|
||||
}
|
||||
else {
|
||||
datestr = "\"??? ?? ????\"";
|
||||
}
|
||||
}
|
||||
return datestr.c_str();
|
||||
}
|
||||
|
||||
// __TIME__
|
||||
inline
|
||||
char const *get_time(bool reset)
|
||||
{
|
||||
static std::string timestr;
|
||||
|
||||
if (reset) {
|
||||
timestr.erase();
|
||||
}
|
||||
else {
|
||||
// for some systems sprintf, time_t etc. is in namespace std
|
||||
using namespace std;
|
||||
|
||||
time_t tt = time(0);
|
||||
struct tm *tb = 0;
|
||||
|
||||
if (tt != (time_t)-1) {
|
||||
char buffer[sizeof("\"12:34:56\"")+1];
|
||||
|
||||
tb = localtime (&tt);
|
||||
sprintf (buffer, "\"%02d:%02d:%02d\"", tb->tm_hour,
|
||||
tb->tm_min, tb->tm_sec);
|
||||
timestr = buffer;
|
||||
}
|
||||
else {
|
||||
timestr = "\"??:??:??\"";
|
||||
}
|
||||
}
|
||||
return timestr.c_str();
|
||||
}
|
||||
|
||||
// __SPIRIT_PP__/__WAVE__
|
||||
inline
|
||||
char const *get_version(bool /*reset*/)
|
||||
{
|
||||
static std::string versionstr;
|
||||
char buffer[sizeof("0x0000")+1];
|
||||
|
||||
using namespace std; // for some systems sprintf is in namespace std
|
||||
sprintf(buffer, "0x%02d%1d%1d", BOOST_WAVE_VERSION_MAJOR,
|
||||
BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR);
|
||||
versionstr = buffer;
|
||||
return versionstr.c_str();
|
||||
}
|
||||
|
||||
// __SPIRIT_PP_VERSION__/__WAVE_VERSION__
|
||||
boost::wave::util::time_conversion_helper const
|
||||
compilation_time(__DATE__ " " __TIME__);
|
||||
|
||||
inline
|
||||
char const *get_fullversion(bool /*reset*/)
|
||||
{
|
||||
static std::string versionstr;
|
||||
char buffer[sizeof("0x00000000")+1];
|
||||
|
||||
// for some systems sprintf, time_t etc. is in namespace std
|
||||
using namespace std;
|
||||
|
||||
// calculate the number of days since Dec 13 2001
|
||||
// (the day the Wave project was started)
|
||||
tm first_day;
|
||||
|
||||
using namespace std; // for some systems memset is in namespace std
|
||||
memset (&first_day, 0, sizeof(tm));
|
||||
first_day.tm_mon = 11; // Dec
|
||||
first_day.tm_mday = 13; // 13
|
||||
first_day.tm_year = 101; // 2001
|
||||
|
||||
long seconds = long(difftime(compilation_time.get_time(),
|
||||
mktime(&first_day)));
|
||||
|
||||
sprintf(buffer, "0x%02d%1d%1d%04ld", BOOST_WAVE_VERSION_MAJOR,
|
||||
BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR,
|
||||
seconds/(3600*24));
|
||||
versionstr = buffer;
|
||||
return versionstr.c_str();
|
||||
}
|
||||
|
||||
// __SPIRIT_PP_VERSION_STR__/__WAVE_VERSION_STR__
|
||||
inline
|
||||
char const *get_versionstr(bool /*reset*/)
|
||||
{
|
||||
static std::string versionstr;
|
||||
char buffer[sizeof("\"00.00.00.0000\"")+1];
|
||||
|
||||
// for some systems sprintf, time_t etc. is in namespace std
|
||||
using namespace std;
|
||||
|
||||
// calculate the number of days since Dec 13 2001
|
||||
// (the day the Wave project was started)
|
||||
tm first_day;
|
||||
|
||||
using namespace std; // for some systems memset is in namespace std
|
||||
memset (&first_day, 0, sizeof(tm));
|
||||
first_day.tm_mon = 11; // Dec
|
||||
first_day.tm_mday = 13; // 13
|
||||
first_day.tm_year = 101; // 2001
|
||||
|
||||
long seconds = long(difftime(compilation_time.get_time(),
|
||||
mktime(&first_day)));
|
||||
|
||||
sprintf(buffer, "\"%d.%d.%d.%ld\"", BOOST_WAVE_VERSION_MAJOR,
|
||||
BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR,
|
||||
seconds/(3600*24));
|
||||
versionstr = buffer;
|
||||
return versionstr.c_str();
|
||||
}
|
||||
|
||||
struct dynamic_macros {
|
||||
char const *name;
|
||||
boost::wave::token_id token_id;
|
||||
get_dynamic_value generator;
|
||||
};
|
||||
|
||||
inline dynamic_macros const &
|
||||
dynamic_data(std::size_t i)
|
||||
{
|
||||
static dynamic_macros data[] = {
|
||||
{ "__DATE__", T_STRINGLIT, get_date },
|
||||
{ "__TIME__", T_STRINGLIT, get_time },
|
||||
{ "__SPIRIT_PP__", T_INTLIT, get_version },
|
||||
{ "__SPIRIT_PP_VERSION__", T_INTLIT, get_fullversion },
|
||||
{ "__SPIRIT_PP_VERSION_STR__", T_STRINGLIT, get_versionstr },
|
||||
{ "__WAVE__", T_INTLIT, get_version },
|
||||
{ "__WAVE_VERSION__", T_INTLIT, get_fullversion },
|
||||
{ "__WAVE_VERSION_STR__", T_STRINGLIT, get_versionstr },
|
||||
{ 0, T_EOF, 0 }
|
||||
};
|
||||
BOOST_ASSERT(i < sizeof(data)/sizeof(data[0]));
|
||||
return data[i];
|
||||
}
|
||||
|
||||
} // namespace predefined_macros
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_MACROMAP_PREDEF_HPP_HK041119)
|
||||
497
include/boost/wave/util/cpp_macromap_utils.hpp
Normal file
@@ -0,0 +1,497 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Token sequence analysis and transformation helper functions
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_MACROMAP_UTIL_HPP_HK041119)
|
||||
#define CPP_MACROMAP_UTIL_HPP_HK041119
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file contains the definition of several token sequence analyse
|
||||
// and transformation utility functions needed during macro handling.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace on_exit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On destruction pop the first element of the list given as the argument
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
class pop_front {
|
||||
public:
|
||||
pop_front(ContainerT &list_) : list(list_) {}
|
||||
~pop_front() { list.pop_front(); }
|
||||
|
||||
private:
|
||||
ContainerT &list;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Append a given list to the list given as argument
|
||||
// On destruction pop the first element of the list given as argument
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
class splice_pop_front {
|
||||
public:
|
||||
splice_pop_front(ContainerT &list_, ContainerT &queue)
|
||||
: list(list_)
|
||||
{
|
||||
list.splice(list.end(), queue);
|
||||
}
|
||||
~splice_pop_front() { list.pop_front(); }
|
||||
|
||||
private:
|
||||
ContainerT &list;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On destruction reset a referenced value to its initial state
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename TypeT>
|
||||
class reset {
|
||||
public:
|
||||
reset(TypeT &target_value_, TypeT new_value)
|
||||
: target_value(target_value_), old_value(target_value_)
|
||||
{
|
||||
target_value_ = new_value;
|
||||
}
|
||||
~reset() { target_value = old_value; }
|
||||
|
||||
private:
|
||||
TypeT &target_value;
|
||||
TypeT old_value;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On destruction assign the given iterator back
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename UnputIteratorT>
|
||||
class assign {
|
||||
public:
|
||||
assign(IteratorT &it_, UnputIteratorT const &uit_)
|
||||
: it(it_), uit(uit_) {}
|
||||
~assign() { it = uit.base(); }
|
||||
|
||||
private:
|
||||
IteratorT ⁢
|
||||
UnputIteratorT const &uit;
|
||||
};
|
||||
|
||||
template <typename IteratorT>
|
||||
class assign<IteratorT, IteratorT> {
|
||||
public:
|
||||
assign(IteratorT &it_, IteratorT const &uit_)
|
||||
: it(it_), uit(uit_) {}
|
||||
~assign() { it = uit; }
|
||||
|
||||
private:
|
||||
IteratorT ⁢
|
||||
IteratorT const &uit;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace on_exit
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test, whether a given identifier resolves to a predefined name
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename StringT>
|
||||
inline bool
|
||||
is_special_macroname (StringT const &name)
|
||||
{
|
||||
if (name.size() < 7)
|
||||
return false;
|
||||
|
||||
if ("defined" == name)
|
||||
return true;
|
||||
|
||||
if ('_' == name[0] && '_' == name[1]) {
|
||||
StringT str = name.substr(2);
|
||||
|
||||
if (str == "cplusplus" || str == "STDC__" ||
|
||||
str == "TIME__" || str == "DATE__" ||
|
||||
str == "LINE__" || str == "FILE__" ||
|
||||
str == "INCLUDE_LEVEL__")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test, whether two tokens are to be considered equal (different sequences
|
||||
// of whitespace are considered to be equal)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT>
|
||||
inline bool
|
||||
token_equals(TokenT const &left, TokenT const &right)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
if (T_PARAMETERBASE == token_id(left) ||
|
||||
T_EXTPARAMETERBASE == token_id(left))
|
||||
#else
|
||||
if (T_PARAMETERBASE == token_id(left))
|
||||
#endif
|
||||
{
|
||||
// if the existing token is of type T_PARAMETERBASE, then the right token
|
||||
// must be of type T_IDENTIFIER or a keyword
|
||||
return (T_IDENTIFIER == token_id(right) ||
|
||||
IS_CATEGORY(right, KeywordTokenType)) &&
|
||||
left.get_value() == right.get_value();
|
||||
}
|
||||
|
||||
// if the left token has whitespace, the value is irrelevant
|
||||
return token_id(left) == token_id(right) && (
|
||||
IS_CATEGORY(left, WhiteSpaceTokenType) ||
|
||||
left.get_value() == right.get_value()
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Tests, whether two macro definitions are equal
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline bool
|
||||
definition_equals(ContainerT const &definition,
|
||||
ContainerT const &new_definition)
|
||||
{
|
||||
typedef typename ContainerT::const_iterator const_iterator_type;
|
||||
|
||||
const_iterator_type first1 = definition.begin();
|
||||
const_iterator_type last1 = definition.end();
|
||||
const_iterator_type first2 = new_definition.begin();
|
||||
const_iterator_type last2 = new_definition.end();
|
||||
|
||||
while (first1 != last1 && token_equals(*first1, *first2)) {
|
||||
// skip whitespace, if both sequences have a whitespace next
|
||||
token_id id1 = next_token<const_iterator_type>::peek(first1, last1, false);
|
||||
token_id id2 = next_token<const_iterator_type>::peek(first2, last2, false);
|
||||
|
||||
if (IS_CATEGORY(id1, WhiteSpaceTokenType) &&
|
||||
IS_CATEGORY(id2, WhiteSpaceTokenType))
|
||||
{
|
||||
// all consecutive whitespace tokens count as one whitespace
|
||||
// adjust first1 and first2 accordingly
|
||||
skip_whitespace(first1, last1);
|
||||
skip_whitespace(first2, last2);
|
||||
}
|
||||
else if (!IS_CATEGORY(id1, WhiteSpaceTokenType) &&
|
||||
!IS_CATEGORY(id2, WhiteSpaceTokenType))
|
||||
{
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
else {
|
||||
// the sequences differ
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (first1 == last1 && first2 == last2) ? true : false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Tests, whether two given sets of macro parameters are equal
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline bool
|
||||
parameters_equal(ContainerT const ¶meters, ContainerT const &new_parameters)
|
||||
{
|
||||
if (parameters.size() != new_parameters.size())
|
||||
return false; // different parameter count
|
||||
|
||||
typedef typename ContainerT::const_iterator const_iterator_type;
|
||||
|
||||
const_iterator_type first1 = parameters.begin();
|
||||
const_iterator_type last1 = parameters.end();
|
||||
const_iterator_type first2 = new_parameters.begin();
|
||||
|
||||
while (first1 != last1) {
|
||||
// parameters are different, if the corresponding tokens are different
|
||||
using namespace boost::wave;
|
||||
if (token_id(*first1) != token_id(*first2) ||
|
||||
(*first1).get_value() != (*first2).get_value())
|
||||
{
|
||||
break;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
return (first1 == last1) ? true : false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Strip leading and trailing whitespace from the given token sequence
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline void
|
||||
trim_replacement_list (ContainerT &replacement_list)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
// strip leading whitespace
|
||||
if (replacement_list.size() > 0) {
|
||||
typename ContainerT::iterator end = replacement_list.end();
|
||||
typename ContainerT::iterator it = replacement_list.begin();
|
||||
|
||||
while (it != end && IS_CATEGORY(*it, WhiteSpaceTokenType)) {
|
||||
if (T_PLACEHOLDER != token_id(*it)) {
|
||||
typename ContainerT::iterator next = it;
|
||||
++next;
|
||||
replacement_list.erase(it);
|
||||
it = next;
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// strip trailing whitespace
|
||||
if (replacement_list.size() > 0) {
|
||||
typename ContainerT::reverse_iterator rend = replacement_list.rend();
|
||||
typename ContainerT::reverse_iterator rit = replacement_list.rbegin();
|
||||
|
||||
while (rit != rend && IS_CATEGORY(*rit, WhiteSpaceTokenType))
|
||||
++rit;
|
||||
|
||||
typename ContainerT::iterator end = replacement_list.end();
|
||||
typename ContainerT::iterator it = rit.base();
|
||||
|
||||
while (it != end && IS_CATEGORY(*it, WhiteSpaceTokenType)) {
|
||||
if (T_PLACEHOLDER != token_id(*it)) {
|
||||
typename ContainerT::iterator next = it;
|
||||
++next;
|
||||
replacement_list.erase(it);
|
||||
it = next;
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Remove all placeholder tokens from the given token sequence
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline void
|
||||
remove_placeholders (ContainerT &replacement_list)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
// strip leading whitespace
|
||||
if (replacement_list.size() > 0) {
|
||||
typename ContainerT::iterator end = replacement_list.end();
|
||||
typename ContainerT::iterator it = replacement_list.begin();
|
||||
|
||||
while (it != end) {
|
||||
if (T_PLACEHOLDER == token_id(*it)) {
|
||||
typename ContainerT::iterator next = it;
|
||||
++next;
|
||||
replacement_list.erase(it);
|
||||
it = next;
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// remove all 'new' leading and trailing whitespace
|
||||
trim_replacement_list(replacement_list);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Remove all whitespace tokens on the left side of the given token sequence
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline void
|
||||
trim_argument_left (ContainerT &argument)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
// strip leading whitespace (should be only one token)
|
||||
if (argument.size() > 0 &&
|
||||
IS_CATEGORY(argument.front(), WhiteSpaceTokenType))
|
||||
{
|
||||
argument.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Remove all whitespace tokens on the right side of the given token sequence
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline void
|
||||
trim_argument_right (ContainerT &argument)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
// strip trailing whitespace (should be only one token)
|
||||
if (argument.size() > 0 &&
|
||||
IS_CATEGORY(argument.back(), WhiteSpaceTokenType))
|
||||
{
|
||||
argument.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Remove all whitespace tokens on the keft and right sides of the given token
|
||||
// sequence
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline void
|
||||
trim_argument (ContainerT &argument)
|
||||
{
|
||||
trim_argument_left(argument);
|
||||
trim_argument_right(argument);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Tests, whether the given token sequence consists out of whitespace only
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContainerT>
|
||||
inline bool
|
||||
is_whitespace_only (ContainerT const &argument)
|
||||
{
|
||||
using namespace cpplexer;
|
||||
|
||||
typename ContainerT::const_iterator end = argument.end();
|
||||
for (typename ContainerT::const_iterator it = argument.begin();
|
||||
it != end; ++it)
|
||||
{
|
||||
if (!IS_CATEGORY(*it, WhiteSpaceTokenType))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Skip forward to a given token
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT>
|
||||
inline bool
|
||||
skip_to_token(IteratorT &it, IteratorT const &end, token_id id)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
if (token_id(*it) == id)
|
||||
return true;
|
||||
if (++it == end)
|
||||
return false;
|
||||
|
||||
while (IS_CATEGORY(*it, WhiteSpaceTokenType) ||
|
||||
T_NEWLINE == token_id(*it))
|
||||
{
|
||||
if (++it == end)
|
||||
return false;
|
||||
}
|
||||
return token_id(*it) == id;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get the full name of a given macro name (concatenate the string
|
||||
// representations of the single tokens).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT>
|
||||
inline std::string
|
||||
get_full_name(IteratorT const &begin, IteratorT const &end)
|
||||
{
|
||||
std::string full_name;
|
||||
for (IteratorT err_it = begin; err_it != end; ++err_it)
|
||||
full_name += (*err_it).get_value().c_str();
|
||||
|
||||
return full_name;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following predicate is used in conjunction with the remove_copy_if
|
||||
// algorithm to allow the detection of an eventually copied operator ##.
|
||||
// No removal is performed in any case.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class find_concat_operator {
|
||||
public:
|
||||
find_concat_operator(bool &found_) : found_concat(found_) {}
|
||||
|
||||
template <typename TokenT>
|
||||
bool operator()(TokenT const &tok)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
if (T_POUND_POUND == BASE_TOKEN(token_id(tok)))
|
||||
found_concat = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool &found_concat;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(CPP_MACROMAP_UTIL_HPP_HK041119)
|
||||
158
include/boost/wave/util/eat_whitespace.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
Whitespace eater
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2003 Paul Mensonides
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(EAT_WHITESPACE_HPP_4CE9AD17_F82D_4AB2_A117_555DF0DCC801_INCLUDED)
|
||||
#define EAT_WHITESPACE_HPP_4CE9AD17_F82D_4AB2_A117_555DF0DCC801_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
template <typename TokenT>
|
||||
class eat_whitespace {
|
||||
|
||||
public:
|
||||
eat_whitespace();
|
||||
|
||||
bool may_skip (TokenT &token, bool &skipped_newline);
|
||||
|
||||
private:
|
||||
typedef bool state_t(TokenT &token, bool &skipped_newline);
|
||||
state_t eat_whitespace::* state;
|
||||
state_t general, newline, newline_2nd, whitespace;
|
||||
};
|
||||
|
||||
template <typename TokenT>
|
||||
inline
|
||||
eat_whitespace<TokenT>::eat_whitespace()
|
||||
: state(&eat_whitespace::newline)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename TokenT>
|
||||
inline bool
|
||||
eat_whitespace<TokenT>::may_skip(TokenT &token, bool &skipped_newline)
|
||||
{
|
||||
return (this->*state)(token, skipped_newline);
|
||||
}
|
||||
|
||||
template <typename TokenT>
|
||||
inline bool
|
||||
eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline)
|
||||
{
|
||||
using boost::wave::token_id;
|
||||
|
||||
token_id id = token_id(token);
|
||||
if (T_NEWLINE == id || T_CPPCOMMENT == id) {
|
||||
state = &eat_whitespace::newline;
|
||||
}
|
||||
else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
|
||||
state = &eat_whitespace::whitespace;
|
||||
|
||||
if (T_CCOMMENT == id) {
|
||||
if (TokenT::string_type::npos !=
|
||||
token.get_value().find_first_of("\n"))
|
||||
{
|
||||
skipped_newline = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (token.get_value().size() > 1)
|
||||
token.set_value(" "); // replace with a single space
|
||||
}
|
||||
else {
|
||||
state = &eat_whitespace::general;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TokenT>
|
||||
inline bool
|
||||
eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
token_id id = token_id(token);
|
||||
if (T_NEWLINE == id || T_CPPCOMMENT == id) {
|
||||
skipped_newline = true;
|
||||
state = &eat_whitespace::newline_2nd;
|
||||
return true;
|
||||
}
|
||||
else if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id) {
|
||||
return general(token, skipped_newline);
|
||||
}
|
||||
|
||||
if (T_CCOMMENT == id) {
|
||||
if (TokenT::string_type::npos !=
|
||||
token.get_value().find_first_of("\n"))
|
||||
{
|
||||
skipped_newline = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TokenT>
|
||||
inline bool
|
||||
eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
token_id id = token_id(token);
|
||||
if (T_SPACE == id || T_SPACE2 == id)
|
||||
return true;
|
||||
if (T_CCOMMENT == id) {
|
||||
if (TokenT::string_type::npos !=
|
||||
token.get_value().find_first_of("\n"))
|
||||
{
|
||||
skipped_newline = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (T_NEWLINE != id && T_CPPCOMMENT != id)
|
||||
return general(token, skipped_newline);
|
||||
|
||||
skipped_newline = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TokenT>
|
||||
inline bool
|
||||
eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
token_id id = token_id(token);
|
||||
if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id)
|
||||
return general(token, skipped_newline);
|
||||
|
||||
if (T_CCOMMENT == id) {
|
||||
if (TokenT::string_type::npos !=
|
||||
token.get_value().find_first_of("\n"))
|
||||
{
|
||||
skipped_newline = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(EAT_WHITESPACE_HPP_4CE9AD17_F82D_4AB2_A117_555DF0DCC801_INCLUDED)
|
||||
|
||||
170
include/boost/wave/util/file_position.hpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Definition of the position_iterator and file_position templates
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)
|
||||
#define FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/spirit/version.hpp>
|
||||
#include <boost/spirit/iterator/position_iterator.hpp>
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// file_position
|
||||
//
|
||||
// A structure to hold positional information. This includes the filename,
|
||||
// line number and column number of a current token position.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename StringT>
|
||||
struct file_position {
|
||||
|
||||
public:
|
||||
typedef StringT string_type;
|
||||
|
||||
file_position()
|
||||
: file(), line(1), column(1)
|
||||
{}
|
||||
explicit file_position(string_type const& file_, int line_ = 1,
|
||||
int column_ = 1)
|
||||
: file(file_), line(line_), column(column_)
|
||||
{}
|
||||
|
||||
// accessors
|
||||
string_type const &get_file() const { return file; }
|
||||
int get_line() const { return line; }
|
||||
int get_column() const { return column; }
|
||||
|
||||
void set_file(string_type const &file_) { file = file_; }
|
||||
void set_line(int line_) { line = line_; }
|
||||
void set_column(int column_) { column = column_; }
|
||||
|
||||
private:
|
||||
string_type file;
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
|
||||
template <typename StringT>
|
||||
bool operator== (file_position<StringT> const &lhs,
|
||||
file_position<StringT> const &rhs)
|
||||
{
|
||||
return lhs.get_column() == rhs.get_column() &&
|
||||
lhs.get_line() == rhs.get_line() && lhs.get_file() == rhs.get_file();
|
||||
}
|
||||
|
||||
template <typename StringT>
|
||||
inline std::ostream &
|
||||
operator<< (std::ostream &o, file_position<StringT> const &pos)
|
||||
{
|
||||
o << pos.get_file() << "(" << pos.get_line() << ")";
|
||||
return o;
|
||||
}
|
||||
|
||||
typedef file_position<BOOST_WAVE_STRINGTYPE> file_position_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// position_iterator
|
||||
//
|
||||
// The position_iterator used by Wave is now based on the corresponding Spirit
|
||||
// type. This type is used with our own file_position though. The needed
|
||||
// specialization of the boost::spirit::position_policy class is provided
|
||||
// below.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
struct position_iterator
|
||||
: boost::spirit::position_iterator<IteratorT, PositionT>
|
||||
{
|
||||
typedef boost::spirit::position_iterator<IteratorT, PositionT> base_t;
|
||||
|
||||
position_iterator()
|
||||
{
|
||||
}
|
||||
|
||||
position_iterator(IteratorT const &begin, IteratorT const &end,
|
||||
PositionT const &pos)
|
||||
: base_t(begin, end, pos)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
|
||||
namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The boost::spirit::position_policy has to be specialized for our
|
||||
// file_position class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <>
|
||||
class position_policy<boost::wave::util::file_position_type> {
|
||||
|
||||
public:
|
||||
position_policy()
|
||||
: m_CharsPerTab(4)
|
||||
{}
|
||||
|
||||
void next_line(boost::wave::util::file_position_type &pos)
|
||||
{
|
||||
pos.set_line(pos.get_line() + 1);
|
||||
pos.set_column(1);
|
||||
}
|
||||
|
||||
void set_tab_chars(unsigned int chars)
|
||||
{
|
||||
m_CharsPerTab = chars;
|
||||
}
|
||||
|
||||
void next_char(boost::wave::util::file_position_type &pos)
|
||||
{
|
||||
pos.set_column(pos.get_column() + 1);
|
||||
}
|
||||
|
||||
void tabulation(boost::wave::util::file_position_type &pos)
|
||||
{
|
||||
pos.set_column(pos.get_column() + m_CharsPerTab -
|
||||
(pos.get_column() - 1) % m_CharsPerTab);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int m_CharsPerTab;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace spirit
|
||||
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)
|
||||
2327
include/boost/wave/util/flex_string.hpp
Normal file
133
include/boost/wave/util/functor_input.hpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)
|
||||
#define FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED
|
||||
|
||||
#include <boost/spirit/iterator/multi_pass.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// class functor_input
|
||||
//
|
||||
// Implementation of the InputPolicy used by multi_pass
|
||||
// functor_input gets tokens from a functor
|
||||
// Note: the functor must have a typedef for result_type
|
||||
// It also must have a static variable of type result_type defined
|
||||
// to represent eof that is called eof.
|
||||
//
|
||||
// This functor input policy template is essentially the same as the
|
||||
// predefined multi_pass functor_input policy. The difference is,
|
||||
// that the first token is not read at initialization time, but only
|
||||
// just before returning the first token.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct functor_input {
|
||||
|
||||
template <typename FunctorT>
|
||||
class inner {
|
||||
|
||||
typedef typename FunctorT::result_type result_type;
|
||||
|
||||
struct Data {
|
||||
Data(FunctorT const &ftor_)
|
||||
: ftor(ftor_), was_initialized(false)
|
||||
{}
|
||||
|
||||
FunctorT ftor;
|
||||
result_type curtok;
|
||||
bool was_initialized;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef result_type value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef result_type *pointer;
|
||||
typedef result_type &reference;
|
||||
|
||||
protected:
|
||||
inner()
|
||||
: data(0)
|
||||
{}
|
||||
|
||||
inner(FunctorT const &x)
|
||||
: data(new Data(x))
|
||||
{}
|
||||
|
||||
inner(inner const &x)
|
||||
: data(x.data)
|
||||
{}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
delete data;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
bool same_input(inner const &x) const
|
||||
{
|
||||
return data == x.data;
|
||||
}
|
||||
|
||||
void swap(inner &x)
|
||||
{
|
||||
boost::spirit::impl::mp_swap(data, x.data);
|
||||
}
|
||||
|
||||
void ensure_initialized() const
|
||||
{
|
||||
if (data && !data->was_initialized) {
|
||||
data->curtok = (data->ftor)(); // get the first token
|
||||
data->was_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
reference get_input() const
|
||||
{
|
||||
ensure_initialized();
|
||||
return data->curtok;
|
||||
}
|
||||
|
||||
void advance_input()
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(0 != data);
|
||||
data->curtok = (data->ftor)();
|
||||
data->was_initialized = true;
|
||||
}
|
||||
|
||||
bool input_at_eof() const
|
||||
{
|
||||
ensure_initialized();
|
||||
return !data || data->curtok == data->ftor.eof;
|
||||
}
|
||||
|
||||
FunctorT& get_functor() const
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(0 != data);
|
||||
return data->ftor;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable Data *data;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)
|
||||
330
include/boost/wave/util/insert_whitespace_detection.hpp
Normal file
@@ -0,0 +1,330 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Detect the need to insert a whitespace token into the output stream
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
#if !defined(INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)
|
||||
#define INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
namespace impl {
|
||||
|
||||
// T_IDENTIFIER
|
||||
template <typename StringT>
|
||||
inline bool
|
||||
would_form_universal_char (StringT const &value)
|
||||
{
|
||||
if ('u' != value[0] && 'U' != value[0])
|
||||
return false;
|
||||
if ('u' == value[0] && value.size() < 5)
|
||||
return false;
|
||||
if ('U' == value[0] && value.size() < 9)
|
||||
return false;
|
||||
|
||||
typename StringT::size_type pos =
|
||||
value.find_first_not_of("0123456789abcdefABCDEF", 1);
|
||||
|
||||
if (StringT::npos == pos ||
|
||||
('u' == value[0] && pos > 5) ||
|
||||
('U' == value[0] && pos > 9))
|
||||
{
|
||||
return true; // would form an universal char
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template <typename StringT>
|
||||
inline bool
|
||||
handle_identifier(boost::wave::token_id prev,
|
||||
boost::wave::token_id before, StringT const &value)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch (static_cast<unsigned int>(prev)) {
|
||||
case T_IDENTIFIER:
|
||||
case T_NONREPLACABLE_IDENTIFIER:
|
||||
case T_INTLIT:
|
||||
case T_FLOATLIT:
|
||||
case T_COMPL_ALT:
|
||||
case T_OR_ALT:
|
||||
case T_AND_ALT:
|
||||
case T_NOT_ALT:
|
||||
case T_XOR_ALT:
|
||||
case T_ANDASSIGN_ALT:
|
||||
case T_ORASSIGN_ALT:
|
||||
case T_XORASSIGN_ALT:
|
||||
case T_NOTEQUAL_ALT:
|
||||
case T_FIXEDPOINTLIT:
|
||||
return true;
|
||||
|
||||
// avoid constructing universal characters (\u1234)
|
||||
case TOKEN_FROM_ID('\\', UnknownTokenType):
|
||||
return would_form_universal_char(value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// T_INTLIT
|
||||
inline bool
|
||||
handle_intlit(boost::wave::token_id prev, boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(prev) {
|
||||
case T_IDENTIFIER:
|
||||
case T_NONREPLACABLE_IDENTIFIER:
|
||||
case T_INTLIT:
|
||||
case T_FLOATLIT:
|
||||
case T_FIXEDPOINTLIT:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// T_FLOATLIT
|
||||
inline bool
|
||||
handle_floatlit(boost::wave::token_id prev,
|
||||
boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(prev) {
|
||||
case T_IDENTIFIER:
|
||||
case T_NONREPLACABLE_IDENTIFIER:
|
||||
case T_INTLIT:
|
||||
case T_FLOATLIT:
|
||||
case T_FIXEDPOINTLIT:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// <% T_LEFTBRACE
|
||||
inline bool
|
||||
handle_alt_leftbrace(boost::wave::token_id prev,
|
||||
boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(prev) {
|
||||
case T_LESS: // <<%
|
||||
case T_SHIFTLEFT: // <<<%
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// <: T_LEFTBRACKET
|
||||
inline bool
|
||||
handle_alt_leftbracket(boost::wave::token_id prev,
|
||||
boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(prev) {
|
||||
case T_LESS: // <<:
|
||||
case T_SHIFTLEFT: // <<<:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// T_FIXEDPOINTLIT
|
||||
inline bool
|
||||
handle_fixedpointlit(boost::wave::token_id prev,
|
||||
boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(prev) {
|
||||
case T_IDENTIFIER:
|
||||
case T_NONREPLACABLE_IDENTIFIER:
|
||||
case T_INTLIT:
|
||||
case T_FLOATLIT:
|
||||
case T_FIXEDPOINTLIT:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// T_DOT
|
||||
inline bool
|
||||
handle_dot(boost::wave::token_id prev, boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(prev) {
|
||||
case T_DOT:
|
||||
if (T_DOT == before)
|
||||
return true; // ...
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// T_QUESTION_MARK
|
||||
inline bool
|
||||
handle_questionmark(boost::wave::token_id prev,
|
||||
boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(static_cast<unsigned int>(prev)) {
|
||||
case TOKEN_FROM_ID('\\', UnknownTokenType): // \?
|
||||
case T_QUESTION_MARK: // ??
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// T_NEWLINE
|
||||
inline bool
|
||||
handle_newline(boost::wave::token_id prev,
|
||||
boost::wave::token_id before)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch(static_cast<unsigned int>(prev)) {
|
||||
case TOKEN_FROM_ID('\\', UnknownTokenType): // \ \n
|
||||
case T_DIVIDE:
|
||||
if (T_QUESTION_MARK == before)
|
||||
return true; // ?/\n // may be \\n
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
|
||||
class insert_whitespace_detection
|
||||
{
|
||||
public:
|
||||
insert_whitespace_detection()
|
||||
: prev(boost::wave::T_EOF), beforeprev(boost::wave::T_EOF)
|
||||
{}
|
||||
|
||||
template <typename StringT>
|
||||
bool must_insert(boost::wave::token_id current, StringT const &value)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
switch (current) {
|
||||
case T_NONREPLACABLE_IDENTIFIER:
|
||||
case T_IDENTIFIER:
|
||||
return impl::handle_identifier(prev, beforeprev, value);
|
||||
case T_INTLIT:
|
||||
return impl::handle_intlit(prev, beforeprev);
|
||||
case T_FLOATLIT:
|
||||
return impl::handle_floatlit(prev, beforeprev);
|
||||
case T_STRINGLIT:
|
||||
if (TOKEN_FROM_ID('L', UnknownTokenType) == prev) // 'L'
|
||||
return true;
|
||||
break;
|
||||
case T_LEFTBRACE_ALT:
|
||||
return impl::handle_alt_leftbrace(prev, beforeprev);
|
||||
case T_LEFTBRACKET_ALT:
|
||||
return impl::handle_alt_leftbracket(prev, beforeprev);
|
||||
case T_FIXEDPOINTLIT:
|
||||
return impl::handle_fixedpointlit(prev, beforeprev);
|
||||
case T_DOT:
|
||||
return impl::handle_dot(prev, beforeprev);
|
||||
case T_QUESTION_MARK:
|
||||
return impl::handle_questionmark(prev, beforeprev);
|
||||
case T_NEWLINE:
|
||||
return impl::handle_newline(prev, beforeprev);
|
||||
|
||||
case T_LEFTPAREN:
|
||||
case T_RIGHTPAREN:
|
||||
case T_LEFTBRACKET:
|
||||
case T_RIGHTBRACKET:
|
||||
case T_SEMICOLON:
|
||||
case T_COMMA:
|
||||
case T_COLON:
|
||||
switch (prev) {
|
||||
case T_LEFTPAREN:
|
||||
case T_RIGHTPAREN:
|
||||
case T_LEFTBRACKET:
|
||||
case T_RIGHTBRACKET:
|
||||
case T_LEFTBRACE:
|
||||
case T_RIGHTBRACE:
|
||||
return false; // no insertion between parens/brackets/braces
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_LEFTBRACE:
|
||||
case T_RIGHTBRACE:
|
||||
switch (prev) {
|
||||
case T_LEFTPAREN:
|
||||
case T_RIGHTPAREN:
|
||||
case T_LEFTBRACKET:
|
||||
case T_RIGHTBRACKET:
|
||||
case T_LEFTBRACE:
|
||||
case T_RIGHTBRACE:
|
||||
case T_SEMICOLON:
|
||||
case T_COMMA:
|
||||
case T_COLON:
|
||||
return false; // no insertion between parens/brackets/braces
|
||||
|
||||
case T_QUESTION_MARK:
|
||||
if (T_QUESTION_MARK == beforeprev)
|
||||
return true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_MINUS:
|
||||
case T_MINUSMINUS:
|
||||
case T_LESS:
|
||||
case T_EQUAL:
|
||||
case T_ASSIGN:
|
||||
case T_GREATER:
|
||||
case T_DIVIDE:
|
||||
case T_CHARLIT:
|
||||
case T_NOT:
|
||||
case T_NOTEQUAL:
|
||||
case T_DIVIDEASSIGN:
|
||||
case T_MINUSASSIGN:
|
||||
if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
|
||||
return true; // ??{op}
|
||||
break;
|
||||
|
||||
case T_COMPL_ALT:
|
||||
case T_OR_ALT:
|
||||
case T_AND_ALT:
|
||||
case T_NOT_ALT:
|
||||
case T_XOR_ALT:
|
||||
case T_ANDASSIGN_ALT:
|
||||
case T_ORASSIGN_ALT:
|
||||
case T_XORASSIGN_ALT:
|
||||
case T_NOTEQUAL_ALT:
|
||||
if (T_IDENTIFIER == prev || T_NONREPLACABLE_IDENTIFIER == prev ||
|
||||
IS_CATEGORY(prev, KeywordTokenType))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
// else, handle operators separately
|
||||
if (IS_CATEGORY(current, OperatorTokenType) &&
|
||||
IS_CATEGORY(prev, OperatorTokenType))
|
||||
{
|
||||
return true; // operators must be delimited always
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void shift_tokens (boost::wave::token_id next_id)
|
||||
{
|
||||
beforeprev = prev;
|
||||
prev = next_id;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::wave::token_id prev; // the previous analyzed token
|
||||
boost::wave::token_id beforeprev; // the token before the previous
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)
|
||||
135
include/boost/wave/util/interpret_pragma.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)
|
||||
#define INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
#include <boost/spirit/core.hpp>
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#include <boost/spirit/actor/assign_actor.hpp>
|
||||
#include <boost/spirit/actor/push_back_actor.hpp>
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
#include <boost/wave/util/macro_helpers.hpp>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
#include <boost/wave/cpp_iteration_context.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
|
||||
#if !defined(spirit_append_actor)
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
|
||||
#else
|
||||
#define spirit_append_actor(actor) boost::spirit::append(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
#endif // !defined(spirit_append_actor)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The function interpret_pragma interprets the given token sequence as the
|
||||
// body of a #pragma directive (or parameter to the _Pragma operator) and
|
||||
// executes the actions associated with recognized Wave specific options.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContextT, typename IteratorT, typename ContainerT>
|
||||
inline bool
|
||||
interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token,
|
||||
IteratorT it, IteratorT const &end, ContainerT &pending)
|
||||
{
|
||||
typedef typename ContextT::token_type token_type;
|
||||
typedef typename token_type::string_type string_type;
|
||||
|
||||
using namespace cpplexer;
|
||||
if (T_IDENTIFIER == token_id(*it) && "wave" == (*it).get_value()) {
|
||||
// this is a wave specific option, it should have the form:
|
||||
// #pragma wave option(value)
|
||||
// where '(value)' is required only for some pragma directives
|
||||
// all of the given #pragma operators are forwarded to the supplied
|
||||
// context_policy
|
||||
using namespace boost::spirit;
|
||||
token_type option;
|
||||
ContainerT values;
|
||||
|
||||
if (!parse (++it, end,
|
||||
( ch_p(T_IDENTIFIER)
|
||||
[spirit_assign_actor(option)]
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask)
|
||||
[spirit_assign_actor(option)]
|
||||
)
|
||||
>> !( ch_p(T_LEFTPAREN)
|
||||
>> lexeme_d[
|
||||
*(anychar_p[spirit_append_actor(values)] - ch_p(T_RIGHTPAREN))
|
||||
]
|
||||
>> ch_p(T_RIGHTPAREN)
|
||||
),
|
||||
pattern_p(WhiteSpaceTokenType, TokenTypeMask)).hit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove the falsely matched closing parenthesis
|
||||
if (values.size() > 0) {
|
||||
if (T_RIGHTPAREN == values.back()) {
|
||||
typename ContainerT::reverse_iterator rit = values.rbegin();
|
||||
|
||||
values.erase((++rit).base());
|
||||
}
|
||||
else {
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option,
|
||||
"missing matching ')'", act_token.get_position());
|
||||
}
|
||||
}
|
||||
|
||||
// decode the option (call the context_policy hook)
|
||||
if (!ctx.interpret_pragma(pending, option, values, act_token))
|
||||
{
|
||||
// unknown #pragma option
|
||||
string_type option_str (option.get_value());
|
||||
|
||||
if (values.size() > 0) {
|
||||
option_str += "(";
|
||||
option_str += impl::as_string(values);
|
||||
option_str += ")";
|
||||
}
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option,
|
||||
option_str, act_token.get_position());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
|
||||
else if (T_IDENTIFIER == token_id(*it) && "once" == (*it).get_value()) {
|
||||
// #pragma once
|
||||
return ctx.add_pragma_once_header(ctx.get_current_filename());
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)
|
||||
71
include/boost/wave/util/iteration_context.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(ITERATION_CONTEXT_HPP_9556CD16_F11E_4ADC_AC8B_FB9A174BE664_INCLUDED)
|
||||
#define ITERATION_CONTEXT_HPP_9556CD16_F11E_4ADC_AC8B_FB9A174BE664_INCLUDED
|
||||
|
||||
#include <cstdlib>
|
||||
#include <stack>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IterationContextT>
|
||||
class iteration_context_stack
|
||||
{
|
||||
typedef std::stack<IterationContextT> base_t;
|
||||
|
||||
public:
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
iteration_context_stack()
|
||||
: max_include_nesting_depth(BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH)
|
||||
{}
|
||||
|
||||
void set_max_include_nesting_depth(size_type new_depth)
|
||||
{ max_include_nesting_depth = new_depth; }
|
||||
size_type get_max_include_nesting_depth() const
|
||||
{ return max_include_nesting_depth; }
|
||||
|
||||
typename base_t::size_type size() const { return iter_ctx.size(); }
|
||||
typename base_t::value_type &top() { return iter_ctx.top(); }
|
||||
void pop() { iter_ctx.pop(); }
|
||||
|
||||
template <typename PositionT>
|
||||
void push(PositionT const &pos, typename base_t::value_type const &val)
|
||||
{
|
||||
if (iter_ctx.size() == max_include_nesting_depth) {
|
||||
char buffer[22]; // 21 bytes holds all NUL-terminated unsigned 64-bit numbers
|
||||
|
||||
using namespace std; // for some systems ltoa is in namespace std
|
||||
sprintf(buffer, "%d", max_include_nesting_depth);
|
||||
BOOST_WAVE_THROW(preprocess_exception, include_nesting_too_deep, buffer,
|
||||
pos);
|
||||
}
|
||||
iter_ctx.push(val);
|
||||
}
|
||||
|
||||
private:
|
||||
size_type max_include_nesting_depth;
|
||||
base_t iter_ctx;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(ITERATION_CONTEXT_HPP_9556CD16_F11E_4ADC_AC8B_FB9A174BE664_INCLUDED)
|
||||
126
include/boost/wave/util/macro_definition.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED)
|
||||
#define MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// macro_definition
|
||||
//
|
||||
// This class containes all infos for a defined macro.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT, typename ContainerT>
|
||||
struct macro_definition {
|
||||
|
||||
typedef std::vector<TokenT> parameter_container_t;
|
||||
typedef ContainerT definition_container_t;
|
||||
|
||||
typedef typename parameter_container_t::const_iterator
|
||||
const_parameter_iterator_t;
|
||||
typedef typename definition_container_t::const_iterator
|
||||
const_definition_iterator_t;
|
||||
|
||||
macro_definition(TokenT const &token_, bool has_parameters,
|
||||
bool is_predefined_, long uid_)
|
||||
: macroname(token_), uid(uid_), is_functionlike(has_parameters),
|
||||
replaced_parameters(false), is_available_for_replacement(true),
|
||||
is_predefined(is_predefined_)
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
, has_ellipsis(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
// generated copy constructor
|
||||
// generated destructor
|
||||
// generated assignment operator
|
||||
|
||||
// Replace all occurrences of the parameters throughout the macrodefinition
|
||||
// with special parameter tokens to simplify later macro replacement.
|
||||
// Additionally mark all occurrences of the macro name itself throughout
|
||||
// the macro definition
|
||||
void replace_parameters()
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
if (!replaced_parameters) {
|
||||
typename definition_container_t::iterator end = macrodefinition.end();
|
||||
typename definition_container_t::iterator it = macrodefinition.begin();
|
||||
|
||||
for (/**/; it != end; ++it) {
|
||||
if (T_IDENTIFIER == token_id(*it) ||
|
||||
IS_CATEGORY(token_id(*it), KeywordTokenType))
|
||||
{
|
||||
// may be a parameter to replace
|
||||
const_parameter_iterator_t cend = macroparameters.end();
|
||||
const_parameter_iterator_t cit = macroparameters.begin();
|
||||
for (typename parameter_container_t::size_type i = 0;
|
||||
cit != cend; ++cit, ++i)
|
||||
{
|
||||
if ((*it).get_value() == (*cit).get_value()) {
|
||||
(*it).set_token_id(token_id(T_PARAMETERBASE+i));
|
||||
break;
|
||||
}
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
else if (T_ELLIPSIS == token_id(*cit) &&
|
||||
"__VA_ARGS__" == (*it).get_value())
|
||||
{
|
||||
// __VA_ARGS__ requires special handling
|
||||
(*it).set_token_id(token_id(T_EXTPARAMETERBASE+i));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
// we need to know, if the last of the formal arguments is an ellipsis
|
||||
if (macroparameters.size() > 0 &&
|
||||
T_ELLIPSIS == token_id(macroparameters.back()))
|
||||
{
|
||||
has_ellipsis = true;
|
||||
}
|
||||
#endif
|
||||
replaced_parameters = true; // do it only once
|
||||
}
|
||||
}
|
||||
|
||||
TokenT macroname; // macro name
|
||||
parameter_container_t macroparameters; // formal parameters
|
||||
definition_container_t macrodefinition; // macro definition token sequence
|
||||
long uid; // unique id of this macro
|
||||
bool is_functionlike;
|
||||
bool replaced_parameters;
|
||||
bool is_available_for_replacement;
|
||||
bool is_predefined;
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
bool has_ellipsis;
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED)
|
||||
241
include/boost/wave/util/macro_helpers.hpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)
|
||||
#define MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/cpplexer/validate_universal_char.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
namespace impl {
|
||||
|
||||
// escape a string literal (insert '\\' before every '\"', '?' and '\\')
|
||||
template <typename StringT>
|
||||
inline StringT
|
||||
escape_lit(StringT const &value)
|
||||
{
|
||||
StringT result;
|
||||
typename StringT::size_type pos = 0;
|
||||
typename StringT::size_type pos1 = value.find_first_of ("\"\\?", 0);
|
||||
if (StringT::npos != pos1) {
|
||||
do {
|
||||
result += value.substr(pos, pos1-pos)
|
||||
+ StringT("\\")
|
||||
+ StringT(1, value[pos1]);
|
||||
pos1 = value.find_first_of ("\"\\?", pos = pos1+1);
|
||||
} while (StringT::npos != pos1);
|
||||
result += value.substr(pos);
|
||||
}
|
||||
else {
|
||||
result = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// un-escape a string literal (remove '\\' just before '\\', '\"' or '?')
|
||||
template <typename StringT>
|
||||
inline StringT
|
||||
unescape_lit(StringT const &value)
|
||||
{
|
||||
StringT result;
|
||||
typename StringT::size_type pos = 0;
|
||||
typename StringT::size_type pos1 = value.find_first_of ("\\", 0);
|
||||
if (StringT::npos != pos1) {
|
||||
do {
|
||||
if ('\\' == value[pos1+1] || '\"' == value[pos1+1] ||
|
||||
'?' == value[pos1+1])
|
||||
{
|
||||
result += value.substr(pos, pos1-pos);
|
||||
}
|
||||
pos1 = value.find_first_of ("\\", pos = pos1+1);
|
||||
} while (pos1 != StringT::npos);
|
||||
result += value.substr(pos);
|
||||
}
|
||||
else {
|
||||
// the string doesn't contain any escaped character sequences
|
||||
result = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// return the string representation of a token sequence
|
||||
template <typename ContainerT, typename PositionT>
|
||||
inline typename ContainerT::value_type::string_type
|
||||
as_stringlit (ContainerT const &token_sequence, PositionT const &pos)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
typedef typename ContainerT::value_type::string_type string_type;
|
||||
|
||||
string_type result("\"");
|
||||
bool was_whitespace = false;
|
||||
typename ContainerT::const_iterator end = token_sequence.end();
|
||||
for (typename ContainerT::const_iterator it = token_sequence.begin();
|
||||
it != end; ++it)
|
||||
{
|
||||
token_id id = token_id(*it);
|
||||
|
||||
if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
|
||||
if (!was_whitespace) {
|
||||
// C++ standard 16.3.2.2 [cpp.stringize]
|
||||
// Each occurrence of white space between the argument’s
|
||||
// preprocessing tokens becomes a single space character in the
|
||||
// character string literal.
|
||||
result += " ";
|
||||
was_whitespace = true;
|
||||
}
|
||||
}
|
||||
else if (T_STRINGLIT == id || T_CHARLIT == id) {
|
||||
// string literals and character literals have to be escaped
|
||||
result += impl::escape_lit((*it).get_value());
|
||||
was_whitespace = false;
|
||||
}
|
||||
else
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
if (T_PLACEMARKER != id)
|
||||
#endif
|
||||
{
|
||||
// now append this token to the string
|
||||
result += (*it).get_value();
|
||||
was_whitespace = false;
|
||||
}
|
||||
}
|
||||
result += "\"";
|
||||
|
||||
// validate the resulting literal to contain no invalid universal character
|
||||
// value (throws if invalid chars found)
|
||||
boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
|
||||
pos.get_column(), pos.get_file());
|
||||
return result;
|
||||
}
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
// return the string representation of a token sequence
|
||||
template <typename ContainerT, typename PositionT>
|
||||
inline typename ContainerT::value_type::string_type
|
||||
as_stringlit (std::vector<ContainerT> const &arguments,
|
||||
typename std::vector<ContainerT>::size_type i, PositionT const &pos)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
typedef typename ContainerT::value_type::string_type string_type;
|
||||
|
||||
BOOST_SPIRIT_ASSERT(0 <= i && i < arguments.size());
|
||||
|
||||
string_type result("\"");
|
||||
bool was_whitespace = false;
|
||||
|
||||
for (/**/; i < arguments.size(); ++i) {
|
||||
// stringize all remaining arguments
|
||||
typename ContainerT::const_iterator end = arguments[i].end();
|
||||
for (typename ContainerT::const_iterator it = arguments[i].begin();
|
||||
it != end; ++it)
|
||||
{
|
||||
token_id id = token_id(*it);
|
||||
|
||||
if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
|
||||
if (!was_whitespace) {
|
||||
// C++ standard 16.3.2.2 [cpp.stringize]
|
||||
// Each occurrence of white space between the argument’s
|
||||
// preprocessing tokens becomes a single space character in the
|
||||
// character string literal.
|
||||
result += " ";
|
||||
was_whitespace = true;
|
||||
}
|
||||
}
|
||||
else if (T_STRINGLIT == id || T_CHARLIT == id) {
|
||||
// string literals and character literals have to be escaped
|
||||
result += impl::escape_lit((*it).get_value());
|
||||
was_whitespace = false;
|
||||
}
|
||||
else if (T_PLACEMARKER != id) {
|
||||
// now append this token to the string
|
||||
result += (*it).get_value();
|
||||
was_whitespace = false;
|
||||
}
|
||||
}
|
||||
|
||||
// append comma, if not last argument
|
||||
if (i < arguments.size()-1) {
|
||||
result += ",";
|
||||
was_whitespace = false;
|
||||
}
|
||||
}
|
||||
result += "\"";
|
||||
|
||||
// validate the resulting literal to contain no invalid universal character
|
||||
// value (throws if invalid chars found)
|
||||
boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
|
||||
pos.get_column(), pos.get_file());
|
||||
return result;
|
||||
}
|
||||
#endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
|
||||
// return the string representation of a token sequence
|
||||
template <typename StringT, typename IteratorT>
|
||||
inline StringT
|
||||
as_string(IteratorT it, IteratorT end)
|
||||
{
|
||||
StringT result;
|
||||
for (/**/; it != end; ++it)
|
||||
{
|
||||
result += (*it).get_value();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// return the string representation of a token sequence
|
||||
template <typename ContainerT>
|
||||
inline typename ContainerT::value_type::string_type
|
||||
as_string (ContainerT const &token_sequence)
|
||||
{
|
||||
typedef typename ContainerT::value_type::string_type string_type;
|
||||
return as_string<string_type>(token_sequence.begin(), token_sequence.end());
|
||||
}
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copies all arguments beginning with the given index to the output
|
||||
// sequence. The arguments are separated by commas.
|
||||
//
|
||||
template <typename ContainerT, typename PositionT>
|
||||
void replace_ellipsis (std::vector<ContainerT> const &arguments,
|
||||
typename ContainerT::size_type index,
|
||||
ContainerT &expanded, PositionT const &pos)
|
||||
{
|
||||
using namespace cpplexer;
|
||||
typedef typename ContainerT::value_type token_type;
|
||||
|
||||
token_type comma(T_COMMA, ",", pos);
|
||||
for (/**/; index < arguments.size(); ++index) {
|
||||
ContainerT const &arg = arguments[index];
|
||||
|
||||
std::copy(arg.begin(), arg.end(),
|
||||
std::inserter(expanded, expanded.end()));
|
||||
|
||||
if (index < arguments.size()-1)
|
||||
expanded.push_back(comma);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)
|
||||
55
include/boost/wave/util/pattern_parser.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Global application configuration
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(BOOST_SPIRIT_PATTERN_PARSER_HPP)
|
||||
#define BOOST_SPIRIT_PATTERN_PARSER_HPP
|
||||
|
||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pattern_and class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT = char>
|
||||
struct pattern_and : public boost::spirit::char_parser<pattern_and<CharT> >
|
||||
{
|
||||
pattern_and(CharT pattern_, unsigned long pattern_mask_ = 0UL)
|
||||
: pattern(pattern_),
|
||||
pattern_mask((0UL != pattern_mask_) ? pattern_mask_ : pattern_)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
bool test(T pattern_) const
|
||||
{ return (pattern_ & pattern_mask) == pattern; }
|
||||
|
||||
CharT pattern;
|
||||
unsigned long pattern_mask;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
inline pattern_and<CharT>
|
||||
pattern_p(CharT pattern, unsigned long pattern_mask = 0UL)
|
||||
{ return pattern_and<CharT>(pattern, pattern_mask); }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // defined(BOOST_SPIRIT_PATTERN_PARSER_HPP)
|
||||
40
include/boost/wave/util/symbol_table.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(SYMBOL_TABLE_HPP_32B0F7C6_3DD6_4113_95A5_E16516C6F45A_INCLUDED)
|
||||
#define SYMBOL_TABLE_HPP_32B0F7C6_3DD6_4113_95A5_E16516C6F45A_INCLUDED
|
||||
|
||||
#include <map>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The symbol_table class is used for the storage of defined macros.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename StringT, typename MacroDefT>
|
||||
struct symbol_table
|
||||
: public std::map<StringT, boost::shared_ptr<MacroDefT> >
|
||||
{
|
||||
symbol_table(long uid_)
|
||||
{}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(SYMBOL_TABLE_HPP_32B0F7C6_3DD6_4113_95A5_E16516C6F45A_INCLUDED)
|
||||
145
include/boost/wave/util/time_conversion_helper.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED)
|
||||
#define TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED
|
||||
|
||||
#include <ctime>
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/symbols.hpp>
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#include <boost/spirit/actor/assign_actor.hpp>
|
||||
#include <boost/spirit/actor/push_back_actor.hpp>
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
|
||||
#if !defined(spirit_append_actor)
|
||||
#if SPIRIT_VERSION >= 0x1700
|
||||
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
|
||||
#else
|
||||
#define spirit_append_actor(actor) boost::spirit::append(actor)
|
||||
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
|
||||
#endif // SPIRIT_VERSION >= 0x1700
|
||||
#endif // !defined(spirit_append_actor)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
namespace time_conversion {
|
||||
|
||||
using namespace std; // some systems have std::tm etc. in namespace std
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CPP_TIME_CONVERSION \
|
||||
(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Grammar for parsing a date/time string generated by the C++ compiler from
|
||||
// __DATE__ and __TIME__
|
||||
class time_conversion_grammar :
|
||||
public boost::spirit::grammar<time_conversion_grammar>
|
||||
{
|
||||
public:
|
||||
time_conversion_grammar() : fYearIsCorrected(false)
|
||||
{
|
||||
memset (&time_stamp, 0, sizeof(tm));
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(*this, "time_conversion_grammar",
|
||||
TRACE_CPP_TIME_CONVERSION);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition {
|
||||
|
||||
definition(time_conversion_grammar const &self)
|
||||
{
|
||||
using boost::spirit::int_p;
|
||||
using boost::spirit::add;
|
||||
|
||||
char const *m[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
for (int i = 0; i < 12; ++i)
|
||||
add (month, m[i], i);
|
||||
|
||||
time_rule // expected format is 'Dec 29 2001 11:23:59'
|
||||
= month[spirit_assign_actor(self.time_stamp.tm_mon)]
|
||||
>> int_p[spirit_assign_actor(self.time_stamp.tm_mday)]
|
||||
>> int_p[spirit_assign_actor(self.time_stamp.tm_year)]
|
||||
>> int_p[spirit_assign_actor(self.time_stamp.tm_hour)]
|
||||
>> int_p[spirit_assign_actor(self.time_stamp.tm_min)]
|
||||
>> int_p[spirit_assign_actor(self.time_stamp.tm_sec)]
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(time_rule, TRACE_CPP_TIME_CONVERSION);
|
||||
}
|
||||
|
||||
boost::spirit::rule<ScannerT> time_rule;
|
||||
boost::spirit::symbols<> month;
|
||||
|
||||
boost::spirit::rule<ScannerT> const&
|
||||
start() const { return time_rule; }
|
||||
};
|
||||
|
||||
void correct_year()
|
||||
{
|
||||
if (!fYearIsCorrected) {
|
||||
time_stamp.tm_year -= 1900;
|
||||
fYearIsCorrected = true;
|
||||
}
|
||||
}
|
||||
|
||||
mutable tm time_stamp;
|
||||
bool fYearIsCorrected;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// calculate the time of the compilation as a std::time_t to ensure correctness
|
||||
// of the saved dfa table
|
||||
class time_conversion_helper
|
||||
{
|
||||
public:
|
||||
time_conversion_helper(char const *act_time) : compile_time(0)
|
||||
{
|
||||
using namespace boost::spirit;
|
||||
|
||||
time_conversion_grammar g;
|
||||
|
||||
if (parse (act_time, g, space_p | ch_p(':')).full) {
|
||||
g.correct_year();
|
||||
compile_time = mktime(&g.time_stamp);
|
||||
}
|
||||
BOOST_ASSERT(0 != compile_time);
|
||||
}
|
||||
|
||||
time_t get_time() const { return compile_time; }
|
||||
|
||||
private:
|
||||
time_t compile_time;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_CPP_TIME_CONVERSION
|
||||
} // namespace time_conversion
|
||||
|
||||
// import time_conversion into the boost::wave::util namespace
|
||||
using namespace time_conversion;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED)
|
||||
158
include/boost/wave/util/transform_iterator.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED)
|
||||
#define TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED
|
||||
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
#if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace impl {
|
||||
|
||||
#if BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Transform Iterator Adaptor
|
||||
//
|
||||
// Upon deference, apply some unary function object and return the
|
||||
// result by reference.
|
||||
//
|
||||
// This class is adapted from the Boost.Iterator library, where a similar
|
||||
// class exists, which returns the next item by value
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <class AdaptableUnaryFunctionT>
|
||||
struct ref_transform_iterator_policies
|
||||
: public boost::default_iterator_policies
|
||||
{
|
||||
ref_transform_iterator_policies()
|
||||
{}
|
||||
ref_transform_iterator_policies(const AdaptableUnaryFunctionT &f)
|
||||
: m_f(f) {}
|
||||
|
||||
template <class IteratorAdaptorT>
|
||||
typename IteratorAdaptorT::reference
|
||||
dereference(const IteratorAdaptorT &iter) const
|
||||
{ return m_f(*iter.base()); }
|
||||
|
||||
AdaptableUnaryFunctionT m_f;
|
||||
};
|
||||
|
||||
template <class AdaptableUnaryFunctionT, class IteratorT>
|
||||
class ref_transform_iterator_generator
|
||||
{
|
||||
typedef typename AdaptableUnaryFunctionT::result_type value_type;
|
||||
|
||||
public:
|
||||
typedef boost::iterator_adaptor<
|
||||
IteratorT,
|
||||
ref_transform_iterator_policies<AdaptableUnaryFunctionT>,
|
||||
value_type, value_type const &, value_type const *,
|
||||
std::input_iterator_tag>
|
||||
type;
|
||||
};
|
||||
|
||||
template <class AdaptableUnaryFunctionT, class IteratorT>
|
||||
inline
|
||||
typename ref_transform_iterator_generator<
|
||||
AdaptableUnaryFunctionT, IteratorT>::type
|
||||
make_ref_transform_iterator(
|
||||
IteratorT base,
|
||||
const AdaptableUnaryFunctionT &f = AdaptableUnaryFunctionT())
|
||||
{
|
||||
typedef typename ref_transform_iterator_generator<
|
||||
AdaptableUnaryFunctionT, IteratorT>::type
|
||||
result_t;
|
||||
return result_t(base, f);
|
||||
}
|
||||
|
||||
// Retrieve the token value given a parse node
|
||||
// This is used in conjunction with the ref_transform_iterator above, to
|
||||
// get the token values while iterating directly over the parse tree.
|
||||
template <typename TokenT, typename ParseTreeNodeT>
|
||||
struct get_token_value {
|
||||
|
||||
typedef TokenT result_type;
|
||||
|
||||
TokenT const &operator()(ParseTreeNodeT const &node) const
|
||||
{
|
||||
BOOST_ASSERT(1 == std::distance(node.value.begin(),
|
||||
node.value.end()));
|
||||
return *node.value.begin();
|
||||
}
|
||||
};
|
||||
|
||||
#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The new Boost.Iterator library already conatins a transform_iterator usable
|
||||
// for our needs. The code below wraps this up.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <class AdaptableUnaryFunctionT, class IteratorT>
|
||||
class ref_transform_iterator_generator
|
||||
{
|
||||
typedef typename AdaptableUnaryFunctionT::result_type return_type;
|
||||
typedef typename AdaptableUnaryFunctionT::argument_type argument_type;
|
||||
|
||||
public:
|
||||
typedef boost::transform_iterator<
|
||||
return_type (*)(argument_type), IteratorT, return_type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <class AdaptableUnaryFunctionT, class IteratorT>
|
||||
inline
|
||||
typename ref_transform_iterator_generator<
|
||||
AdaptableUnaryFunctionT, IteratorT>::type
|
||||
make_ref_transform_iterator(
|
||||
IteratorT base, AdaptableUnaryFunctionT const &f)
|
||||
{
|
||||
typedef typename ref_transform_iterator_generator<
|
||||
AdaptableUnaryFunctionT, IteratorT>::type
|
||||
iterator_type;
|
||||
return iterator_type(base, f.transform);
|
||||
}
|
||||
|
||||
// Retrieve the token value given a parse node
|
||||
// This is used in conjunction with the ref_transform_iterator above, to
|
||||
// get the token values while iterating directly over the parse tree.
|
||||
template <typename TokenT, typename ParseTreeNodeT>
|
||||
struct get_token_value {
|
||||
|
||||
typedef TokenT const &result_type;
|
||||
typedef ParseTreeNodeT const &argument_type;
|
||||
|
||||
static result_type
|
||||
transform (argument_type node)
|
||||
{
|
||||
BOOST_ASSERT(1 == std::distance(node.value.begin(),
|
||||
node.value.end()));
|
||||
return *node.value.begin();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED)
|
||||
455
include/boost/wave/util/unput_queue_iterator.hpp
Normal file
@@ -0,0 +1,455 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Definition of the unput queue iterator
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
#if !defined(UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)
|
||||
#define UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace util {
|
||||
|
||||
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
|
||||
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
template <typename TokenT, typename ContainerT>
|
||||
class unput_queue_policies : public boost::default_iterator_policies
|
||||
{
|
||||
public:
|
||||
unput_queue_policies(ContainerT &unput_queue_)
|
||||
: unput_queue(unput_queue_)
|
||||
{}
|
||||
|
||||
unput_queue_policies &operator= (unput_queue_policies const &rhs)
|
||||
{
|
||||
unput_queue = rhs.unput_queue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename BaseT>
|
||||
void initialize(BaseT &)
|
||||
{}
|
||||
|
||||
template <typename IteratorAdaptorT>
|
||||
typename IteratorAdaptorT::reference
|
||||
dereference(const IteratorAdaptorT &x) const
|
||||
{
|
||||
if (x.policies().unput_queue.size() > 0)
|
||||
return x.policies().unput_queue.front();
|
||||
return *x.base();
|
||||
}
|
||||
|
||||
template <typename IteratorAdaptorT>
|
||||
void
|
||||
increment(IteratorAdaptorT &x)
|
||||
{
|
||||
if (x.policies().unput_queue.size() > 0) {
|
||||
// there exist pending tokens in the unput queue
|
||||
x.policies().unput_queue.pop_front();
|
||||
}
|
||||
else {
|
||||
// the unput_queue is empty, so advance the base iterator
|
||||
++x.base();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename IteratorAdaptorT1, typename IteratorAdaptorT2>
|
||||
bool
|
||||
equal(const IteratorAdaptorT1 &x, const IteratorAdaptorT2 &y) const
|
||||
{
|
||||
// two iterators are equal, if both begin() iterators of the queue objects
|
||||
// are equal and the base iterators are equal as well
|
||||
return
|
||||
(x.policies().unput_queue.begin() == y.policies().unput_queue.begin() ||
|
||||
(0 == x.policies().queuesize() && 0 == y.policies().queuesize())) &&
|
||||
x.base() == y.base();
|
||||
}
|
||||
|
||||
typename ContainerT::size_type queuesize() const
|
||||
{ return unput_queue.size(); }
|
||||
|
||||
ContainerT &get_unput_queue() { return unput_queue; }
|
||||
ContainerT const &get_unput_queue() const { return unput_queue; }
|
||||
|
||||
private:
|
||||
ContainerT &unput_queue;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// unput_queue_iterator
|
||||
//
|
||||
// The unput_queue_iterator templates encapsulates an unput_queue together
|
||||
// with the direct input to be read after the unput queue is emptied
|
||||
//
|
||||
// This version is for the old iterator_adaptors (Boost V1.30.x)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename TokenT, typename ContainerT>
|
||||
class unput_queue_iterator
|
||||
: public boost::iterator_adaptor<
|
||||
IteratorT, unput_queue_policies<TokenT, ContainerT>, TokenT,
|
||||
TokenT const &, TokenT const *>
|
||||
{
|
||||
typedef
|
||||
boost::iterator_adaptor<
|
||||
IteratorT, unput_queue_policies<TokenT, ContainerT>, TokenT,
|
||||
TokenT const &, TokenT const *
|
||||
>
|
||||
base_type;
|
||||
typedef unput_queue_policies<TokenT, ContainerT> policies_type;
|
||||
|
||||
public:
|
||||
typedef ContainerT container_type;
|
||||
typedef IteratorT iterator_type;
|
||||
|
||||
unput_queue_iterator(IteratorT const &it, ContainerT &queue)
|
||||
: base_type(it, policies_type(queue))
|
||||
{}
|
||||
|
||||
ContainerT &get_unput_queue()
|
||||
{ return policies().get_unput_queue(); }
|
||||
ContainerT const &get_unput_queue() const
|
||||
{ return policies().get_unput_queue(); }
|
||||
IteratorT &get_base_iterator()
|
||||
{ return base(); }
|
||||
IteratorT const &get_base_iterator() const
|
||||
{ return base(); }
|
||||
};
|
||||
|
||||
#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// unput_queue_iterator
|
||||
//
|
||||
// The unput_queue_iterator templates encapsulates an unput_queue together
|
||||
// with the direct input to be read after the unput queue is emptied
|
||||
//
|
||||
// This version is for the new iterator_adaptors (was released with
|
||||
// Boost V1.31.0)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename TokenT, typename ContainerT>
|
||||
class unput_queue_iterator
|
||||
: public boost::iterator_adaptor<
|
||||
unput_queue_iterator<IteratorT, TokenT, ContainerT>,
|
||||
IteratorT, TokenT const, std::forward_iterator_tag>
|
||||
{
|
||||
typedef boost::iterator_adaptor<
|
||||
unput_queue_iterator<IteratorT, TokenT, ContainerT>,
|
||||
IteratorT, TokenT const, std::forward_iterator_tag>
|
||||
base_type;
|
||||
|
||||
public:
|
||||
typedef ContainerT container_type;
|
||||
typedef IteratorT iterator_type;
|
||||
|
||||
unput_queue_iterator(IteratorT const &it, ContainerT &queue)
|
||||
: base_type(it), unput_queue(queue)
|
||||
{}
|
||||
|
||||
ContainerT &get_unput_queue()
|
||||
{ return unput_queue; }
|
||||
ContainerT const &get_unput_queue() const
|
||||
{ return unput_queue; }
|
||||
IteratorT &get_base_iterator()
|
||||
{ return base_type::base_reference(); }
|
||||
IteratorT const &get_base_iterator() const
|
||||
{ return base_type::base_reference(); }
|
||||
|
||||
unput_queue_iterator &operator= (unput_queue_iterator const &rhs)
|
||||
{
|
||||
if (this != &rhs) {
|
||||
unput_queue = rhs.unput_queue;
|
||||
base_type::operator=(rhs);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
typename base_type::reference dereference() const
|
||||
{
|
||||
if (!unput_queue.empty())
|
||||
return unput_queue.front();
|
||||
return *base_type::base_reference();
|
||||
}
|
||||
|
||||
void increment()
|
||||
{
|
||||
if (!unput_queue.empty()) {
|
||||
// there exist pending tokens in the unput queue
|
||||
unput_queue.pop_front();
|
||||
}
|
||||
else {
|
||||
// the unput_queue is empty, so advance the base iterator
|
||||
++base_type::base_reference();
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename OtherDerivedT, typename OtherIteratorT,
|
||||
typename V, typename C, typename R, typename D
|
||||
>
|
||||
bool equal(
|
||||
boost::iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
|
||||
const &x) const
|
||||
{
|
||||
// two iterators are equal, if both begin() iterators of the queue
|
||||
// objects are equal and the base iterators are equal as well
|
||||
OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
|
||||
return
|
||||
(unput_queue.empty() && rhs.unput_queue.empty() ||
|
||||
(&unput_queue == &rhs.unput_queue &&
|
||||
unput_queue.begin() == rhs.unput_queue.begin()
|
||||
)
|
||||
) &&
|
||||
get_base_iterator() == rhs.get_base_iterator();
|
||||
}
|
||||
|
||||
private:
|
||||
ContainerT &unput_queue;
|
||||
};
|
||||
|
||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename TokenT, typename ContainerT>
|
||||
struct gen_unput_queue_iterator
|
||||
{
|
||||
typedef ContainerT container_type;
|
||||
typedef IteratorT iterator_type;
|
||||
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
|
||||
return_type;
|
||||
|
||||
static container_type last;
|
||||
|
||||
static return_type
|
||||
generate(iterator_type const &it)
|
||||
{
|
||||
return return_type(it, last);
|
||||
}
|
||||
|
||||
static return_type
|
||||
generate(ContainerT &queue, iterator_type const &it)
|
||||
{
|
||||
return return_type(it, queue);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IteratorT, typename TokenT, typename ContainerT>
|
||||
typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
|
||||
container_type
|
||||
gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::last =
|
||||
typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
|
||||
container_type();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename TokenT, typename ContainerT>
|
||||
struct gen_unput_queue_iterator<
|
||||
unput_queue_iterator<IteratorT, TokenT, ContainerT>,
|
||||
TokenT, ContainerT>
|
||||
{
|
||||
typedef ContainerT container_type;
|
||||
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
|
||||
iterator_type;
|
||||
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
|
||||
return_type;
|
||||
|
||||
static container_type last;
|
||||
|
||||
static return_type
|
||||
generate(iterator_type &it)
|
||||
{
|
||||
return return_t(it.base(), last);
|
||||
}
|
||||
|
||||
static return_type
|
||||
generate(ContainerT &queue, iterator_type &it)
|
||||
{
|
||||
return return_t(it.base(), queue);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT>
|
||||
struct assign_iterator {
|
||||
|
||||
static void
|
||||
do_ (IteratorT &dest, IteratorT const &src)
|
||||
{
|
||||
dest = src;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
|
||||
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
template <typename IteratorT, typename TokenT, typename ContainerT>
|
||||
struct assign_iterator<
|
||||
unput_queue_iterator<IteratorT, TokenT, ContainerT> >
|
||||
{
|
||||
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
|
||||
iterator_type;
|
||||
|
||||
static void
|
||||
do_ (iterator_type &dest, iterator_type const &src)
|
||||
{
|
||||
dest.base() = src.base();
|
||||
dest.policies() = src.policies();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Look for the first non-whitespace token and return this token id.
|
||||
// Note though, that the embedded unput_queues are not touched in any way!
|
||||
//
|
||||
template <typename IteratorT>
|
||||
struct next_token {
|
||||
|
||||
static boost::wave::token_id
|
||||
peek(IteratorT it, IteratorT end, bool skip_whitespace = true)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
if (skip_whitespace) {
|
||||
for (++it; it != end; ++it) {
|
||||
if (!IS_CATEGORY(*it, WhiteSpaceTokenType) &&
|
||||
T_NEWLINE != token_id(*it))
|
||||
{
|
||||
break; // stop at the first non-whitespace token
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
++it; // we have at least to look ahead
|
||||
}
|
||||
if (it != end)
|
||||
return token_id(*it);
|
||||
return T_EOI;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IteratorT, typename TokenT, typename ContainerT>
|
||||
struct next_token<
|
||||
unput_queue_iterator<IteratorT, TokenT, ContainerT> > {
|
||||
|
||||
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT> iterator_type;
|
||||
|
||||
static boost::wave::token_id
|
||||
peek(iterator_type it, iterator_type end, bool skip_whitespace = true)
|
||||
{
|
||||
using namespace boost::wave;
|
||||
|
||||
typename iterator_type::container_type &queue = it.get_unput_queue();
|
||||
|
||||
// first try to find it in the unput_queue
|
||||
if (0 != queue.size()) {
|
||||
typename iterator_type::container_type::iterator cit = queue.begin();
|
||||
typename iterator_type::container_type::iterator cend = queue.end();
|
||||
|
||||
if (skip_whitespace) {
|
||||
for (++cit; cit != cend; ++cit) {
|
||||
if (!IS_CATEGORY(*cit, WhiteSpaceTokenType) &&
|
||||
T_NEWLINE != token_id(*cit))
|
||||
{
|
||||
break; // stop at the first non-whitespace token
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
++cit; // we have at least to look ahead
|
||||
}
|
||||
if (cit != cend)
|
||||
return token_id(*cit);
|
||||
}
|
||||
|
||||
// second try to move on into the base iterator stream
|
||||
typename iterator_type::iterator_type base_it = it.get_base_iterator();
|
||||
typename iterator_type::iterator_type base_end = end.get_base_iterator();
|
||||
|
||||
if (0 == queue.size())
|
||||
++base_it; // advance, if the unput queue is empty
|
||||
|
||||
if (skip_whitespace) {
|
||||
for (/**/; base_it != base_end; ++base_it) {
|
||||
if (!IS_CATEGORY(*base_it, WhiteSpaceTokenType) &&
|
||||
T_NEWLINE != token_id(*base_it))
|
||||
{
|
||||
break; // stop at the first non-whitespace token
|
||||
}
|
||||
}
|
||||
}
|
||||
if (base_it == base_end)
|
||||
return T_EOI;
|
||||
|
||||
return token_id(*base_it);
|
||||
}
|
||||
};
|
||||
|
||||
// Skip all whitespace characters and queue the skipped characters into the
|
||||
// given container
|
||||
template <typename IteratorT>
|
||||
inline boost::wave::token_id
|
||||
skip_whitespace(IteratorT &first, IteratorT const &last)
|
||||
{
|
||||
using namespace cpplexer;
|
||||
|
||||
token_id id = next_token<IteratorT>::peek(first, last, false);
|
||||
|
||||
if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
|
||||
do {
|
||||
++first;
|
||||
id = next_token<IteratorT>::peek(first, last, false);
|
||||
} while (IS_CATEGORY(id, WhiteSpaceTokenType));
|
||||
}
|
||||
++first;
|
||||
return id;
|
||||
}
|
||||
|
||||
template <typename IteratorT, typename ContainerT>
|
||||
inline boost::wave::token_id
|
||||
skip_whitespace(IteratorT &first, IteratorT const &last, ContainerT &queue)
|
||||
{
|
||||
using namespace cpplexer;
|
||||
queue.push_back (*first); // queue up the current token
|
||||
|
||||
token_id id = next_token<IteratorT>::peek(first, last, false);
|
||||
|
||||
if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
|
||||
do {
|
||||
queue.push_back(*++first); // queue up the next whitespace
|
||||
id = next_token<IteratorT>::peek(first, last, false);
|
||||
} while (IS_CATEGORY(id, WhiteSpaceTokenType));
|
||||
}
|
||||
++first;
|
||||
return id;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace util
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)
|
||||
281
include/boost/wave/wave_config.hpp
Normal file
@@ -0,0 +1,281 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Global application configuration
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(WAVE_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED)
|
||||
#define WAVE_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/spirit/version.hpp>
|
||||
#include <boost/wave/wave_version.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Define the maximal include nesting depth allowed. If this value isn't
|
||||
// defined it defaults to 1024
|
||||
//
|
||||
// To define a new initial include nesting depth uncomment the following and
|
||||
// supply a new integer value.
|
||||
//
|
||||
#if !defined(BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH)
|
||||
#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Decide, whether to support variadics and placemarkers
|
||||
//
|
||||
// To implement support variadics and placemarkers uncomment the following
|
||||
//
|
||||
#if !defined(BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS)
|
||||
#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Decide, whether to implement a #warning directive as an extension to the
|
||||
// C++ Standard (same as #error, but emits a warning, not an error)
|
||||
//
|
||||
// To implement #warning directives, uncomment the following
|
||||
//
|
||||
#if !defined(BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE)
|
||||
#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Decide, whether to implement #pragma once
|
||||
//
|
||||
// To implement #pragma once, uncomment the following
|
||||
//
|
||||
#if !defined(BOOST_WAVE_SUPPORT_PRAGMA_ONCE)
|
||||
#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Decide, whether to implement #include_next
|
||||
// Please note, that this is an extension to the C++ Standard.
|
||||
//
|
||||
// To implement #include_next, uncomment the following
|
||||
//
|
||||
#if !defined(BOOST_WAVE_SUPPORT_INCLUDE_NEXT)
|
||||
#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Undefine the following, to enable some MS specific language extensions:
|
||||
// __int8, __int16, __int32, __int64, __based, __declspec, __cdecl,
|
||||
// __fastcall, __stdcall, __try, __except, __finally, __leave, __inline,
|
||||
// __asm, #region, #endregion
|
||||
//
|
||||
// Note: By default this is enabled for Windows based systems, otherwise it's
|
||||
// disabled.
|
||||
#if !defined(BOOST_WAVE_SUPPORT_MS_EXTENSIONS)
|
||||
#if defined(BOOST_WINDOWS)
|
||||
#define BOOST_WAVE_SUPPORT_MS_EXTENSIONS 1
|
||||
#else
|
||||
#define BOOST_WAVE_SUPPORT_MS_EXTENSIONS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allow the message body of the #error and #warning directives to be
|
||||
// preprocessed before the diagnostic is issued.
|
||||
//
|
||||
// Uncommenting the following will preprocess the message bodies of #error and
|
||||
// #warning messages before the error (warning) is issued
|
||||
//
|
||||
#if !defined(BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY)
|
||||
#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allow the #pragma directives to be returned to the caller (optionally after
|
||||
// preprocessing the body)
|
||||
//
|
||||
// Uncommenting the following will skip #pragma directives, so that the caller
|
||||
// will not see them.
|
||||
//
|
||||
#if !defined(BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES)
|
||||
#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allow the body of a #pragma directive to be preprocessed before the
|
||||
// directive is returned to the caller.
|
||||
//
|
||||
// Uncommenting the following will preprocess the bodies of #pragma directives
|
||||
//
|
||||
#if !defined(BOOST_WAVE_PREPROCESS_PRAGMA_BODY)
|
||||
#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allow to define macros with the command line syntax (-DMACRO(x)=definition)
|
||||
//
|
||||
// Uncommenting the following will enable the possibility to define macros
|
||||
// based on the command line syntax
|
||||
//
|
||||
#if !defined(BOOST_WAVE_ENABLE_COMMANDLINE_MACROS)
|
||||
#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Define the string type to be used to store the token values and the file
|
||||
// names inside a file_position template class
|
||||
//
|
||||
#if !defined(BOOST_WAVE_STRINGTYPE)
|
||||
|
||||
// use the following, if you have a fast std::allocator<char>
|
||||
#define BOOST_WAVE_STRINGTYPE boost::wave::util::flex_string< \
|
||||
char, std::char_traits<char>, std::allocator<char>, \
|
||||
boost::wave::util::CowString</*char, */\
|
||||
boost::wave::util::AllocatorStringStorage<char> \
|
||||
> \
|
||||
> \
|
||||
/**/
|
||||
|
||||
/* #define BOOST_WAVE_STRINGTYPE boost::wave::util::flex_string< \
|
||||
char, std::char_traits<char>, boost::fast_pool_allocator<char>, \
|
||||
boost::wave::util::CowString<char, \
|
||||
boost::wave::util::AllocatorStringStorage<char, \
|
||||
boost::fast_pool_allocator<char> \
|
||||
> \
|
||||
> \
|
||||
> \
|
||||
*/ /**/
|
||||
|
||||
// This include is needed for the flex_string class used in the
|
||||
// BOOST_WAVE_STRINGTYPE above.
|
||||
#include <boost/wave/util/flex_string.hpp>
|
||||
|
||||
// This include is needed for the boost::fast_allocator class used in the
|
||||
// BOOST_WAVE_STRINGTYPE above.
|
||||
// Configure Boost.Pool thread support (for now: no thread support at all)
|
||||
//#define BOOST_NO_MT
|
||||
//#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
// Use the following, if you want to incorporate Maxim Yegorushkin's
|
||||
// const_string library (http://sourceforge.net/projects/conststring/), which
|
||||
// may be even faster, than using the flex_string class from above
|
||||
//#define BOOST_WAVE_STRINGTYPE boost::const_string<char>
|
||||
//
|
||||
//#include <boost/const_string/const_string.hpp>
|
||||
//#include <boost/const_string/io.hpp>
|
||||
//#include <boost/const_string/concatenation.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment the following, if you need debug output, the
|
||||
// BOOST_SPIRIT_DEBUG_FLAGS_CPP constants below help to fine control the
|
||||
// amount of the generated debug output.
|
||||
//#define BOOST_SPIRIT_DEBUG
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Debug flags for the Wave library, possible flags spcified below.
|
||||
//
|
||||
// Note: These flags take effect only if the BOOST_SPIRIT_DEBUG constant
|
||||
// above is defined as well.
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR 0x0001
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION 0x0002
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR 0x0004
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR 0x0008
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR 0x0010
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR 0x0020
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR 0x0040
|
||||
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_CPP)
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP 0 // default is no debugging
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// For all recognized preprocessor statements the output parse trees
|
||||
// formatted as xml are printed. The formatted parse trees are streamed to the
|
||||
// std::ostream defined by the WAVE_DUMP_PARSE_TREE_OUT constant.
|
||||
//
|
||||
// Uncomment the following, if you want to see these parse trees.
|
||||
//
|
||||
#if !defined(BOOST_WAVE_DUMP_PARSE_TREE)
|
||||
#define BOOST_WAVE_DUMP_PARSE_TREE 0
|
||||
#endif
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0 && !defined(BOOST_WAVE_DUMP_PARSE_TREE_OUT)
|
||||
#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// For all #if and #elif directives the preprocessed expressions are printed.
|
||||
// These expressions are streamed to the std::ostream defined by the
|
||||
// BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant.
|
||||
//
|
||||
// Uncomment the following, if you want to see the preprocessed expressions
|
||||
//
|
||||
#if !defined(BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS)
|
||||
#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 0
|
||||
#endif
|
||||
#if BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS != 0 && \
|
||||
!defined(BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT)
|
||||
#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Decide, whether to use the separate compilation model for the instantiation
|
||||
// of the C++ lexer objects.
|
||||
//
|
||||
// If this is defined, you should explicitly instantiate the C++ lexer
|
||||
// template with the correct parameters in a separate compilation unit of
|
||||
// your program (see the file instantiate_re2c_lexer.cpp).
|
||||
//
|
||||
// To use the lexer inclusion model, uncomment the following
|
||||
//
|
||||
#if !defined(BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION)
|
||||
#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Decide, whether to use the separate compilation model for the instantiation
|
||||
// of the grammar objects.
|
||||
//
|
||||
// If this is defined, you should explicitly instantiate the grammar
|
||||
// templates with the correct parameters in a separate compilation unit of
|
||||
// your program (see the files instantiate_cpp_grammar.cpp et.al.).
|
||||
//
|
||||
// To use the grammar inclusion model, uncomment the following
|
||||
//
|
||||
#if !defined(BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION)
|
||||
#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// configure Boost.Pool thread support (for now: no thread support at all)
|
||||
#if !defined(BOOST_NO_MT)
|
||||
#define BOOST_NO_MT
|
||||
#endif // !defined(BOOST_NO_MT)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Auto library naming
|
||||
#if BOOST_VERSION >= 103100
|
||||
// auto link features work beginning from Boost V1.31.0
|
||||
#if !defined(BOOST_WAVE_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \
|
||||
!defined(BOOST_WAVE_NO_LIB)
|
||||
|
||||
#define BOOST_LIB_NAME boost_wave
|
||||
|
||||
// tell the auto-link code to select a dll when required:
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WAVE_DYN_LINK)
|
||||
#define BOOST_DYN_LINK
|
||||
#endif
|
||||
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
#endif // auto-linking disabled
|
||||
#endif // BOOST_VERSION
|
||||
|
||||
#endif // !defined(WAVE_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED)
|
||||
26
include/boost/wave/wave_version.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
This is the current version of the Wave library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED)
|
||||
#define WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED
|
||||
|
||||
// BOOST_WAVE_VERSION & 0x0000FF is the sub-minor version
|
||||
// BOOST_WAVE_VERSION & 0x00FF00 is the minor version
|
||||
// BOOST_WAVE_VERSION & 0xFF0000 is the major version
|
||||
#define BOOST_WAVE_VERSION 0x010114
|
||||
|
||||
// The following defines contain the same information as above
|
||||
#define BOOST_WAVE_VERSION_MAJOR 1
|
||||
#define BOOST_WAVE_VERSION_MINOR 1
|
||||
#define BOOST_WAVE_VERSION_SUBMINOR 14
|
||||
|
||||
#endif // !defined(WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED)
|
||||
106
index.html
Normal file
@@ -0,0 +1,106 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave V1.2</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="doc/theme/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body text="#000000" background="doc/theme/bkd.gif">
|
||||
<table width="100%" border="0" cellspacing="2" background="doc/theme/bkd2.gif">
|
||||
<tr>
|
||||
<td width="21"> <h1></h1></td>
|
||||
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Wave
|
||||
V1.1.13</font></b></font></td>
|
||||
<td width="96"><a href="http://spirit.sf.net"><img src="doc/theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table width="75%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="table_title">Table of Contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/preface.html">Preface</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/introduction.html">Introduction</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/quickstart.html">Quick Start</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><b><font face="Geneva, Arial, Helvetica, san-serif">Class
|
||||
References </font></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><a href="doc/class_reference_context.html">The Context
|
||||
Object</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><a href="doc/class_reference_inputpolicy.html">The Input
|
||||
Policy </a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><a href="doc/class_reference_contextpolicy.html">The Context
|
||||
Policy </a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><a href="doc/class_reference_lexer.html">The Lexer Iterator Interface
|
||||
</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><a href="doc/class_reference_tokentype.html">The Token
|
||||
Type</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><a href="doc/token_ids.html">The Token Identifiers </a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><a href="doc/class_reference_fileposition.html">The File
|
||||
Position</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><b><a href="doc/predefined_macros.html">Predefined Macros</a></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/supported_pragmas.html">Supported Pragma
|
||||
Directives </a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/macro_expansion_process.html">The Macro
|
||||
Expansion Process</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/compiletime_config.html">Compile Time Configuration</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/samples.html">Samples</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><b>The Wave Driver Executable</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><b><a href="doc/wave_driver.html">The Wave Driver Command
|
||||
Line </a></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1"><b><a href="doc/tracing_facility.html">The Tracing Facility</a></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/acknowledgements.html">Acknowledgments</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0"><a href="doc/references.html">References</a> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1">
|
||||
<p class="copyright">Copyright © 2003-2005 Hartmut Kaiser<br>
|
||||
<br>
|
||||
<font size="2">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) </font> </p>
|
||||
<span class="updated"></span>
|
||||
<p class="copyright"><span class="updated">Last updated:
|
||||
<!-- #BeginDate format:fcAm1m -->Wednesday, February 9, 2005 23:38<!-- #EndDate -->
|
||||
</span></p>
|
||||
</body>
|
||||
</html>
|
||||
13
samples/Jamfile.v2
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright Vladimir Prus 2004.
|
||||
# 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)
|
||||
|
||||
project
|
||||
: requirements <hardcode-dll-paths>true
|
||||
;
|
||||
|
||||
build-project cpp_tokens/build ;
|
||||
build-project list_includes/build ;
|
||||
build-project quick_start/build ;
|
||||
build-project waveidl/build ;
|
||||
30
samples/cpp_tokens/build/Jamfile
Normal file
@@ -0,0 +1,30 @@
|
||||
# Wave: A Standard compliant C++ preprocessor library
|
||||
#
|
||||
# Boost Wave Library Sample Build Jamfile (cpp_tokens)
|
||||
#
|
||||
# http://spirit.sourceforge.net/
|
||||
#
|
||||
# Copyright (c) 2001-2005 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)
|
||||
|
||||
subproject libs/wave/samples/cpp_tokens/build ;
|
||||
|
||||
exe cpp_tokens
|
||||
: ../cpp_tokens.cpp
|
||||
../instantiate_cpp_exprgrammar.cpp
|
||||
../instantiate_cpp_grammar.cpp
|
||||
../instantiate_cpp_literalgrammars.cpp
|
||||
../instantiate_defined_grammar.cpp
|
||||
../instantiate_slex_lexer.cpp
|
||||
<lib>../../../build/boost_wave
|
||||
<lib>../../../../../libs/program_options/build/boost_program_options
|
||||
<lib>../../../../../libs/filesystem/build/boost_filesystem
|
||||
:
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<vc-7_1><*><rtti>off # workaround for compiler bug
|
||||
:
|
||||
<runtime-link>static
|
||||
<threading>single
|
||||
;
|
||||
|
||||
23
samples/cpp_tokens/build/Jamfile.v2
Normal file
@@ -0,0 +1,23 @@
|
||||
# Wave: A Standard compliant C++ preprocessor library
|
||||
#
|
||||
# Boost Wave Library Sample Build Jamfile (cpp_tokens)
|
||||
#
|
||||
# http://spirit.sourceforge.net/
|
||||
#
|
||||
# Copyright (c) 2001-2005 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)
|
||||
|
||||
exe cpp_tokens
|
||||
: ../cpp_tokens.cpp
|
||||
../instantiate_cpp_exprgrammar.cpp
|
||||
../instantiate_cpp_grammar.cpp
|
||||
../instantiate_cpp_literalgrammars.cpp
|
||||
../instantiate_defined_grammar.cpp
|
||||
../instantiate_slex_lexer.cpp
|
||||
../../../build//boost_wave
|
||||
$(BOOST_ROOT)/boost/program_options//boost_program_options
|
||||
:
|
||||
<toolset>msvc-7.1:<rtti>off # workaround for compiler bug
|
||||
;
|
||||
|
||||
131
samples/cpp_tokens/cpp_tokens.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Sample: Print out the preprocessed tokens returned by the Wave iterator
|
||||
|
||||
This sample shows, how it is possible to use a custom lexer type and a
|
||||
custom token type with the Wave library.
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#include "cpp_tokens.hpp" // global configuration
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Include Wave itself
|
||||
#include <boost/wave.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The following files contain the custom lexer type to use
|
||||
#include "slex_token.hpp"
|
||||
#include "slex_iterator.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// include lexer specifics, import lexer names
|
||||
#if !defined(BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION)
|
||||
#include "slex/cpp_slex_lexer.hpp"
|
||||
#endif // !defined(BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// import required names
|
||||
using namespace boost::spirit;
|
||||
|
||||
using std::string;
|
||||
using std::getline;
|
||||
using std::ifstream;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// main program
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if (2 != argc) {
|
||||
cout << "Usage: cpp_tokens input_file" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// read the file to analyse into a std::string
|
||||
ifstream infile(argv[1]);
|
||||
string teststr;
|
||||
if (infile.is_open()) {
|
||||
infile.unsetf(std::ios::skipws);
|
||||
string line;
|
||||
for (getline(infile, line); infile.good(); getline(infile, line)) {
|
||||
teststr += line;
|
||||
teststr += '\n';
|
||||
}
|
||||
}
|
||||
else {
|
||||
teststr = argv[1];
|
||||
}
|
||||
|
||||
// The following typedef does the trick. It defines the context type to use,
|
||||
// which depends on the lexer type (provided by the second template
|
||||
// parameter). Our lexer type 'slex_iterator<>' depends on a custom token type
|
||||
// 'slex_token<>'. Our custom token type differs from the original one povided
|
||||
// by the Wave library only by defining an additional operator<<(), which is
|
||||
// used to dump the token information carried by a given token (see loop
|
||||
// below).
|
||||
typedef boost::wave::cpp_token_sample::slex_token<> token_type;
|
||||
typedef boost::wave::cpp_token_sample::slex_iterator<token_type>
|
||||
lex_iterator_type;
|
||||
typedef boost::wave::context<std::string::iterator, lex_iterator_type>
|
||||
context_type;
|
||||
|
||||
// The C++ preprocessor iterator shouldn't be constructed directly. It is to be
|
||||
// generated through a boost::wave::context<> object. This object is
|
||||
// additionally to be used to initialize and define different parameters of
|
||||
// the actual preprocessing.
|
||||
// The preprocessing of the input stream is done on the fly behind the scenes
|
||||
// during iteration over the context_type::iterator_type stream.
|
||||
context_type ctx (teststr.begin(), teststr.end(), argv[1]);
|
||||
context_type::iterator_type first = ctx.begin();
|
||||
context_type::iterator_type last = ctx.end();
|
||||
context_type::token_type current_token;
|
||||
|
||||
try {
|
||||
// Traverse over the tokens generated from the input and dump the token
|
||||
// contents.
|
||||
while (first != last) {
|
||||
// retrieve next token
|
||||
current_token = *first;
|
||||
|
||||
// output token info
|
||||
cout << "matched " << current_token << endl;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
catch (boost::wave::cpp_exception &e) {
|
||||
// some preprocessing error
|
||||
cerr
|
||||
<< e.file_name() << "(" << e.line_no() << "): "
|
||||
<< e.description() << endl;
|
||||
return 2;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
// use last recognized token to retrieve the error position
|
||||
cerr
|
||||
<< current_token.get_position().get_file()
|
||||
<< "(" << current_token.get_position().get_line() << "): "
|
||||
<< "unexpected exception: " << e.what()
|
||||
<< endl;
|
||||
return 3;
|
||||
}
|
||||
catch (...) {
|
||||
// use last recognized token to retrieve the error position
|
||||
cerr
|
||||
<< current_token.get_position().get_file()
|
||||
<< "(" << current_token.get_position().get_line() << "): "
|
||||
<< "unexpected exception." << endl;
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
38
samples/cpp_tokens/cpp_tokens.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Sample: Print out the preprocessed tokens returned by the Wave iterator
|
||||
|
||||
This sample shows, how it is possible to use a custom lexer object and a
|
||||
custom token type with the Wave library.
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_TOKENS_HPP_D6A31137_CE14_4869_9779_6357E2C43187_INCLUDED)
|
||||
#define CPP_TOKENS_HPP_D6A31137_CE14_4869_9779_6357E2C43187_INCLUDED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// include often used files from the stdlib
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// include boost config
|
||||
#include <boost/config.hpp> // global configuration information
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// configure this app here (global configuration constants)
|
||||
#include "cpp_tokens_config.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// include required boost libraries
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
#endif // !defined(CPP_TOKENS_HPP_D6A31137_CE14_4869_9779_6357E2C43187_INCLUDED)
|
||||
55
samples/cpp_tokens/cpp_tokens_config.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Sample: Print out the preprocessed tokens returned by the Wave iterator
|
||||
Configuration data
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED)
|
||||
#define CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment the following, if you need debug output, the
|
||||
// BOOST_SPIRIT_DEBUG_FLAGS constants below help to fine control the amount of
|
||||
// the generated debug output
|
||||
//#define BOOST_SPIRIT_DEBUG
|
||||
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// debug flags for the pp-iterator library, possible flags (defined in
|
||||
// wave_config.hpp):
|
||||
//
|
||||
// #define BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR 0x0001
|
||||
// #define BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION 0x0002
|
||||
// #define BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR 0x0004
|
||||
// #define BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR 0x0008
|
||||
// #define BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR 0x0010
|
||||
// #define BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR 0x0020
|
||||
// #define BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR 0x0040
|
||||
|
||||
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP (\
|
||||
/* insert the required flags from above */ \
|
||||
) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Include the configuration stuff for the Wave library itself
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MSVC specific #pragma's
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning (disable: 4355) // 'this' used in base member initializer list
|
||||
#pragma warning (disable: 4800) // forcing value to bool 'true' or 'false'
|
||||
#pragma inline_depth(255)
|
||||
#pragma inline_recursion(on)
|
||||
#endif // defined(BOOST_MSVC)
|
||||
|
||||
#endif // !defined(CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED)
|
||||
42
samples/cpp_tokens/instantiate_cpp_exprgrammar.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Sample: prints out the preprocessed tokens returned by the pp iterator
|
||||
Explicit instantiation of the cpp_expression_grammar parsing
|
||||
function
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#include "cpp_tokens.hpp" // config data
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include "slex_token.hpp"
|
||||
#include "slex_iterator.hpp"
|
||||
|
||||
#include <boost/wave/grammars/cpp_expression_grammar.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Explicit instantiation of the expression_grammar_gen template with the
|
||||
// correct token type. This instantiates the corresponding parse function,
|
||||
// which in turn instantiates the expression_grammar object (see
|
||||
// wave/grammars/cpp_expression_grammar.hpp)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef boost::wave::cpp_token_sample::slex_token<> token_type;
|
||||
|
||||
template struct boost::wave::grammars::expression_grammar_gen<token_type>;
|
||||
|
||||
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
42
samples/cpp_tokens/instantiate_cpp_grammar.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Sample: prints out the preprocessed tokens returned by the pp iterator
|
||||
Explicit instantiation of the cpp_grammar parsing function
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#include "cpp_tokens.hpp" // config data
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include "slex_token.hpp"
|
||||
#include "slex_iterator.hpp"
|
||||
|
||||
#include <boost/wave/grammars/cpp_grammar.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Explicit instantiation of the cpp_grammar_gen template with the correct
|
||||
// token type. This instantiates the corresponding pt_parse function, which
|
||||
// in turn instantiates the cpp_grammar object
|
||||
// (see wave/grammars/cpp_grammar.hpp)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef boost::wave::cpp_token_sample::slex_iterator<
|
||||
boost::wave::cpp_token_sample::slex_token<> >
|
||||
lexer_type;
|
||||
template struct boost::wave::grammars::cpp_grammar_gen<lexer_type>;
|
||||
|
||||
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
43
samples/cpp_tokens/instantiate_cpp_literalgrammars.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Sample: prints out the preprocessed tokens returned by the pp iterator
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#include "cpp_tokens.hpp" // config data
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include "slex_token.hpp"
|
||||
#include "slex_iterator.hpp"
|
||||
|
||||
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
|
||||
#include <boost/wave/grammars/cpp_intlit_grammar.hpp>
|
||||
#include <boost/wave/grammars/cpp_chlit_grammar.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Explicit instantiation of the intlit_grammar_gen, chlit_grammar_gen and
|
||||
// floatlit_grammar_gen templates with the correct token type. This
|
||||
// instantiates the corresponding parse function, which in turn instantiates
|
||||
// the corresponding parser object.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef boost::wave::cpp_token_sample::slex_token<> token_type;
|
||||
|
||||
template struct boost::wave::grammars::intlit_grammar_gen<token_type>;
|
||||
template struct boost::wave::grammars::chlit_grammar_gen<token_type>;
|
||||
|
||||
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
39
samples/cpp_tokens/instantiate_defined_grammar.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#include "cpp_tokens.hpp" // config data
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include "slex_token.hpp"
|
||||
#include "slex_iterator.hpp"
|
||||
|
||||
#include <boost/wave/grammars/cpp_defined_grammar.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Explicit instantiation of the defined_grammar_gen template
|
||||
// with the correct token type. This instantiates the corresponding parse
|
||||
// function, which in turn instantiates the defined_grammar
|
||||
// object (see wave/grammars/cpp_defined_grammar.hpp)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef boost::wave::cpp_token_sample::slex_iterator<
|
||||
boost::wave::cpp_token_sample::slex_token<> >
|
||||
lexer_type;
|
||||
template struct boost::wave::grammars::defined_grammar_gen<lexer_type>;
|
||||
|
||||
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
|
||||
47
samples/cpp_tokens/instantiate_slex_lexer.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
Sample: Print out the preprocessed tokens returned by the Wave iterator
|
||||
Explicit instantiation of the lex_functor generation function
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#include "cpp_tokens.hpp" // config data
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include "slex_token.hpp"
|
||||
#include "slex_iterator.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The following file needs to be included only once throughout the whole
|
||||
// program.
|
||||
#include "slex/cpp_slex_lexer.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This instantiates the correct 'new_lexer' function, which generates the
|
||||
// C++ lexer used in this sample.
|
||||
//
|
||||
// This is moved into a separate compilation unit to decouple the compilation
|
||||
// of the C++ lexer from the compilation of the other modules, which helps to
|
||||
// reduce compilation time.
|
||||
//
|
||||
// The template parameter(s) supplied should be identical to the parameters
|
||||
// supplied while instantiating the context<> template.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template struct boost::wave::cpp_token_sample::new_lexer_gen<
|
||||
std::string::iterator>;
|
||||
|
||||
#endif // BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0
|
||||
620
samples/cpp_tokens/slex/cpp_slex_lexer.hpp
Normal file
@@ -0,0 +1,620 @@
|
||||
/*=============================================================================
|
||||
Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
SLex (Spirit Lex) based C++ lexer
|
||||
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright (c) 2001-2005 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)
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(SLEX_LEXER_HPP_5E8E1DF0_BB41_4938_B7E5_A4BB68222FF6_INCLUDED)
|
||||
#define SLEX_LEXER_HPP_5E8E1DF0_BB41_4938_B7E5_A4BB68222FF6_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
#include <iostream>
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/spirit/core.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/util/file_position.hpp>
|
||||
#include <boost/wave/util/time_conversion_helper.hpp>
|
||||
#include <boost/wave/cpplexer/validate_universal_char.hpp>
|
||||
|
||||
#include "../slex_interface.hpp"
|
||||
#include "../slex_token.hpp"
|
||||
#include "../slex_iterator.hpp"
|
||||
|
||||
#include "lexer.hpp" // "spirit/lexer.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace cpp_token_sample {
|
||||
namespace slex {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// encapsulation of the boost::spirit::slex based cpp lexer
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
class lexer
|
||||
: public boost::spirit::lexer<
|
||||
boost::wave::util::position_iterator<IteratorT, PositionT> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::wave::util::position_iterator<IteratorT, PositionT>
|
||||
iterator_type;
|
||||
typedef typename std::iterator_traits<IteratorT>::value_type char_t;
|
||||
typedef boost::spirit::lexer<iterator_type> base_t;
|
||||
|
||||
typedef boost::wave::cpp_token_sample::slex_token<PositionT> token_type;
|
||||
|
||||
lexer();
|
||||
void init_dfa(boost::wave::language_support language);
|
||||
|
||||
// get time of last compilation
|
||||
static std::time_t get_compilation_time()
|
||||
{ return compilation_time.get_time(); }
|
||||
|
||||
private:
|
||||
// initialization data (regular expressions for the token definitions)
|
||||
struct lexer_data {
|
||||
token_id tokenid; // token data
|
||||
char_t const *tokenregex; // associated token to match
|
||||
typename base_t::callback_t tokencb; // associated callback function
|
||||
unsigned int lexerstate; // valid for lexer state
|
||||
};
|
||||
|
||||
static lexer_data const init_data[]; // common patterns
|
||||
static lexer_data const init_data_cpp[]; // C++ only patterns
|
||||
|
||||
// helper for calculation of the time of last compilation
|
||||
static boost::wave::util::time_conversion_helper compilation_time;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// data required for initialization of the lexer (token definitions)
|
||||
#define OR "|"
|
||||
#define Q(c) "\\" c
|
||||
#define TRI(c) Q("?") Q("?") c
|
||||
|
||||
// definition of some subtoken regexps to simplify the regex definitions
|
||||
#define BLANK "[ \\t]"
|
||||
#define CCOMMENT \
|
||||
Q("/") Q("*") "[^*]*" Q("*") "+" "(" "[^/*][^*]*" Q("*") "+" ")*" Q("/")
|
||||
|
||||
#define PPSPACE "(" BLANK OR CCOMMENT ")*"
|
||||
|
||||
#define OCTALDIGIT "[0-7]"
|
||||
#define DIGIT "[0-9]"
|
||||
#define HEXDIGIT "[0-9a-fA-F]"
|
||||
#define SIGN "[-+]?"
|
||||
#define EXPONENT "(" "[eE]" SIGN "[0-9]+" ")"
|
||||
|
||||
#define INTEGER_SUFFIX "(" "[uU][lL]?|[lL][uU]?" ")"
|
||||
#define FLOAT_SUFFIX "(" "[fF][lL]?|[lL][fF]?" ")"
|
||||
#define CHAR_SPEC "L?"
|
||||
|
||||
#define BACKSLASH "(" Q("\\") OR TRI(Q("/")) ")"
|
||||
#define ESCAPESEQ BACKSLASH "(" \
|
||||
"[abfnrtv?'\"]" OR \
|
||||
BACKSLASH OR \
|
||||
"x" HEXDIGIT "+" OR \
|
||||
OCTALDIGIT OCTALDIGIT "?" OCTALDIGIT "?" \
|
||||
")"
|
||||
#define HEXQUAD HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT
|
||||
#define UNIVERSALCHAR BACKSLASH "(" \
|
||||
"u" HEXQUAD OR \
|
||||
"U" HEXQUAD HEXQUAD \
|
||||
")"
|
||||
|
||||
#define POUNDDEF "(" "#" OR TRI("=") OR Q("%:") ")"
|
||||
#define NEWLINEDEF "(" "\\n" OR "\\r" OR "\\r\\n" ")"
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
#define INCLUDEDEF "(include|include_next)"
|
||||
#else
|
||||
#define INCLUDEDEF "include"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// sexer state constants
|
||||
#define LEXER_STATE_NORMAL 0
|
||||
#define LEXER_STATE_PP 1
|
||||
|
||||
#define NUM_LEXER_STATES 1
|
||||
|
||||
// helper for initializing token data
|
||||
#define TOKEN_DATA(id, regex) \
|
||||
{ T_##id, regex, 0, LEXER_STATE_NORMAL }
|
||||
|
||||
#define TOKEN_DATA_EX(id, regex, callback) \
|
||||
{ T_##id, regex, callback, LEXER_STATE_NORMAL }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// common C++/C99 token definitions
|
||||
template <typename IteratorT, typename PositionT>
|
||||
typename lexer<IteratorT, PositionT>::lexer_data const
|
||||
lexer<IteratorT, PositionT>::init_data[] =
|
||||
{
|
||||
TOKEN_DATA(AND, "&"),
|
||||
TOKEN_DATA(ANDAND, "&&"),
|
||||
TOKEN_DATA(ASSIGN, "="),
|
||||
TOKEN_DATA(ANDASSIGN, "&="),
|
||||
TOKEN_DATA(OR, Q("|")),
|
||||
TOKEN_DATA(OR_TRIGRAPH, TRI("!")),
|
||||
TOKEN_DATA(ORASSIGN, Q("|=") OR TRI("!=")),
|
||||
TOKEN_DATA(XOR, Q("^")),
|
||||
TOKEN_DATA(XOR_TRIGRAPH, TRI("'")),
|
||||
TOKEN_DATA(XORASSIGN, Q("^=") OR TRI("'=")),
|
||||
TOKEN_DATA(COMMA, ","),
|
||||
TOKEN_DATA(COLON, ":"),
|
||||
TOKEN_DATA(DIVIDE, Q("/")),
|
||||
TOKEN_DATA(DIVIDEASSIGN, Q("/=")),
|
||||
TOKEN_DATA(DOT, Q(".")),
|
||||
TOKEN_DATA(ELLIPSIS, Q(".") Q(".") Q(".")),
|
||||
TOKEN_DATA(EQUAL, "=="),
|
||||
TOKEN_DATA(GREATER, ">"),
|
||||
TOKEN_DATA(GREATEREQUAL, ">="),
|
||||
TOKEN_DATA(LEFTBRACE, Q("{")),
|
||||
TOKEN_DATA(LEFTBRACE_ALT, "<" Q("%")),
|
||||
TOKEN_DATA(LEFTBRACE_TRIGRAPH, TRI("<")),
|
||||
TOKEN_DATA(LESS, "<"),
|
||||
TOKEN_DATA(LESSEQUAL, "<="),
|
||||
TOKEN_DATA(LEFTPAREN, Q("(")),
|
||||
TOKEN_DATA(LEFTBRACKET, Q("[")),
|
||||
TOKEN_DATA(LEFTBRACKET_ALT, "<:"),
|
||||
TOKEN_DATA(LEFTBRACKET_TRIGRAPH, TRI(Q("("))),
|
||||
TOKEN_DATA(MINUS, Q("-")),
|
||||
TOKEN_DATA(MINUSASSIGN, Q("-=")),
|
||||
TOKEN_DATA(MINUSMINUS, Q("-") Q("-")),
|
||||
TOKEN_DATA(PERCENT, Q("%")),
|
||||
TOKEN_DATA(PERCENTASSIGN, Q("%=")),
|
||||
TOKEN_DATA(NOT, "!"),
|
||||
TOKEN_DATA(NOTEQUAL, "!="),
|
||||
TOKEN_DATA(OROR, Q("|") Q("|") OR TRI("!") Q("|") OR Q("|") TRI("!") OR
|
||||
TRI("!") TRI("!")),
|
||||
TOKEN_DATA(PLUS, Q("+")),
|
||||
TOKEN_DATA(PLUSASSIGN, Q("+=")),
|
||||
TOKEN_DATA(PLUSPLUS, Q("+") Q("+")),
|
||||
TOKEN_DATA(ARROW, Q("->")),
|
||||
TOKEN_DATA(QUESTION_MARK, Q("?")),
|
||||
TOKEN_DATA(RIGHTBRACE, Q("}")),
|
||||
TOKEN_DATA(RIGHTBRACE_ALT, Q("%>")),
|
||||
TOKEN_DATA(RIGHTBRACE_TRIGRAPH, TRI(">")),
|
||||
TOKEN_DATA(RIGHTPAREN, Q(")")),
|
||||
TOKEN_DATA(RIGHTBRACKET, Q("]")),
|
||||
TOKEN_DATA(RIGHTBRACKET_ALT, ":>"),
|
||||
TOKEN_DATA(RIGHTBRACKET_TRIGRAPH, TRI(Q(")"))),
|
||||
TOKEN_DATA(SEMICOLON, ";"),
|
||||
TOKEN_DATA(SHIFTLEFT, "<<"),
|
||||
TOKEN_DATA(SHIFTLEFTASSIGN, "<<="),
|
||||
TOKEN_DATA(SHIFTRIGHT, ">>"),
|
||||
TOKEN_DATA(SHIFTRIGHTASSIGN, ">>="),
|
||||
TOKEN_DATA(STAR, Q("*")),
|
||||
TOKEN_DATA(COMPL, Q("~")),
|
||||
TOKEN_DATA(COMPL_TRIGRAPH, TRI("-")),
|
||||
TOKEN_DATA(STARASSIGN, Q("*=")),
|
||||
TOKEN_DATA(ASM, "asm"),
|
||||
TOKEN_DATA(AUTO, "auto"),
|
||||
TOKEN_DATA(BOOL, "bool"),
|
||||
TOKEN_DATA(FALSE, "false"),
|
||||
TOKEN_DATA(TRUE, "true"),
|
||||
TOKEN_DATA(BREAK, "break"),
|
||||
TOKEN_DATA(CASE, "case"),
|
||||
TOKEN_DATA(CATCH, "catch"),
|
||||
TOKEN_DATA(CHAR, "char"),
|
||||
TOKEN_DATA(CLASS, "class"),
|
||||
TOKEN_DATA(CONST, "const"),
|
||||
TOKEN_DATA(CONSTCAST, "const_cast"),
|
||||
TOKEN_DATA(CONTINUE, "continue"),
|
||||
TOKEN_DATA(DEFAULT, "default"),
|
||||
// TOKEN_DATA(DEFINED, "defined"),
|
||||
TOKEN_DATA(DELETE, "delete"),
|
||||
TOKEN_DATA(DO, "do"),
|
||||
TOKEN_DATA(DOUBLE, "double"),
|
||||
TOKEN_DATA(DYNAMICCAST, "dynamic_cast"),
|
||||
TOKEN_DATA(ELSE, "else"),
|
||||
TOKEN_DATA(ENUM, "enum"),
|
||||
TOKEN_DATA(EXPLICIT, "explicit"),
|
||||
TOKEN_DATA(EXPORT, "export"),
|
||||
TOKEN_DATA(EXTERN, "extern"),
|
||||
TOKEN_DATA(FLOAT, "float"),
|
||||
TOKEN_DATA(FOR, "for"),
|
||||
TOKEN_DATA(FRIEND, "friend"),
|
||||
TOKEN_DATA(GOTO, "goto"),
|
||||
TOKEN_DATA(IF, "if"),
|
||||
TOKEN_DATA(INLINE, "inline"),
|
||||
TOKEN_DATA(INT, "int"),
|
||||
TOKEN_DATA(LONG, "long"),
|
||||
TOKEN_DATA(MUTABLE, "mutable"),
|
||||
TOKEN_DATA(NAMESPACE, "namespace"),
|
||||
TOKEN_DATA(NEW, "new"),
|
||||
TOKEN_DATA(OPERATOR, "operator"),
|
||||
TOKEN_DATA(PRIVATE, "private"),
|
||||
TOKEN_DATA(PROTECTED, "protected"),
|
||||
TOKEN_DATA(PUBLIC, "public"),
|
||||
TOKEN_DATA(REGISTER, "register"),
|
||||
TOKEN_DATA(REINTERPRETCAST, "reinterpret_cast"),
|
||||
TOKEN_DATA(RETURN, "return"),
|
||||
TOKEN_DATA(SHORT, "short"),
|
||||
TOKEN_DATA(SIGNED, "signed"),
|
||||
TOKEN_DATA(SIZEOF, "sizeof"),
|
||||
TOKEN_DATA(STATIC, "static"),
|
||||
TOKEN_DATA(STATICCAST, "static_cast"),
|
||||
TOKEN_DATA(STRUCT, "struct"),
|
||||
TOKEN_DATA(SWITCH, "switch"),
|
||||
TOKEN_DATA(TEMPLATE, "template"),
|
||||
TOKEN_DATA(THIS, "this"),
|
||||
TOKEN_DATA(THROW, "throw"),
|
||||
TOKEN_DATA(TRY, "try"),
|
||||
TOKEN_DATA(TYPEDEF, "typedef"),
|
||||
TOKEN_DATA(TYPEID, "typeid"),
|
||||
TOKEN_DATA(TYPENAME, "typename"),
|
||||
TOKEN_DATA(UNION, "union"),
|
||||
TOKEN_DATA(UNSIGNED, "unsigned"),
|
||||
TOKEN_DATA(USING, "using"),
|
||||
TOKEN_DATA(VIRTUAL, "virtual"),
|
||||
TOKEN_DATA(VOID, "void"),
|
||||
TOKEN_DATA(VOLATILE, "volatile"),
|
||||
TOKEN_DATA(WCHART, "wchar_t"),
|
||||
TOKEN_DATA(WHILE, "while"),
|
||||
TOKEN_DATA(PP_DEFINE, POUNDDEF PPSPACE "define"),
|
||||
TOKEN_DATA(PP_IF, POUNDDEF PPSPACE "if"),
|
||||
TOKEN_DATA(PP_IFDEF, POUNDDEF PPSPACE "ifdef"),
|
||||
TOKEN_DATA(PP_IFNDEF, POUNDDEF PPSPACE "ifndef"),
|
||||
TOKEN_DATA(PP_ELSE, POUNDDEF PPSPACE "else"),
|
||||
TOKEN_DATA(PP_ELIF, POUNDDEF PPSPACE "elif"),
|
||||
TOKEN_DATA(PP_ENDIF, POUNDDEF PPSPACE "endif"),
|
||||
TOKEN_DATA(PP_ERROR, POUNDDEF PPSPACE "error"),
|
||||
TOKEN_DATA(PP_QHEADER, POUNDDEF PPSPACE \
|
||||
INCLUDEDEF PPSPACE Q("\"") "[^\\n\\r\"]+" Q("\"")),
|
||||
TOKEN_DATA(PP_HHEADER, POUNDDEF PPSPACE \
|
||||
INCLUDEDEF PPSPACE "<" "[^\\n\\r>]+" ">"),
|
||||
TOKEN_DATA(PP_INCLUDE, POUNDDEF PPSPACE \
|
||||
INCLUDEDEF PPSPACE),
|
||||
TOKEN_DATA(PP_LINE, POUNDDEF PPSPACE "line"),
|
||||
TOKEN_DATA(PP_PRAGMA, POUNDDEF PPSPACE "pragma"),
|
||||
TOKEN_DATA(PP_UNDEF, POUNDDEF PPSPACE "undef"),
|
||||
TOKEN_DATA(PP_WARNING, POUNDDEF PPSPACE "warning"),
|
||||
TOKEN_DATA(IDENTIFIER, "([a-zA-Z_]" OR UNIVERSALCHAR ")([a-zA-Z0-9_]" OR UNIVERSALCHAR ")*"),
|
||||
// TOKEN_DATA(OCTALINT, "0" OCTALDIGIT "*" INTEGER_SUFFIX "?"),
|
||||
// TOKEN_DATA(DECIMALINT, "[1-9]" DIGIT "*" INTEGER_SUFFIX "?"),
|
||||
// TOKEN_DATA(HEXAINT, "(0x|0X)" HEXDIGIT "+" INTEGER_SUFFIX "?"),
|
||||
TOKEN_DATA(INTLIT, "(" "(0x|0X)" HEXDIGIT "+" OR "0" OCTALDIGIT "*" OR \
|
||||
"[1-9]" DIGIT "*" ")" INTEGER_SUFFIX "?"),
|
||||
TOKEN_DATA(FLOATLIT,
|
||||
"(" DIGIT "*" Q(".") DIGIT "+" OR DIGIT "+" Q(".") ")"
|
||||
EXPONENT "?" FLOAT_SUFFIX "?" OR
|
||||
DIGIT "+" EXPONENT FLOAT_SUFFIX "?"),
|
||||
TOKEN_DATA(CCOMMENT, CCOMMENT),
|
||||
TOKEN_DATA(CPPCOMMENT, Q("/") Q("/[^\\n\\r]*") NEWLINEDEF ),
|
||||
TOKEN_DATA(CHARLIT, CHAR_SPEC "'"
|
||||
"(" ESCAPESEQ OR "[^\\n\\r']" OR UNIVERSALCHAR ")+" "'"),
|
||||
TOKEN_DATA(STRINGLIT, CHAR_SPEC Q("\"")
|
||||
"(" ESCAPESEQ OR "[^\\n\\r\"]" OR UNIVERSALCHAR ")*" Q("\"")),
|
||||
TOKEN_DATA(SPACE, BLANK "+"),
|
||||
TOKEN_DATA(SPACE2, "[\\v\\f]+"),
|
||||
TOKEN_DATA(CONTLINE, Q("\\") "\\n"),
|
||||
TOKEN_DATA(NEWLINE, NEWLINEDEF),
|
||||
TOKEN_DATA(POUND_POUND, "##"),
|
||||
TOKEN_DATA(POUND_POUND_ALT, Q("%:") Q("%:")),
|
||||
TOKEN_DATA(POUND_POUND_TRIGRAPH, TRI("=") TRI("=")),
|
||||
TOKEN_DATA(POUND, "#"),
|
||||
TOKEN_DATA(POUND_ALT, Q("%:")),
|
||||
TOKEN_DATA(POUND_TRIGRAPH, TRI("=")),
|
||||
TOKEN_DATA(ANY, "."),
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
TOKEN_DATA(MSEXT_INT8, "__int8"),
|
||||
TOKEN_DATA(MSEXT_INT16, "__int16"),
|
||||
TOKEN_DATA(MSEXT_INT32, "__int32"),
|
||||
TOKEN_DATA(MSEXT_INT64, "__int64"),
|
||||
TOKEN_DATA(MSEXT_BASED, "_?" "_based"),
|
||||
TOKEN_DATA(MSEXT_DECLSPEC, "_?" "_declspec"),
|
||||
TOKEN_DATA(MSEXT_CDECL, "_?" "_cdecl"),
|
||||
TOKEN_DATA(MSEXT_FASTCALL, "_?" "_fastcall"),
|
||||
TOKEN_DATA(MSEXT_STDCALL, "_?" "_stdcall"),
|
||||
TOKEN_DATA(MSEXT_TRY , "__try"),
|
||||
TOKEN_DATA(MSEXT_EXCEPT, "__except"),
|
||||
TOKEN_DATA(MSEXT_FINALLY, "__finally"),
|
||||
TOKEN_DATA(MSEXT_LEAVE, "__leave"),
|
||||
TOKEN_DATA(MSEXT_INLINE, "_?" "_inline"),
|
||||
TOKEN_DATA(MSEXT_ASM, "_?" "_asm"),
|
||||
TOKEN_DATA(MSEXT_PP_REGION, POUNDDEF PPSPACE "region"),
|
||||
TOKEN_DATA(MSEXT_PP_ENDREGION, POUNDDEF PPSPACE "endregion"),
|
||||
#endif // BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
{ token_id(0) } // this should be the last entry
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// C++ only token definitions
|
||||
template <typename IteratorT, typename PositionT>
|
||||
typename lexer<IteratorT, PositionT>::lexer_data const
|
||||
lexer<IteratorT, PositionT>::init_data_cpp[] =
|
||||
{
|
||||
TOKEN_DATA(AND_ALT, "bitand"),
|
||||
TOKEN_DATA(ANDAND_ALT, "and"),
|
||||
TOKEN_DATA(ANDASSIGN_ALT, "and_eq"),
|
||||
TOKEN_DATA(OR_ALT, "bitor"),
|
||||
TOKEN_DATA(ORASSIGN_ALT, "or_eq"),
|
||||
TOKEN_DATA(OROR_ALT, "or"),
|
||||
TOKEN_DATA(XOR_ALT, "xor"),
|
||||
TOKEN_DATA(XORASSIGN_ALT, "xor_eq"),
|
||||
TOKEN_DATA(NOT_ALT, "not"),
|
||||
TOKEN_DATA(NOTEQUAL_ALT, "not_eq"),
|
||||
TOKEN_DATA(COMPL_ALT, "compl"),
|
||||
TOKEN_DATA(ARROWSTAR, Q("->") Q("*")),
|
||||
TOKEN_DATA(DOTSTAR, Q(".") Q("*")),
|
||||
TOKEN_DATA(COLON_COLON, "::"),
|
||||
{ token_id(0) } // this should be the last entry
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// undefine macros, required for regular expression definitions
|
||||
#undef INCLUDEDEF
|
||||
#undef POUNDDEF
|
||||
#undef CCOMMENT
|
||||
#undef PPSPACE
|
||||
#undef DIGIT
|
||||
#undef OCTALDIGIT
|
||||
#undef HEXDIGIT
|
||||
#undef SIGN
|
||||
#undef EXPONENT
|
||||
#undef INTEGER_SUFFIX
|
||||
#undef FLOAT_SUFFIX
|
||||
#undef CHAR_SPEC
|
||||
#undef BACKSLASH
|
||||
#undef ESCAPESEQ
|
||||
#undef HEXQUAD
|
||||
#undef UNIVERSALCHAR
|
||||
|
||||
#undef Q
|
||||
#undef TRI
|
||||
#undef OR
|
||||
|
||||
#undef TOKEN_DATA
|
||||
#undef TOKEN_DATA_EX
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// initialize cpp lexer with token data
|
||||
template <typename IteratorT, typename PositionT>
|
||||
inline
|
||||
lexer<IteratorT, PositionT>::lexer()
|
||||
: base_t(NUM_LEXER_STATES)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
inline void
|
||||
lexer<IteratorT, PositionT>::init_dfa(boost::wave::language_support lang)
|
||||
{
|
||||
if (has_compiled_dfa())
|
||||
return;
|
||||
|
||||
for (int i = 0; 0 != init_data[i].tokenid; ++i) {
|
||||
this->register_regex(init_data[i].tokenregex, init_data[i].tokenid,
|
||||
init_data[i].tokencb, init_data[i].lexerstate);
|
||||
}
|
||||
|
||||
// if in C99 mode, some of the keywords are not valid
|
||||
if (!boost::wave::need_c99(lang)) {
|
||||
for (int j = 0; 0 != init_data_cpp[j].tokenid; ++j) {
|
||||
this->register_regex(init_data_cpp[j].tokenregex,
|
||||
init_data_cpp[j].tokenid, init_data_cpp[j].tokencb,
|
||||
init_data_cpp[j].lexerstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get time of last compilation of this file
|
||||
template <typename IteratorT, typename PositionT>
|
||||
boost::wave::util::time_conversion_helper
|
||||
lexer<IteratorT, PositionT>::compilation_time(__DATE__ " " __TIME__);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template <typename IteratorT, typename PositionT>
|
||||
inline void
|
||||
init_lexer (lexer<IteratorT, PositionT> &lexer,
|
||||
boost::wave::language_support language, bool force_reinit = false)
|
||||
{
|
||||
if (lexer.has_compiled_dfa())
|
||||
return; // nothing to do
|
||||
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
using std::ios;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
ifstream dfa_in("wave_slex_lexer.dfa", ios::in|ios::binary);
|
||||
|
||||
lexer.init_dfa(language);
|
||||
if (force_reinit || !dfa_in.is_open() ||
|
||||
!lexer.load (dfa_in, (long)lexer.get_compilation_time()))
|
||||
{
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
cerr << "Compiling regular expressions for slex ...";
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
dfa_in.close();
|
||||
lexer.create_dfa();
|
||||
|
||||
ofstream dfa_out ("wave_slex_lexer.dfa", ios::out|ios::binary|ios::trunc);
|
||||
|
||||
if (dfa_out.is_open())
|
||||
lexer.save (dfa_out, (long)lexer.get_compilation_time());
|
||||
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
cerr << " Done." << endl;
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lex_functor
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename IteratorT, typename PositionT = wave::util::file_position_type>
|
||||
class slex_functor
|
||||
: public slex_input_interface<typename lexer<IteratorT, PositionT>::token_type>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::wave::util::position_iterator<IteratorT, PositionT>
|
||||
iterator_type;
|
||||
typedef typename std::iterator_traits<IteratorT>::value_type char_t;
|
||||
typedef BOOST_WAVE_STRINGTYPE string_type;
|
||||
typedef typename lexer<IteratorT, PositionT>::token_type token_type;
|
||||
|
||||
slex_functor(IteratorT const &first_, IteratorT const &last_,
|
||||
PositionT const &pos_, boost::wave::language_support language)
|
||||
: first(first_, last_, pos_), at_eof(false)
|
||||
{
|
||||
// initialize lexer dfa tables
|
||||
init_lexer(lexer, language);
|
||||
}
|
||||
virtual ~slex_functor() {}
|
||||
|
||||
// get the next token from the input stream
|
||||
token_type get()
|
||||
{
|
||||
token_type token;
|
||||
|
||||
if (!at_eof) {
|
||||
do {
|
||||
// generate and return the next token
|
||||
std::string value;
|
||||
PositionT pos = first.get_position(); // begin of token position
|
||||
token_id id = token_id(lexer.next_token(first, last, &value));
|
||||
|
||||
if ((token_id)(-1) == id)
|
||||
id = T_EOF; // end of input reached
|
||||
|
||||
string_type token_val(value.c_str());
|
||||
|
||||
if (T_CONTLINE != id) {
|
||||
switch (id) {
|
||||
case T_IDENTIFIER:
|
||||
// test identifier characters for validity (throws if
|
||||
// invalid chars found)
|
||||
using boost::wave::cpplexer::impl::validate_identifier_name;
|
||||
validate_identifier_name(token_val,
|
||||
pos.get_line(), pos.get_column(), pos.get_file());
|
||||
break;
|
||||
|
||||
case T_STRINGLIT:
|
||||
case T_CHARLIT:
|
||||
// test literal characters for validity (throws if invalid
|
||||
// chars found)
|
||||
using boost::wave::cpplexer::impl::validate_literal;
|
||||
validate_literal(token_val,
|
||||
pos.get_line(), pos.get_column(), pos.get_file());
|
||||
break;
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
case T_PP_HHEADER:
|
||||
case T_PP_QHEADER:
|
||||
case T_PP_INCLUDE:
|
||||
// convert to the corresponding ..._next token, if appropriate
|
||||
if (string_type::npos != value.find("include_"))
|
||||
id = token_id(id | AltTokenType);
|
||||
break;
|
||||
#endif // BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
|
||||
case T_EOF:
|
||||
// T_EOF is returned as a valid token, the next call will
|
||||
// return T_EOI, i.e. the actual end of input
|
||||
at_eof = true;
|
||||
break;
|
||||
}
|
||||
return token_type(id, token_val, pos);
|
||||
}
|
||||
|
||||
// skip the T_CONTLINE token
|
||||
} while (true);
|
||||
}
|
||||
return token; // return T_EOI
|
||||
}
|
||||
void set_position(PositionT const &pos)
|
||||
{ first.set_position(pos); }
|
||||
|
||||
private:
|
||||
iterator_type first;
|
||||
iterator_type last;
|
||||
static lexer<IteratorT, PositionT> lexer; // needed only once
|
||||
|
||||
bool at_eof;
|
||||
};
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
lexer<IteratorT, PositionT> slex_functor<IteratorT, PositionT>::lexer;
|
||||
|
||||
} // namespace slex
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The 'new_lexer' function allows the opaque generation of a new lexer object.
|
||||
// It is coupled to the iterator type to allow to decouple the lexer/iterator
|
||||
// configurations at compile time.
|
||||
//
|
||||
// This function is declared inside the cpp_slex_token.hpp file, which is
|
||||
// referenced by the source file calling the lexer and the source file, which
|
||||
// instantiates the lex_functor. But is is defined here, so it will be
|
||||
// instantiated only while compiling the source file, which instantiates the
|
||||
// lex_functor. While the cpp_slex_token.hpp file may be included everywhere,
|
||||
// this file (cpp_slex_lexer.hpp) should be included only once. This allows
|
||||
// to decouple the lexer interface from the lexer implementation and reduces
|
||||
// compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The new_lexer_gen<>::new_lexer function (declared in cpp_slex_token.hpp)
|
||||
// should be defined inline, if the lex_functor shouldn't be instantiated
|
||||
// separately from the lex_iterator.
|
||||
//
|
||||
// Separate (explicit) instantiation helps to reduce compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_SLEX_NEW_LEXER_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_SLEX_NEW_LEXER_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename IteratorT, typename PositionT>
|
||||
BOOST_WAVE_SLEX_NEW_LEXER_INLINE
|
||||
slex_input_interface<slex_token<PositionT> > *
|
||||
new_lexer_gen<IteratorT, PositionT>::new_lexer(IteratorT const &first,
|
||||
IteratorT const &last, PositionT const &pos,
|
||||
boost::wave::language_support language)
|
||||
{
|
||||
return new slex::slex_functor<IteratorT, PositionT>(first, last, pos,
|
||||
language);
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_SLEX_NEW_LEXER_INLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace cpp_token_sample
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(SLEX_LEXER_HPP_5E8E1DF0_BB41_4938_B7E5_A4BB68222FF6_INCLUDED)
|
||||