2
0
mirror of https://github.com/boostorg/wave.git synced 2026-02-22 15:52:22 +00:00

Added Wave review candidate to repository.

[SVN r1909]
This commit is contained in:
Hartmut Kaiser
2004-01-26 06:23:58 +00:00
parent b683dba9be
commit bb119d710a
140 changed files with 74210 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
# Wave: A Standard compliant C++ preprocessor library
#
# Boost Wave Library Sample Build Jamfile (cpp_tokens)
#
# Copyright (c) 2001-2004 Hartmut Kaiser
# http://spirit.sourceforge.net/
#
# 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)
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)
<vc7.1><*><rtti>off # workaround for compiler bug
:
<runtime-link>static
<threading>single
;

View File

@@ -0,0 +1,28 @@
# Wave: A Standard compliant C++ preprocessor library
#
# Boost Wave Library Sample Build Jamfile (list_includes)
#
# Copyright (c) 2001-2004 Hartmut Kaiser
# http://spirit.sourceforge.net/
#
# 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)
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
:
<vc7.1><*><rtti>off # workaround for compiler bug
:
<runtime-link>static
<threading>single
;

View File

@@ -0,0 +1,132 @@
/*=============================================================================
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.
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "cpp_tokens.hpp" // global configuration
///////////////////////////////////////////////////////////////////////////////
// Include Wave itself
#include <boost/wave.hpp>
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
// The follwoing 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 addition 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_t;
typedef boost::wave::cpp_token_sample::slex_iterator<token_t>
lex_iterator_t;
typedef boost::wave::context<std::string::iterator, lex_iterator_t>
context_t;
// 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_t::iterator_t stream.
context_t ctx (teststr.begin(), teststr.end(), argv[1]);
context_t::iterator_t first = ctx.begin();
context_t::iterator_t last = ctx.end();
context_t::token_t 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;
}

View File

@@ -0,0 +1,39 @@
/*=============================================================================
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.
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#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)

View File

@@ -0,0 +1,226 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: Print out the preprocessed tokens returned by the Wave iterator
Configuration data
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED)
#define CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement macro scopes (#scope/#endscope), variadics,
// placemarkers and well defined token pasting in C++ mode
//
// To implement these features, uncomment the following
//
#define BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS 0
///////////////////////////////////////////////////////////////////////////////
// Define the macro scoping keywords to be used for the experimental macro
// scoping support.
//
// If the following macros aren't defined, the corresponding default value is
// used.
//
//#define BOOST_WAVE_PP_REGION "region"
//#define BOOST_WAVE_PP_REGION_UC "REGION" // uppercase of BOOST_WAVE_PP_REGION
//#define BOOST_WAVE_PP_ENDREGION "endregion"
//#define BOOST_WAVE_PP_IMPORT "import"
///////////////////////////////////////////////////////////////////////////////
// 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.
//
//#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to support variadics and placemarkers
//
// To implement support variadics and placemarkers uncomment the following
//
#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement a #warning directive as
//
// To implement #warning directives, uncomment the following
//
#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #pragma once
//
// To implement #pragma once, uncomment the following
//
#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #include_next
// Please note, that this is an extension to the C++ Standard.
//
// To implement #include_next, uncomment the following
//
#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 0
///////////////////////////////////////////////////////////////////////////////
// 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
#define BOOST_WAVE_SUPPORT_MS_EXTENSIONS 0
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 0
///////////////////////////////////////////////////////////////////////////////
// Allow the #pragma directives to be returned to the caller (optionally after
// preprocessing the body)
//
// Undefining the following will skip #pragma directives, so that the caller
// will not see them.
//
#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 0
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 0
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 0
///////////////////////////////////////////////////////////////////////////////
// Define the string type to be used to store the token values and the file
// names inside a file_position template class
//
// use the following, if you have a fast std::allocator<char>
#define BOOST_WAVE_STRINGTYPE wave::util::flex_string< \
char, std::char_traits<char>, std::allocator<char>, \
wave::util::CowString</*char,*/ \
wave::util::AllocatorStringStorage<char> > \
> \
/**/
#include <boost/wave/util/flex_string.hpp>
///////////////////////////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////////////////////////
// debug rules, subrules and grammars only, for possible flags see
// spirit/debug.hpp
#if defined(BOOST_SPIRIT_DEBUG)
#define BOOST_SPIRIT_DEBUG_FLAGS ( \
BOOST_SPIRIT_DEBUG_FLAGS_NODES | \
BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES \
) \
/**/
///////////////////////////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
//#define BOOST_WAVE_DUMP_PARSE_TREE 1
//#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr
///////////////////////////////////////////////////////////////////////////////
//
// For all #if and #elif directives the preprocessed expressions are printed.
// These expressions are streamed to the std::ostream defined by the
// WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant.
//
// Uncomment the following, if you want to see the preprocessed expressions
//
//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 1
//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr
///////////////////////////////////////////////////////////////////////////////
// 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 files instantiate_slex_lexer.cpp and
// instantiate_re2c_lexer.cpp).
//
// To use the lexer inclusion model, uncomment the following
//
#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1
///////////////////////////////////////////////////////////////////////////////
// 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).
//
// To use the grammar inclusion model, uncomment the following
//
#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1
///////////////////////////////////////////////////////////////////////////////
// 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)
///////////////////////////////////////////////////////////////////////////////
// Now include the cofiguration stuff for the Wave library itself
#include <boost/wave/wave_config.hpp>
#endif // !defined(CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED)

View File

@@ -0,0 +1,45 @@
/*=============================================================================
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
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
See Copyright.txt for full acknowledgements.
=============================================================================*/
#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_t;
template struct boost::wave::grammars::expression_grammar_gen<token_t>;
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0

View File

@@ -0,0 +1,45 @@
/*=============================================================================
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
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
See Copyright.txt for full acknowledgements.
=============================================================================*/
#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<> >
lex_t;
template struct boost::wave::grammars::cpp_grammar_gen<lex_t>;
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0

View File

@@ -0,0 +1,46 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: prints out the preprocessed tokens returned by the pp iterator
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
See Copyright.txt for full acknowledgements.
=============================================================================*/
#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_t;
template struct boost::wave::grammars::intlit_grammar_gen<token_t>;
template struct boost::wave::grammars::chlit_grammar_gen<token_t>;
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0

View File

@@ -0,0 +1,40 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#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<> >
lex_t;
template struct boost::wave::grammars::defined_grammar_gen<lex_t>;
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0

View File

@@ -0,0 +1,48 @@
/*=============================================================================
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
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#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

View File

@@ -0,0 +1,657 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
SLex (Spirit Lex) based C++ lexer
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#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_t;
typedef typename std::iterator_traits<IteratorT>::value_type char_t;
typedef boost::spirit::lexer<iterator_t> base_t;
typedef boost::wave::cpp_token_sample::slex_token<PositionT> token_t;
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
#if BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
static lexer_data const init_data_cpp0x[]; // C++0x only patterns
#endif // BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
// 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"),
#endif // BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
#if BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
TOKEN_DATA(PP_REGION, POUNDDEF PPSPACE BOOST_WAVE_PP_REGION),
TOKEN_DATA(PP_ENDREGION, POUNDDEF PPSPACE BOOST_WAVE_PP_ENDREGION),
TOKEN_DATA(PP_IMPORT, POUNDDEF PPSPACE BOOST_WAVE_PP_IMPORT),
#endif // BOOST_WAVE_ENABLE_CPP0X_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
};
#if BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
///////////////////////////////////////////////////////////////////////////////
// C++0x only token definitions
template <typename IteratorT, typename PositionT>
typename lexer<IteratorT, PositionT>::lexer_data const
lexer<IteratorT, PositionT>::init_data_cpp0x[] =
{
TOKEN_DATA(COMMA_ALT, "__comma__"),
TOKEN_DATA(LEFTPAREN_ALT, "__lparen__"),
TOKEN_DATA(RIGHTPAREN_ALT, "__rparen__"),
{ token_id(0) } // this should be the last entry
};
#endif // BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
///////////////////////////////////////////////////////////////////////////////
// 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)
{
// the modes are mutually exclusive
#if BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
BOOST_ASSERT(!boost::wave::need_c99(lang) || !boost::wave::need_cpp0x(lang));
#endif // BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
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);
}
}
#if BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
// C++0x mode has it's own new keywords
if (boost::wave::need_cpp0x(lang)) {
for (int k = 0; 0 != init_data_cpp0x[k].tokenid; ++k) {
this->register_regex(init_data_cpp0x[k].tokenregex,
init_data_cpp0x[k].tokenid, init_data_cpp0x[k].tokencb,
init_data_cpp0x[k].lexerstate);
}
}
#endif // BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS != 0
}
///////////////////////////////////////////////////////////////////////////////
// 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_t>
class slex_functor
: public slex_input_interface<typename lexer<IteratorT, PositionT>::token_t>
{
public:
typedef boost::wave::util::position_iterator<IteratorT, PositionT>
iterator_t;
typedef typename std::iterator_traits<IteratorT>::value_type char_t;
typedef BOOST_WAVE_STRINGTYPE string_t;
typedef typename lexer<IteratorT, PositionT>::token_t token_t;
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_t get()
{
token_t token;
if (!at_eof) {
do {
// generate and return the next token
std::string value;
PositionT const &pos = first.get_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_t 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_t::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_t(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_t first;
iterator_t 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)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the abstract lexer interface
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(SLEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED)
#define SLEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED
#include <boost/wave/language_support.hpp>
#include <boost/wave/util/file_position.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpp_token_sample {
///////////////////////////////////////////////////////////////////////////////
//
// new_lexer_gen: generates a new instance of the required C++ lexer
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT> struct slex_input_interface;
template <
typename IteratorT,
typename PositionT = boost::wave::util::file_position_t
>
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 slex_input_interface<slex_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 slex_input_interface
{
typedef typename TokenT::position_t position_t;
virtual TokenT get() = 0;
virtual void set_position(position_t const &pos) = 0;
virtual ~slex_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 slex_input_interface *
new_lexer(IteratorT const &first, IteratorT const &last,
position_t const &pos, boost::wave::language_support language)
{
return new_lexer_gen<IteratorT, position_t>::new_lexer (first, last,
pos, language);
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace cpp_token_sample
} // namespace wave
} // namespace boost
#endif // !defined(SLEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED)

View File

@@ -0,0 +1,136 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the lexer iterator
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(SLEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)
#define SLEX_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/language_support.hpp>
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/util/functor_input.hpp>
#include "slex_interface.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpp_token_sample {
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// lex_iterator_functor_shim
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
class slex_iterator_functor_shim
{
public:
template <typename IteratorT>
slex_iterator_functor_shim(IteratorT const &first, IteratorT const &last,
typename TokenT::position_t const &pos,
boost::wave::language_support language)
: functor_ptr(slex_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_t const &pos)
{
BOOST_ASSERT(0 != functor_ptr.get());
functor_ptr->set_position(pos);
}
private:
boost::shared_ptr<slex_input_interface<TokenT> > functor_ptr;
};
///////////////////////////////////////////////////////////////////////////////
// eof token
//template <typename TokenT>
//typename slex_iterator_functor_shim<TokenT>::result_type const
// slex_iterator_functor_shim<TokenT>::eof =
// typename slex_iterator_functor_shim<TokenT>::result_type();
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
//
// slex_iterator
//
// A generic C++ lexer interface class, which allows to plug in different
// lexer implementations (template parameter LexT). The following
// requirement apply:
//
// - the lexer type should have a function implemented, which returnes
// the next lexed token from the input stream:
// typename LexT::token_t 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 and
// a third parameter containing the name of the parsed input file
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
class slex_iterator
: public boost::spirit::multi_pass<
impl::slex_iterator_functor_shim<TokenT>,
boost::wave::util::functor_input
>
{
typedef impl::slex_iterator_functor_shim<TokenT> input_policy_t;
typedef
boost::spirit::multi_pass<input_policy_t,
boost::wave::util::functor_input>
base_t;
typedef slex_iterator<TokenT> self_t;
public:
typedef TokenT token_t;
slex_iterator()
{}
template <typename IteratorT>
slex_iterator(IteratorT const &first, IteratorT const &last,
typename TokenT::position_t const &pos,
boost::wave::language_support language)
: base_t(input_policy_t(first, last, pos, language))
{}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace cpp_token_sample
} // namespace wave
} // namespace boost
#endif // !defined(SLEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)

View File

@@ -0,0 +1,116 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
A generic C++ lexer token definition
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
#define SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED
#include <iomanip>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/language_support.hpp>
#include <boost/wave/util/file_position.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpp_token_sample {
///////////////////////////////////////////////////////////////////////////////
// forward declaration of the token type
template <typename PositionT = boost::wave::util::file_position_t>
class slex_token;
///////////////////////////////////////////////////////////////////////////////
//
// lex_token
//
///////////////////////////////////////////////////////////////////////////////
template <typename PositionT>
class slex_token
{
public:
typedef BOOST_WAVE_STRINGTYPE string_t;
typedef PositionT position_t;
slex_token()
: id(T_EOI)
{}
slex_token(token_id id_, string_t const &value_, PositionT const &pos_)
: id(id_), value(value_), pos(pos_)
{}
// accessors
operator token_id() const { return id; }
string_t const &get_value() const { return value; }
position_t const &get_position() const { return pos; }
void set_token_id (token_id id_) { id = id_; }
void set_value (string_t const &newval) { value = newval; }
void set_position (position_t 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_t get_token_value(lex_token const &t)
{ return t.get_value(); }
#endif
// print support
void print (std::ostream &stream) const
{
using namespace std;
using namespace boost::wave;
stream << setw(16) << left << boost::wave::get_token_name(id) << " ("
<< "(#" << token_id(ID_FROM_TOKEN(*this))
<< ") at " << get_position().get_file() << " ("
<< setw(3) << right << get_position().get_line() << "/"
<< setw(2) << right << get_position().get_column()
<< "): >";
for (size_t i = 0; i < value.size(); ++i) {
switch (value[i]) {
case '\r': stream << "\\r"; break;
case '\n': stream << "\\n"; break;
case '\t': stream << "\\t"; break;
default:
stream << value[i];
break;
}
}
stream << "<";
}
private:
boost::wave::token_id id; // the token id
string_t value; // the text, which was parsed into this token
PositionT pos; // the original file position
};
template <typename PositionT>
inline std::ostream &
operator<< (std::ostream &stream, slex_token<PositionT> const &object)
{
object.print(stream);
return stream;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace cpp_token_sample
} // namespace wave
} // namespace boost
#endif // !defined(SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)

View File

@@ -0,0 +1,26 @@
# Wave: A Standard compliant C++ preprocessor library
#
# Boost Wave Library Sample Build Jamfile (list_includes)
#
# Copyright (c) 2001-2004 Hartmut Kaiser
# http://spirit.sourceforge.net/
#
# 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)
subproject libs/wave/samples/list_includes/build ;
exe list_includes
: ../list_includes.cpp
<lib>../../../build/boost_wave
<lib>../../../../../libs/program_options/build/boost_program_options
<lib>../../../../../libs/filesystem/build/boost_filesystem
:
<sysinclude>$(BOOST_ROOT)
<vc7.1><*><rtti>off # workaround for compiler bug
:
<runtime-link>static
<threading>single
;

View File

@@ -0,0 +1,23 @@
# Wave: A Standard compliant C++ preprocessor library
#
# Boost Wave Library Sample Build Jamfile (list_includes)
#
# Copyright (c) 2001-2004 Hartmut Kaiser
# http://spirit.sourceforge.net/
#
# 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)
exe list_includes
: ../list_includes.cpp
<lib>../../../build/boost_wave
<lib>../../../../../libs/program_options/build/boost_program_options
<lib>../../../../../libs/filesystem/build/boost_filesystem
:
<vc7.1><*><rtti>off # workaround for compiler bug
:
<runtime-link>static
<threading>single
;

View File

@@ -0,0 +1,286 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: List include dependencies of a given source file
The 'list_includes' sample shows a simple way, how to use the Wave C++
preprocessor library to extract a list of included files from a given
source file.
To get a hint which commandline options are supported, call it with the
--help option.
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "list_includes.hpp" // config data
///////////////////////////////////////////////////////////////////////////////
// include required boost libraries
#include <boost/assert.hpp>
///////////////////////////////////////////////////////////////////////////////
// This sample requires the program_options library written by Vladimir Prus,
// which is currently under Boost review.
// It is available here: http://boost-sandbox.sourceforge.net/program_options
//
#include <boost/program_options.hpp>
///////////////////////////////////////////////////////////////////////////////
// Include Wave itself
#include <boost/wave.hpp>
//#include <boost/wave/util/time_conversion_helper.hpp>
//#include <boost/wave/util/file_position.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include <boost/wave/cpplexer/cpp_lex_iterator.hpp>
#include <boost/wave/trace_policies.hpp>
#include <boost/wave/cpp_context.hpp>
///////////////////////////////////////////////////////////////////////////////
// include lexer specifics, import lexer names
#if !defined(BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION)
#include <boost/wave/cpplexer/re2clex/cpp_re2c_lexer.hpp>
#endif // !defined(BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION)
///////////////////////////////////////////////////////////////////////////////
// import required names
using namespace boost::spirit;
using std::string;
using std::vector;
using std::set;
using std::cout;
using std::cerr;
using std::endl;
using std::ifstream;
using std::ostream;
using std::istreambuf_iterator;
namespace po = boost::program_options;
///////////////////////////////////////////////////////////////////////////////
// print the current version
int print_version()
{
// get time of last compilation of this file
boost::wave::util::time_conversion_helper compilation_time(__DATE__ " " __TIME__);
// calculate the number of days since Jan 29 2003
// (the day the list_includes project was started)
std::tm first_day;
std::memset (&first_day, 0, sizeof(std::tm));
first_day.tm_mon = 0; // Jan
first_day.tm_mday = 29; // 29
first_day.tm_year = 103; // 2003
long seconds = long(std::difftime(compilation_time.get_time(),
std::mktime(&first_day)));
cout
<< LIST_INCLUDES_VERSION_MAJOR << '.'
<< LIST_INCLUDES_VERSION_MINOR << '.'
<< LIST_INCLUDES_VERSION_SUBMINOR << '.'
<< seconds/(3600*24); // get number of days from seconds
return 1; // exit app
}
///////////////////////////////////////////////////////////////////////////////
// policy class
struct trace_include_files
: public boost::wave::trace_policies::default_tracing
{
trace_include_files(set<string> &files_) : files(files_) {}
void
opened_include_file(string const &filename,
std::size_t include_depth, bool is_system_include)
{
set<string>::iterator it = files.find(filename);
if (it == files.end()) {
// print indented filename
for (size_t i = 0; i < include_depth; ++i)
cout << " ";
cout << filename << endl;
files.insert(filename);
}
}
set<string> &files;
};
///////////////////////////////////////////////////////////////////////////////
//
int do_actual_work (
po::options_and_arguments const opts, po::variables_map const &vm,
vector<string> const &pathes, vector<string> const &syspathes)
{
// current file position is saved for exception handling
boost::wave::util::file_position_t current_position;
try {
vector<string> const &arguments = opts.arguments();
vector<string>::const_iterator lastfile = arguments.end();
for (vector<string>::const_iterator file_it = arguments.begin();
file_it != lastfile; ++file_it)
{
ifstream instream((*file_it).c_str());
string instring;
if (!instream.is_open()) {
cerr << "Could not open input file: " << *file_it << endl;
continue;
}
instream.unsetf(ios::skipws);
instring = string(istreambuf_iterator<char>(instream.rdbuf()),
istreambuf_iterator<char>());
// The template boost::wave::cpplexer::lex_token<> is the token type to be
// used by the Wave library.
typedef boost::wave::cpplexer::lex_iterator<
boost::wave::cpplexer::lex_token<> >
lex_iterator_t;
typedef boost::wave::context<
std::string::iterator, lex_iterator_t,
boost::wave::iteration_context_policies::load_file_to_string,
trace_include_files
> context_t;
set<string> files;
trace_include_files trace(files);
// The preprocessor iterator shouldn't be constructed directly. It is
// to be generated through a wave::context<> object. This wave:context<>
// 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_t::iterator_t stream.
context_t ctx (instring.begin(), instring.end(), (*file_it).c_str(), trace);
// add include directories to the include path
if (vm.count("path")) {
vector<string>::const_iterator end = pathes.end();
for (vector<string>::const_iterator cit = pathes.begin();
cit != end; ++cit)
{
ctx.add_include_path((*cit).c_str());
}
}
// add system include directories to the include path
if (vm.count("syspath")) {
vector<string>::const_iterator end = syspathes.end();
for (vector<string>::const_iterator cit = syspathes.begin();
cit != end; ++cit)
{
ctx.add_sysinclude_path((*cit).c_str());
}
}
// analyze the actual file
context_t::iterator_t first = ctx.begin();
context_t::iterator_t last = ctx.end();
cout << "Printing dependency information for: "
<< *file_it << endl;
while (first != last) {
current_position = (*first).get_position();
++first;
}
// prepend endl before next file
cout << endl;
}
}
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_position.get_file()
<< "(" << current_position.get_line() << "): "
<< "exception caught: " << e.what()
<< endl;
return 3;
}
catch (...) {
// use last recognized token to retrieve the error position
cerr
<< current_position.get_file()
<< "(" << current_position.get_line() << "): "
<< "unexpected exception caught." << endl;
return 4;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// here we go!
int
main (int argc, char const *argv[])
{
try {
// analyze the command line options and arguments
vector<string> pathes;
vector<string> syspathes;
po::options_description desc("Usage: list_includes [options] file ...");
desc.add_options()
("help,h", "", "print out program usage (this message)")
("version,v", "", "print the version number")
("path,I", po::parameter<vector<string> >("dir", &pathes),
"specify additional include directory")
("syspath,S", po::parameter<vector<string> >("dir", &syspathes),
"specify additional system include directory")
;
po::options_and_arguments opts = po::parse_command_line(argc, argv, desc);
po::variables_map vm;
po::store(opts, vm, desc);
if (vm.count("help")) {
cout << desc << endl;
return 1;
}
if (vm.count("version")) {
return print_version();
}
// if there is no input file given, then exit
if (0 == opts.arguments().size()) {
cerr << "list_includes: No input file given. "
<< "Use --help to get a hint." << endl;
return 5;
}
// iterate over all given input files
return do_actual_work(opts, vm, pathes, syspathes);
}
catch (std::exception &e) {
cout << "list_includes: exception caught: " << e.what() << endl;
return 6;
}
catch (...) {
cerr << "list_includes: unexpected exception caught." << endl;
return 7;
}
}

View File

@@ -0,0 +1,43 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: List include dependencies of a given source file
Configuration data
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(LIST_INCLUDES_HPP_843DB412_3AA8_4BCF_8081_AA4A5FDE0BE7_INCLUDED)
#define LIST_INCLUDES_HPP_843DB412_3AA8_4BCF_8081_AA4A5FDE0BE7_INCLUDED
///////////////////////////////////////////////////////////////////////////////
// include often used files from the stdlib
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <set>
///////////////////////////////////////////////////////////////////////////////
// include boost config
#include <boost/config.hpp> // global configuration information
///////////////////////////////////////////////////////////////////////////////
// build version
#include "list_includes_version.hpp"
///////////////////////////////////////////////////////////////////////////////
// configure this app here (global configuration constants)
#include "list_includes_config.hpp"
///////////////////////////////////////////////////////////////////////////////
// include required boost libraries
#include <boost/assert.hpp>
#include <boost/pool/pool_alloc.hpp>
#endif // !defined(LIST_INCLUDES_HPP_843DB412_3AA8_4BCF_8081_AA4A5FDE0BE7_INCLUDED)

View File

@@ -0,0 +1,228 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Global application configuration of the list_includes sample
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(LIST_INCLUDES_CONFIG_HPP_0DE80E47_8D50_4DFA_9C1C_0EECAA8A934A_INCLUDED)
#define LIST_INCLUDES_CONFIG_HPP_0DE80E47_8D50_4DFA_9C1C_0EECAA8A934A_INCLUDED
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement macro scopes (#scope/#endscope), variadics,
// placemarkers and well defined token pasting in C++ mode
//
// To implement these features, uncomment the following
//
#define BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS 0
///////////////////////////////////////////////////////////////////////////////
// Define the macro scoping keywords to be used for the experimental macro
// scoping support.
//
// If the following macros aren't defined, the corresponding default value is
// used.
//
// Note, if you change this, you will have to change the corresponding entries
// inside the wave/cpplexer/re2c/cpp.re file too.
//
//#define BOOST_WAVE_PP_REGION "region"
//#define BOOST_WAVE_PP_REGION_UC "REGION" // uppercase of BOOST_WAVE_PP_REGION
//#define BOOST_WAVE_PP_ENDREGION "endregion"
//#define BOOST_WAVE_PP_IMPORT "import"
///////////////////////////////////////////////////////////////////////////////
// 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.
//
//#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to support variadics and placemarkers
//
// To implement support variadics and placemarkers uncomment the following
//
#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement a #warning directive as
//
// To implement #warning directives, uncomment the following
//
#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #pragma once
//
// To implement #pragma once, uncomment the following
//
#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #include_next
// Please note, that this is an extension to the C++ Standard.
//
// To implement #include_next, uncomment the following
//
#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 1
///////////////////////////////////////////////////////////////////////////////
// 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
#define BOOST_WAVE_SUPPORT_MS_EXTENSIONS 0
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1
///////////////////////////////////////////////////////////////////////////////
// Allow the #pragma directives to be returned to the caller (optionally after
// preprocessing the body)
//
// Undefining the following will skip #pragma directives, so that the caller
// will not see them.
//
#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 0
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 0
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 0
///////////////////////////////////////////////////////////////////////////////
// Define the string type to be used to store the token values and the file
// names inside a file_position template class
//
// use the following, if you have a fast std::allocator<char>
#define BOOST_WAVE_STRINGTYPE wave::util::flex_string< \
char, std::char_traits<char>, std::allocator<char>, \
wave::util::CowString</*char,*/ \
wave::util::AllocatorStringStorage<char> > \
> \
/**/
#include <boost/wave/util/flex_string.hpp>
///////////////////////////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////////////////////////
// debug rules, subrules and grammars only, for possible flags see
// spirit/debug.hpp
#if defined(BOOST_SPIRIT_DEBUG)
#define BOOST_SPIRIT_DEBUG_FLAGS ( \
BOOST_SPIRIT_DEBUG_FLAGS_NODES | \
BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES \
) \
/**/
///////////////////////////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
//#define BOOST_WAVE_DUMP_PARSE_TREE 1
//#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr
///////////////////////////////////////////////////////////////////////////////
//
// For all #if and #elif directives the preprocessed expressions are printed.
// These expressions are streamed to the std::ostream defined by the
// WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant.
//
// Uncomment the following, if you want to see the preprocessed expressions
//
//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 1
//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr
///////////////////////////////////////////////////////////////////////////////
// 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 files instantiate_slex_lexer.cpp and
// instantiate_re2c_lexer.cpp).
//
// To use the lexer inclusion model, uncomment the following
//
#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1
///////////////////////////////////////////////////////////////////////////////
// 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).
//
// To use the grammar inclusion model, uncomment the following
//
#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1
///////////////////////////////////////////////////////////////////////////////
// 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)
///////////////////////////////////////////////////////////////////////////////
// Now include the cofiguration stuff for the Wave library itself
#include <boost/wave/wave_config.hpp>
#endif // !defined(LIST_INCLUDES_CONFIG_HPP_0DE80E47_8D50_4DFA_9C1C_0EECAA8A934A_INCLUDED)

View File

@@ -0,0 +1,21 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: List include dependencies of a given source file version number
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(LIST_INCLUDES_VERSION_HPP_FF662D6C_C3E6_4BEC_A062_5D9BD7415EBF_INCLUDED)
#define LIST_INCLUDES_VERSION_HPP_FF662D6C_C3E6_4BEC_A062_5D9BD7415EBF_INCLUDED
#define LIST_INCLUDES_VERSION_MAJOR 0
#define LIST_INCLUDES_VERSION_MINOR 2
#define LIST_INCLUDES_VERSION_SUBMINOR 0
#endif // !defined(LIST_INCLUDES_VERSION_HPP_FF662D6C_C3E6_4BEC_A062_5D9BD7415EBF_INCLUDED)

View File

@@ -0,0 +1,32 @@
# Wave: A Standard compliant C++ preprocessor library
#
# Boost Wave Library Sample Build Jamfile (waveidl)
#
# Copyright (c) 2001-2004 Hartmut Kaiser
# http://spirit.sourceforge.net/
#
# 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)
subproject libs/wave/samples/waveidl/build ;
exe waveidl
: ../idl.cpp
../instantiate_cpp_grammar.cpp
../instantiate_defined_grammar.cpp
../instantiate_predef_macros.cpp
../instantiate_re2c_lexer.cpp
../instantiate_re2c_lexer_string.cpp
../idllexer/idl.re.cpp
<lib>../../../build/boost_wave
<lib>../../../../../libs/program_options/build/boost_program_options
<lib>../../../../../libs/filesystem/build/boost_filesystem
:
<sysinclude>$(BOOST_ROOT)
<vc7.1><*><rtti>off # workaround for compiler bug
:
<runtime-link>static
<threading>single
;

View File

@@ -0,0 +1,29 @@
# Wave: A Standard compliant C++ preprocessor library
#
# Boost Wave Library Sample Build Jamfile (waveidl)
#
# Copyright (c) 2001-2004 Hartmut Kaiser
# http://spirit.sourceforge.net/
#
# 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)
exe waveidl
: ../idl.cpp
../instantiate_cpp_grammar.cpp
../instantiate_defined_grammar.cpp
../instantiate_predef_macros.cpp
../instantiate_re2c_lexer.cpp
../instantiate_re2c_lexer_string.cpp
../idllexer/idl.re.cpp
<lib>../../../build/boost_wave
<lib>../../../../../libs/program_options/build/boost_program_options
<lib>../../../../../libs/filesystem/build/boost_filesystem
:
<vc7.1><*><rtti>off # workaround for compiler bug
:
<runtime-link>static
<threading>single
;

521
samples/waveidl/idl.cpp Normal file
View File

@@ -0,0 +1,521 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "idl.hpp" // global configuration
///////////////////////////////////////////////////////////////////////////////
// This sample requires the program_options library written by Vladimir Prus,
// which is already accepted into Boost, but not included with the
// distribution yet.
// It is available here: http://boost-sandbox.sourceforge.net/program_options.
//
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
///////////////////////////////////////////////////////////////////////////////
// Include Wave itself
#include <boost/wave.hpp>
// Include the lexer related stuff
#include <boost/wave/token_ids.hpp> // token Id's
#include <boost/wave/cpplexer/cpp_lex_token.hpp> // token type
#include "idllexer/idl_lex_iterator.hpp" // lexer type
///////////////////////////////////////////////////////////////////////////////
// include lexer specifics, import lexer names
//
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION == 0
#include "idllexer/idl_re2c_lexer.hpp"
#endif
///////////////////////////////////////////////////////////////////////////////
// include the grammar definitions, if these shouldn't be compiled separately
// (ATTENTION: _very_ large compilation times!)
//
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION == 0
#include <boost/wave/grammars/cpp_intlit_grammar.hpp>
#include <boost/wave/grammars/cpp_chlit_grammar.hpp>
#include <boost/wave/grammars/cpp_grammar.hpp>
#include <boost/wave/grammars/cpp_expression_grammar.hpp>
#include <boost/wave/grammars/cpp_predef_macros_grammar.hpp>
#include <boost/wave/grammars/cpp_defined_grammar.hpp>
#endif
///////////////////////////////////////////////////////////////////////////////
// import required names
using namespace boost::spirit;
using std::string;
using std::pair;
using std::vector;
using std::getline;
using std::ifstream;
using std::cout;
using std::cerr;
using std::endl;
using std::ostream;
using std::istreambuf_iterator;
namespace po = boost::program_options;
namespace fs = boost::filesystem;
///////////////////////////////////////////////////////////////////////////////
// print the current version
int print_version()
{
typedef boost::wave::idllexer::lex_iterator<
boost::wave::cpplexer::lex_token<> >
lex_iterator_t;
typedef boost::wave::context<std::string::iterator, lex_iterator_t>
context_t;
string version (context_t::get_version_string());
cout
<< version.substr(1, version.size()-2) // strip quotes
<< " (" << IDL_VERSION_DATE << ")" // add date
<< endl;
return 0; // exit app
}
///////////////////////////////////////////////////////////////////////////////
// print the copyright statement
int print_copyright()
{
char const *copyright[] = {
"",
"Sample: IDL oriented preprocessor",
"Based on: Wave, A Standard conformant C++ preprocessor library",
"Copyright (c) 2001-2004 Hartmut Kaiser",
"It is hosted by http://spirit.sourceforge.net/.",
"",
"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)",
0
};
for (int i = 0; 0 != copyright[i]; ++i)
cout << copyright[i] << endl;
return 0; // exit app
}
///////////////////////////////////////////////////////////////////////////////
namespace cmd_line_util {
// Additional command line parser which interprets '@something' as an
// option "config-file" with the value "something".
pair<string, string> at_option_parser(string const&s)
{
if ('@' == s[0])
return std::make_pair(string("config-file"), s.substr(1));
else
return pair<string, string>();
}
// class, which keeps include file information from the command line
class include_paths {
public:
include_paths() : seen_separator(false) {}
vector<string> paths; // stores user paths
vector<string> syspaths; // stores system paths
bool seen_separator; // command line contains a '-I-' option
// Function which validates additional tokens from command line.
static void
validate(boost::any &v, vector<string> const &tokens)
{
if (v.empty())
v = boost::any(include_paths());
include_paths *p = boost::any_cast<include_paths>(&v);
BOOST_SPIRIT_ASSERT(p);
// Assume only one path per '-I' occurrence.
string t = tokens[0];
if (t == "-") {
// found -I- option, so switch behaviour
p->seen_separator = true;
}
else if (p->seen_separator) {
// store this path as a system path
p->syspaths.push_back(t);
}
else {
// store this path as an user path
p->paths.push_back(t);
}
}
};
// Workaround for a problem in the program_options library: all options
// stored in a variables_map, which have an assigned validator function
// need an extraction operator.
std::istream& operator>>(std::istream& is, include_paths& p)
{
return is;
}
// Read all options from a given config file, parse and add them to the
// given variables_map
void read_config_file_options(string const &filename,
po::options_description const &desc, po::variables_map &vm,
bool may_fail = false)
{
ifstream ifs(filename.c_str());
if (!ifs.is_open()) {
if (!may_fail) {
cerr << filename
<< ": command line warning: config file not found"
<< endl;
}
return;
}
vector<string> options;
string line;
while (std::getline(ifs, line)) {
// skip empty lines
string::size_type pos = line.find_first_not_of(" \t");
if (pos == string::npos)
continue;
// skip comment lines
if ('#' != line[pos])
options.push_back(line);
}
if (options.size() > 0) {
po::options_and_arguments oa = po::parse_command_line(options, desc);
po::store(oa, vm, desc);
}
}
///////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////
// do the actual preprocessing
int do_actual_work (po::options_and_arguments const opts,
po::variables_map const &vm)
{
// current file position is saved for exception handling
boost::wave::util::file_position_t current_position;
try {
// process the given file
string file_name(opts.arguments().front());
ifstream instream(file_name.c_str());
string instring;
if (!instream.is_open()) {
cerr << "waveidl: could not open input file: " << file_name << endl;
return -1;
}
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
copy (istream_iterator<char>(instream),
istream_iterator<char>(),
inserter(instring, instring.end()));
#else
instring = string(istreambuf_iterator<char>(instream.rdbuf()),
istreambuf_iterator<char>());
#endif
// This sample uses the lex_iterator and lex_token types predefined with
// the Wave library, but it is possible to use your own types.
typedef boost::wave::idllexer::lex_iterator<
boost::wave::cpplexer::lex_token<> >
lex_iterator_t;
typedef boost::wave::context<std::string::iterator, lex_iterator_t>
context_t;
// The C++ preprocessor iterators shouldn't be constructed directly. They
// are to be generated through a boost::wave::context<> object. This
// boost::wave::context 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_t::iterator_t stream.
context_t ctx (instring.begin(), instring.end(), file_name.c_str());
// add include directories to the system include search paths
if (vm.count("sysinclude")) {
vector<string> syspaths = vm["sysinclude"].as<vector<string> >();
vector<string>::const_iterator end = syspaths.end();
for (vector<string>::const_iterator cit = syspaths.begin();
cit != end; ++cit)
{
ctx.add_sysinclude_path((*cit).c_str());
}
}
// add include directories to the include search paths
if (vm.count("include")) {
cmd_line_util::include_paths const &ip =
vm["include"].as<cmd_line_util::include_paths>();
vector<string>::const_iterator end = ip.paths.end();
for (vector<string>::const_iterator cit = ip.paths.begin();
cit != end; ++cit)
{
ctx.add_include_path((*cit).c_str());
}
// if on the command line was given -I- , this has to be propagated
if (ip.seen_separator)
ctx.set_sysinclude_delimiter();
// add system include directories to the include path
vector<string>::const_iterator sysend = ip.syspaths.end();
for (vector<string>::const_iterator syscit = ip.syspaths.begin();
syscit != sysend; ++syscit)
{
ctx.add_sysinclude_path((*syscit).c_str());
}
}
// add additional defined macros
if (vm.count("define")) {
vector<string> macros = vm["define"].as<vector<string> >();
vector<string>::const_iterator end = macros.end();
for (vector<string>::const_iterator cit = macros.begin();
cit != end; ++cit)
{
ctx.add_macro_definition(*cit);
}
}
// add additional predefined macros
if (vm.count("predefine")) {
vector<string> predefmacros = vm["predefine"].as<vector<string> >();
vector<string>::const_iterator end = predefmacros.end();
for (vector<string>::const_iterator cit = predefmacros.begin();
cit != end; ++cit)
{
ctx.add_macro_definition(*cit, true);
}
}
// undefine specified macros
if (vm.count("undefine")) {
vector<string> undefmacros = vm["undefine"].as<vector<string> >();
vector<string>::const_iterator end = undefmacros.end();
for (vector<string>::const_iterator cit = undefmacros.begin();
cit != end; ++cit)
{
ctx.remove_macro_definition((*cit).c_str(), true);
}
}
// open the output file
std::ofstream output;
if (vm.count("output")) {
// try to open the file, where to put the preprocessed output
string out_file (vm["output"].as<string>());
output.open(out_file.c_str());
if (!output.is_open()) {
cerr << "waveidl: could not open output file: " << out_file
<< endl;
return -1;
}
}
else {
// output the preprocessed result to std::cout
output.copyfmt(cout);
output.clear(cout.rdstate());
static_cast<std::basic_ios<char> &>(output).rdbuf(cout.rdbuf());
}
// analyze the input file
context_t::iterator_t first = ctx.begin();
context_t::iterator_t last = ctx.end();
// loop over all generated tokens outputing the generated text
while (first != last) {
// print out the string representation of this token (skip comments)
using namespace boost::wave;
// store the last known good token position
current_position = (*first).get_position();
token_id id = token_id(*first);
if (T_CPPCOMMENT == id || T_NEWLINE == id) {
// C++ comment tokens contain the trailing newline
output << endl;
}
else if (id != T_CCOMMENT) {
// print out the current token value
output << (*first).get_value();
}
++first; // advance to the next token
}
}
catch (boost::wave::cpp_exception &e) {
// some preprocessing error
cerr
<< e.file_name() << "(" << e.line_no() << "): "
<< e.description() << endl;
return 1;
}
catch (boost::wave::cpplexer::lexing_exception &e) {
// some lexing 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_position.get_file()
<< "(" << current_position.get_line() << "): "
<< "exception caught: " << e.what()
<< endl;
return 3;
}
catch (...) {
// use last recognized token to retrieve the error position
cerr
<< current_position.get_file()
<< "(" << current_position.get_line() << "): "
<< "unexpected exception caught." << endl;
return 4;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// main entry point
int
main (int argc, char const *argv[])
{
try {
// analyze the command line options and arguments
vector<string> cfg_files;
// declare the options allowed from the command line only
po::options_description desc_cmdline ("Options allowed on the command line only");
desc_cmdline.add_options()
("help,h", "", "print out program usage (this message)")
("version,v", "", "print the version number")
("copyright,c", "", "print out the copyright statement")
("config-file", po::parameter("filepath", &cfg_files),
"specify a config file (alternatively: @filepath)")
;
// declare the options allowed on command line and in config files
po::options_description desc_generic ("Options allowed additionally in a config file");
desc_generic.add_options()
("output,o", "path", "specify a file to use for output instead of stdout")
("include,I", "path", "specify an additional include directory").
validator(&cmd_line_util::include_paths::validate)
("sysinclude,S", po::parameter<vector<string> >("syspath"),
"specify an additional system include directory")
("define,D", po::parameter<vector<string> >("macro[=[value]]"),
"specify a macro to define")
("predefine,P", po::parameter<vector<string> >("macro[=[value]]"),
"specify a macro to predefine")
("undefine,U", po::parameter<vector<string> >("macro"),
"specify a macro to undefine")
;
// combine the options for the different usage schemes
po::options_description desc_overall_cmdline;
desc_overall_cmdline.add(desc_cmdline);
desc_overall_cmdline.add(desc_generic);
po::options_description desc_overall_cfgfile;
desc_overall_cfgfile.add(desc_generic);
// parse command line and store results
po::options_and_arguments opts = po::parse_command_line(argc, argv,
desc_overall_cmdline, 0, cmd_line_util::at_option_parser);
po::variables_map vm;
po::store(opts, vm, desc_overall_cmdline);
// Try to find a waveidl.cfg in the same directory as the executable was
// started from. If this exists, treat it as a wave config file
fs::path filename(argv[0], fs::native);
filename = filename.branch_path() / "waveidl.cfg";
cmd_line_util::read_config_file_options(filename.string(),
desc_overall_cfgfile, vm, true);
// if there is specified at least one config file, parse it and add the
// options to the main variables_map
if (vm.count("config-file")) {
vector<string>::const_iterator end = cfg_files.end();
for (vector<string>::const_iterator cit = cfg_files.begin();
cit != end; ++cit)
{
// parse a single config file and store the results
cmd_line_util::read_config_file_options(*cit,
desc_overall_cfgfile, vm);
}
}
// ... act as required
if (vm.count("help")) {
po::options_description desc_help (
"Usage: waveidl [options] [@config-file(s)] file");
desc_help.add(desc_cmdline);
desc_help.add(desc_generic);
cout << desc_help << endl;
return 1;
}
if (vm.count("version")) {
return print_version();
}
if (vm.count("copyright")) {
return print_copyright();
}
// if there is no input file given, then exit
if (0 == opts.arguments().size()) {
cerr << "waveidl: no input file given, "
<< "use --help to get a hint." << endl;
return 5;
}
// preprocess the given input file
return do_actual_work(opts, vm);
}
catch (std::exception &e) {
cout << "waveidl: exception caught: " << e.what() << endl;
return 6;
}
catch (...) {
cerr << "waveidl: unexpected exception caught." << endl;
return 7;
}
}

46
samples/waveidl/idl.hpp Normal file
View File

@@ -0,0 +1,46 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(IDL_HPP_FC7EE131_5CE9_43F2_A713_8D9BBC3C8477_INCLUDED)
#define IDL_HPP_FC7EE131_5CE9_43F2_A713_8D9BBC3C8477_INCLUDED
///////////////////////////////////////////////////////////////////////////////
// This file may be used as a precompiled header (if applicable)
///////////////////////////////////////////////////////////////////////////////
// include often used files from the stdlib
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
///////////////////////////////////////////////////////////////////////////////
// include boost config
#include <boost/config.hpp> // global configuration information
///////////////////////////////////////////////////////////////////////////////
// build version
#include "idl_version.hpp"
///////////////////////////////////////////////////////////////////////////////
// configure this app here (global configuration constants)
#include "idl_config.hpp"
///////////////////////////////////////////////////////////////////////////////
// include required boost libraries
#include <boost/assert.hpp>
#include <boost/pool/pool_alloc.hpp>
#endif // !defined(IDL_HPP_FC7EE131_5CE9_43F2_A713_8D9BBC3C8477_INCLUDED)

View File

@@ -0,0 +1,207 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Global application configuration of the Wave driver command
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(IDL_CONFIG_HPP_012D7524_FF3F_482F_9123_91966C72F4EA_INCLUDED)
#define IDL_CONFIG_HPP_012D7524_FF3F_482F_9123_91966C72F4EA_INCLUDED
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement macro scopes (#scope/#endscope), variadics,
// placemarkers and well defined token pasting in C++ mode
//
// To implement these features, uncomment the following
//
#define BOOST_WAVE_ENABLE_CPP0X_EXTENSIONS 0
///////////////////////////////////////////////////////////////////////////////
// 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.
//
//#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to support variadics and placemarkers
//
// To implement support variadics and placemarkers uncomment the following
//
#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement a #warning directive as
//
// To implement #warning directives, uncomment the following
//
#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #pragma once
//
// To implement #pragma once, uncomment the following
//
#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 0
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #include_next
// Please note, that this is an extension to the C++ Standard.
//
// To implement #include_next, uncomment the following
//
#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 0
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1
///////////////////////////////////////////////////////////////////////////////
// Allow the #pragma directives to be returned to the caller (optionally after
// preprocessing the body)
//
// Undefining the following will skip #pragma directives, so that the caller
// will not see them.
//
#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 1
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 1
///////////////////////////////////////////////////////////////////////////////
// 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
//
#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 1
///////////////////////////////////////////////////////////////////////////////
// Define the string type to be used to store the token values and the file
// names inside a file_position template class
//
// 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< \
boost::wave::util::AllocatorStringStorage<char> > \
> \
/**/
#include <boost/wave/util/flex_string.hpp>
///////////////////////////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////////////////////////
// debug rules, subrules and grammars only, for possible flags see
// spirit/debug.hpp
#if defined(BOOST_SPIRIT_DEBUG)
#define BOOST_SPIRIT_DEBUG_FLAGS ( \
BOOST_SPIRIT_DEBUG_FLAGS_NODES | \
BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES \
) \
/**/
///////////////////////////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////////////////////////
//
// 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 BOOST_WAVE_DUMP_PARSE_TREE_OUT constant.
//
// Uncomment the following, if you want to see these parse trees.
//
//#define BOOST_WAVE_DUMP_PARSE_TREE 1
//#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr
///////////////////////////////////////////////////////////////////////////////
//
// 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
//
//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 1
//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr
///////////////////////////////////////////////////////////////////////////////
// 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 files instantiate_slex_lexer.cpp and
// instantiate_re2c_lexer.cpp).
//
// To use the lexer inclusion model, uncomment the following
//
#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1
///////////////////////////////////////////////////////////////////////////////
// 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).
//
// To use the grammar inclusion model, uncomment the following
//
#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1
///////////////////////////////////////////////////////////////////////////////
// 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)
///////////////////////////////////////////////////////////////////////////////
// Now include the cofiguration stuff for the Wave library itself
#include <boost/wave/wave_config.hpp>
#endif // !defined(IDL_CONFIG_HPP_012D7524_FF3F_482F_9123_91966C72F4EA_INCLUDED)

View File

@@ -0,0 +1,24 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(IDL_VERSION_HPP_780C1190_3107_440B_B303_B687A449749B_INCLUDED)
#define IDL_VERSION_HPP_780C1190_3107_440B_B303_B687A449749B_INCLUDED
#include <boost/wave/wave_version.hpp>
#define IDL_VERSION_MAJOR BOOST_WAVE_VERSION_MAJOR
#define IDL_VERSION_MINOR BOOST_WAVE_VERSION_MINOR
#define IDL_VERSION_SUBMINOR BOOST_WAVE_VERSION_SUBMINOR
#define IDL_VERSION_DATE 20040124L
#endif // !defined(IDL_VERSION_HPP_780C1190_3107_440B_B303_B687A449749B_INCLUDED)

View File

@@ -0,0 +1,561 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL lexer
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <boost/config.hpp>
#if defined(BOOST_HAS_UNISTD_H)
#include <unistd.h>
#else
#include <io.h>
#endif
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
// reuse the token ids and re2c helper functions from the default C++ lexer
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/re2clex/aq.hpp>
#include <boost/wave/cpplexer/re2clex/scanner.hpp>
#include "idl.re.hpp"
#if defined(_MSC_VER) && !defined(__COMO__)
#pragma warning (disable: 4101) // 'foo' : unreferenced local variable
#pragma warning (disable: 4102) // 'foo' : unreferenced label
#if BOOST_WORKAROUND(_MSC_VER, BOOST_TESTED_AT(1310))
// VC upto 7.1 is not able to optimize this file
#pragma optimize("", off)
#endif
#endif
#define BSIZE 196608
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n) {cursor = fill(s, cursor);}
//#define RET(i) {s->cur = cursor; return (i);}
#define RET(i) \
{ \
s->line += count_backslash_newlines(s, cursor); \
s->cur = cursor; \
return (i); \
} \
/**/
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace idllexer {
namespace re2clex {
#define RE2C_ASSERT BOOST_ASSERT
int
get_one_char(boost::wave::cpplexer::re2clex::Scanner *s)
{
using namespace boost::wave::cpplexer::re2clex;
if (s->fd != -1) {
uchar val;
if (read(s->fd, &val, sizeof(val)))
return val;
}
else if (0 != s->act) {
RE2C_ASSERT(s->first != 0 && s->last != 0);
RE2C_ASSERT(s->first <= s->act && s->act <= s->last);
if (s->act < s->last)
return *(s->act)++;
}
return -1;
}
std::ptrdiff_t
rewind_stream (boost::wave::cpplexer::re2clex::Scanner *s, int cnt)
{
if (s->fd != -1) {
return lseek(s->fd, cnt, SEEK_CUR);
}
else if (0 != s->act) {
RE2C_ASSERT(s->first != 0 && s->last != 0);
s->act += cnt;
RE2C_ASSERT(s->first <= s->act && s->act <= s->last);
return s->act - s->first;
}
return 0;
}
std::size_t
get_first_eol_offset(boost::wave::cpplexer::re2clex::Scanner* s)
{
if (!AQ_EMPTY(s->eol_offsets))
{
return s->eol_offsets->queue[s->eol_offsets->head];
}
else
{
return (unsigned int)-1;
}
}
void
adjust_eol_offsets(boost::wave::cpplexer::re2clex::Scanner* s,
std::size_t adjustment)
{
boost::wave::cpplexer::re2clex::aq_queue q;
std::size_t i;
if (!s->eol_offsets)
s->eol_offsets = boost::wave::cpplexer::re2clex::aq_create();
q = s->eol_offsets;
if (AQ_EMPTY(q))
return;
i = q->head;
while (i != q->tail)
{
if (adjustment > q->queue[i])
q->queue[i] = 0;
else
q->queue[i] -= adjustment;
++i;
if (i == q->max_size)
i = 0;
}
if (adjustment > q->queue[i])
q->queue[i] = 0;
else
q->queue[i] -= adjustment;
}
int
count_backslash_newlines(boost::wave::cpplexer::re2clex::Scanner *s,
boost::wave::cpplexer::re2clex::uchar *cursor)
{
using namespace boost::wave::cpplexer::re2clex;
std::size_t diff, offset;
int skipped = 0;
/* figure out how many backslash-newlines skipped over unknowingly. */
diff = cursor - s->bot;
offset = get_first_eol_offset(s);
while (offset <= diff && offset != (unsigned int)-1)
{
skipped++;
boost::wave::cpplexer::re2clex::aq_pop(s->eol_offsets);
offset = get_first_eol_offset(s);
}
return skipped;
}
boost::wave::cpplexer::re2clex::uchar *
fill(boost::wave::cpplexer::re2clex::Scanner *s,
boost::wave::cpplexer::re2clex::uchar *cursor)
{
using namespace boost::wave::cpplexer::re2clex;
if(!s->eof)
{
uchar* p;
std::ptrdiff_t cnt = s->tok - s->bot;
if(cnt)
{
memcpy(s->bot, s->tok, s->lim - s->tok);
s->tok = s->bot;
s->ptr -= cnt;
cursor -= cnt;
s->lim -= cnt;
adjust_eol_offsets(s, cnt);
}
if((s->top - s->lim) < BSIZE)
{
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
if (buf == 0)
{
if (0 != s->error_proc)
(*s->error_proc)(s, "Out of memory!");
else
printf("Out of memory!\n");
/* get the scanner to stop */
*cursor = 0;
return cursor;
}
memcpy(buf, s->tok, s->lim - s->tok);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
cursor = &buf[cursor - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[BSIZE];
free(s->bot);
s->bot = buf;
}
if (s->fd != -1) {
if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE)
{
s->eof = &s->lim[cnt]; *(s->eof)++ = '\0';
}
}
else if (s->act != 0) {
cnt = s->last - s->act;
if (cnt > BSIZE)
cnt = BSIZE;
memcpy(s->lim, s->act, cnt);
s->act += cnt;
if (cnt != BSIZE)
{
s->eof = &s->lim[cnt]; *(s->eof)++ = '\0';
}
}
/* backslash-newline erasing time */
/* first scan for backslash-newline and erase them */
for (p = s->lim; p < s->lim + cnt - 2; ++p)
{
if (*p == '\\')
{
if (*(p+1) == '\n')
{
memmove(p, p + 2, s->lim + cnt - p - 2);
cnt -= 2;
--p;
boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets,
p - s->bot + 1);
}
else if (*(p+1) == '\r')
{
if (*(p+2) == '\n')
{
memmove(p, p + 3, s->lim + cnt - p - 3);
cnt -= 3;
--p;
}
else
{
memmove(p, p + 2, s->lim + cnt - p - 2);
cnt -= 2;
--p;
}
boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets,
p - s->bot + 1);
}
}
}
/* check to see if what we just read ends in a backslash */
if (cnt >= 2)
{
uchar last = s->lim[cnt-1];
uchar last2 = s->lim[cnt-2];
/* check \ EOB */
if (last == '\\')
{
int next = get_one_char(s);
/* check for \ \n or \ \r or \ \r \n straddling the border */
if (next == '\n')
{
--cnt; /* chop the final \, we've already read the \n. */
boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets,
cnt + (s->lim - s->bot));
}
else if (next == '\r')
{
int next2 = get_one_char(s);
if (next2 == '\n')
{
--cnt; /* skip the backslash */
}
else
{
/* rewind one, and skip one char */
rewind_stream(s, -1);
--cnt;
}
boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets,
cnt + (s->lim - s->bot));
}
else if (next != -1) /* -1 means end of file */
{
/* next was something else, so rewind the stream */
lseek(s->fd, -1, SEEK_CUR);
}
}
/* check \ \r EOB */
else if (last == '\r' && last2 == '\\')
{
int next = get_one_char(s);
if (next == '\n')
{
cnt -= 2; /* skip the \ \r */
}
else
{
/* rewind one, and skip two chars */
rewind_stream(s, -1);
cnt -= 2;
}
boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets,
cnt + (s->lim - s->bot));
}
/* check \ \n EOB */
else if (last == '\n' && last2 == '\\')
{
cnt -= 2;
boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets,
cnt + (s->lim - s->bot));
}
}
s->lim += cnt;
if (s->eof) /* eof needs adjusting if we erased backslash-newlines */
{
s->eof = s->lim;
*(s->eof)++ = '\0';
}
}
return cursor;
}
boost::wave::token_id
scan(boost::wave::cpplexer::re2clex::Scanner *s)
{
using namespace boost::wave::cpplexer::re2clex;
uchar *cursor = s->tok = s->cur;
/*!re2c
any = [\t\v\f\r\n\040-\377];
OctalDigit = [0-7];
Digit = [0-9];
HexDigit = [a-fA-F0-9];
ExponentPart = [Ee] [+-]? Digit+;
FractionalConstant = (Digit* "." Digit+) | (Digit+ ".");
FloatingSuffix = [fF][lL]?|[lL][fF]?;
IntegerSuffix = [uU][lL]?|[lL][uU]?;
FixedPointSuffix = [dD];
Backslash = [\\]|"??/";
EscapeSequence = Backslash ([abfnrtv?'"] | Backslash | "x" HexDigit+ | OctalDigit OctalDigit? OctalDigit?);
HexQuad = HexDigit HexDigit HexDigit HexDigit;
UniversalChar = Backslash ("u" HexQuad | "U" HexQuad HexQuad);
PPSpace = ([ \t]|("/*"((any\[*\n\r])*|"*"+(any\[*/\n\r])*|"\n"|"\r"|"\r\n")*"*/"))*;
Pound = "#" | "??=" | "%:";
Newline = "\r\n" | "\n" | "\r";
*/
/*!re2c
"/*" { goto ccomment; }
"//" { goto cppcomment; }
"TRUE" { RET(T_TRUE); }
"FALSE" { RET(T_FALSE); }
"{" { RET(T_LEFTBRACE); }
"}" { RET(T_RIGHTBRACE); }
"[" { RET(T_LEFTBRACKET); }
"]" { RET(T_RIGHTBRACKET); }
"#" { RET(T_POUND); }
"##" { RET(T_POUND_POUND); }
"(" { RET(T_LEFTPAREN); }
")" { RET(T_RIGHTPAREN); }
";" { RET(T_SEMICOLON); }
":" { RET(T_COLON); }
"?" { RET(T_QUESTION_MARK); }
"." { RET(T_DOT); }
"+" { RET(T_PLUS); }
"-" { RET(T_MINUS); }
"*" { RET(T_STAR); }
"/" { RET(T_DIVIDE); }
"%" { RET(T_PERCENT); }
"^" { RET(T_XOR); }
"&" { RET(T_AND); }
"|" { RET(T_OR); }
"~" { RET(T_COMPL); }
"!" { RET(T_NOT); }
"=" { RET(T_ASSIGN); }
"<" { RET(T_LESS); }
">" { RET(T_GREATER); }
"<<" { RET(T_SHIFTLEFT); }
">>" { RET(T_SHIFTRIGHT); }
"==" { RET(T_EQUAL); }
"!=" { RET(T_NOTEQUAL); }
"<=" { RET(T_LESSEQUAL); }
">=" { RET(T_GREATEREQUAL); }
"&&" { RET(T_ANDAND); }
"||" { RET(T_OROR); }
"++" { RET(T_PLUSPLUS); }
"--" { RET(T_MINUSMINUS); }
"," { RET(T_COMMA); }
([a-zA-Z_] | UniversalChar) ([a-zA-Z_0-9] | UniversalChar)*
{ RET(T_IDENTIFIER); }
(("0" [xX] HexDigit+) | ("0" OctalDigit*) | ([1-9] Digit*)) IntegerSuffix?
{ RET(T_INTLIT); }
((FractionalConstant ExponentPart?) | (Digit+ ExponentPart)) FloatingSuffix?
{ RET(T_FLOATLIT); }
(FractionalConstant | Digit+) FixedPointSuffix
{ RET(T_FIXEDPOINTLIT); }
"L"? (['] (EscapeSequence|any\[\n\r\\']|UniversalChar)+ ['])
{ RET(T_CHARLIT); }
"L"? (["] (EscapeSequence|any\[\n\r\\"]|UniversalChar)* ["])
{ RET(T_STRINGLIT); }
Pound PPSpace "include" PPSpace "<" (any\[\n\r>])+ ">"
{ RET(T_PP_HHEADER); }
Pound PPSpace "include" PPSpace "\"" (any\[\n\r"])+ "\""
{ RET(T_PP_QHEADER); }
Pound PPSpace "include" PPSpace
{ RET(T_PP_INCLUDE); }
Pound PPSpace "if" { RET(T_PP_IF); }
Pound PPSpace "ifdef" { RET(T_PP_IFDEF); }
Pound PPSpace "ifndef" { RET(T_PP_IFNDEF); }
Pound PPSpace "else" { RET(T_PP_ELSE); }
Pound PPSpace "elif" { RET(T_PP_ELIF); }
Pound PPSpace "endif" { RET(T_PP_ENDIF); }
Pound PPSpace "define" { RET(T_PP_DEFINE); }
Pound PPSpace "undef" { RET(T_PP_UNDEF); }
Pound PPSpace "line" { RET(T_PP_LINE); }
Pound PPSpace "error" { RET(T_PP_ERROR); }
Pound PPSpace "pragma" { RET(T_PP_PRAGMA); }
Pound PPSpace "warning" { RET(T_PP_WARNING); }
[ \t\v\f]+
{ RET(T_SPACE); }
Newline
{
s->line++;
RET(T_NEWLINE);
}
"\000"
{
if(cursor != s->eof)
{
if (0 != s->error_proc)
(*s->error_proc)(s, "'\\000' in input stream");
else
printf("Error: 0 in file\n");
}
RET(T_EOF);
}
any
{
/* if (0 != s->error_proc)
(*s->error_proc)(s, "Unexpected character: '%c'", *s->tok);
else
printf("unexpected character: '%c'\n", *s->tok);
*/
RET(TOKEN_FROM_ID(*s->tok, UnknownTokenType));
}
*/
ccomment:
/*!re2c
"*/" { RET(T_CCOMMENT); }
Newline
{
/*if(cursor == s->eof) RET(T_EOF);*/
/*s->tok = cursor; */
s->line += count_backslash_newlines(s, cursor) +1;
goto ccomment;
}
any { goto ccomment; }
"\000"
{
yyaccept = 0; /* avoid warning about unreferenced variable */
if(cursor == s->eof)
{
if (s->error_proc)
(*s->error_proc)(s, "Unterminated comment");
else
printf("Error: Unterminated comment\n");
}
else
{
if (s->error_proc)
(*s->error_proc)(s, "'\\000' in input stream");
else
printf("Error: 0 in file");
}
RET(T_EOF);
}
*/
cppcomment:
/*!re2c
Newline
{
/*if(cursor == s->eof) RET(T_EOF); */
/*s->tok = cursor; */
s->line++;
RET(T_CPPCOMMENT);
}
any { goto cppcomment; }
"\000"
{
yyaccept = 0; /* avoid warning about unreferenced variable */
if(cursor != s->eof)
{
if (s->error_proc)
(*s->error_proc)(s, "'\\000' in input stream");
else
printf("Error: 0 in file");
}
/* adjust cursor such next call returns T_EOF */
--YYCURSOR;
/* the comment is unterminated, but nevertheless its a comment */
RET(T_CPPCOMMENT);
}
*/
} /* end of scan */
#undef RE2C_ASSERT
///////////////////////////////////////////////////////////////////////////////
} // namespace re2clex
} // namespace idllexer
} // namespace wave
} // namespace boost

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: Re2C based IDL lexer
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(IDL_RE_HPP_BD62775D_1659_4684_872C_03C02543C9A5_INCLUDED)
#define IDL_RE_HPP_BD62775D_1659_4684_872C_03C02543C9A5_INCLUDED
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace idllexer {
namespace re2clex {
///////////////////////////////////////////////////////////////////////////////
// The scanner function to call whenever a new token is requested
boost::wave::token_id scan(
boost::wave::cpplexer::re2clex::Scanner *s);
///////////////////////////////////////////////////////////////////////////////
} // namespace re2clex
} // namespace idllexer
} // namespace wave
} // namespace boost
#endif // !defined(IDL_RE_HPP_BD62775D_1659_4684_872C_03C02543C9A5_INCLUDED)

View File

@@ -0,0 +1,84 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the abstract lexer interface
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#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 idllexer {
///////////////////////////////////////////////////////////////////////////////
//
// 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_t
>
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<
boost::wave::cpplexer::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_t position_t;
virtual TokenT get() = 0;
virtual void set_position(position_t 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_t const &pos, boost::wave::language_support language)
{
return new_lexer_gen<IteratorT, position_t>::new_lexer (first, last,
pos, language);
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(CPP_LEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED)

View File

@@ -0,0 +1,137 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: Re2C based IDL lexer
Definition of the lexer iterator
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(IDL_LEX_ITERATOR_HPP_7926F865_E02F_4950_9EB5_5F453C9FF953_INCLUDED)
#define IDL_LEX_ITERATOR_HPP_7926F865_E02F_4950_9EB5_5F453C9FF953_INCLUDED
#include <string>
#include <iostream>
#include <boost/assert.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/spirit/iterator/multi_pass.hpp>
#include <boost/wave/language_support.hpp>
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/util/functor_input.hpp>
#include "idl_lex_interface.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace idllexer {
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// lex_iterator_functor_shim
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
class lex_iterator_functor_shim
{
typedef lex_input_interface<TokenT> lex_input_interface_t;
public:
template <typename IteratorT>
lex_iterator_functor_shim(IteratorT const &first, IteratorT const &last,
typename TokenT::position_t const &pos,
boost::wave::language_support language)
: functor_ptr(lex_input_interface_t::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_t const &pos)
{
BOOST_ASSERT(0 != functor_ptr.get());
functor_ptr->set_position(pos);
}
private:
boost::shared_ptr<lex_input_interface_t> 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 (template parameter LexT). The following
// requirement apply:
//
// - the lexer type should have a function implemented, which returnes
// the next lexed token from the input stream:
// typename LexT::token_t 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 and
// a third parameter containing the name of the parsed input file
//
///////////////////////////////////////////////////////////////////////////////
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_t;
typedef
boost::spirit::multi_pass<input_policy_t,
boost::wave::util::functor_input>
base_t;
typedef lex_iterator<TokenT> self_t;
public:
typedef TokenT token_t;
lex_iterator()
{}
template <typename IteratorT>
lex_iterator(IteratorT const &first, IteratorT const &last,
typename TokenT::position_t const &pos,
boost::wave::language_support language)
: base_t(input_policy_t(first, last, pos, language))
{}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace idllexer
} // namespace wave
} // namespace boost
#endif // !defined(IDL_LEX_ITERATOR_HPP_7926F865_E02F_4950_9EB5_5F453C9FF953_INCLUDED)

View File

@@ -0,0 +1,264 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Re2C based IDL lexer
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#if !defined(IDL_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED)
#define IDL_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/token_ids.hpp>
#include <boost/wave/language_support.hpp>
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/cpplexer/validate_universal_char.hpp>
#include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
// reuse the default token type and re2c lexer helpers
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include <boost/wave/cpplexer/cpp_lex_interface.hpp>
#include <boost/wave/cpplexer/re2clex/scanner.hpp>
#include "idl.re.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace idllexer {
namespace re2clex {
///////////////////////////////////////////////////////////////////////////////
//
// encapsulation of the re2c based idl lexer
//
///////////////////////////////////////////////////////////////////////////////
template <
typename IteratorT,
typename PositionT = boost::wave::util::file_position_t
>
class lexer
{
typedef boost::wave::cpplexer::re2clex::Scanner scanner_t;
public:
typedef char char_t;
typedef boost::wave::cpplexer::re2clex::Scanner base_t;
typedef boost::wave::cpplexer::lex_token<PositionT> token_t;
typedef typename token_t::string_t string_t;
lexer(IteratorT const &first, IteratorT const &last,
PositionT const &pos, boost::wave::language_support language);
~lexer();
boost::wave::cpplexer::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_t *s, char *, ...);
private:
static char const *tok_names[];
scanner_t scanner;
string_t filename;
bool at_eof;
};
///////////////////////////////////////////////////////////////////////////////
// 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)
{
using namespace boost::wave::cpplexer::re2clex;
memset(&scanner, '\0', sizeof(scanner_t));
scanner.fd = -1;
scanner.eol_offsets = aq_create();
scanner.first = scanner.act = (uchar *)&(*first);
scanner.last = (uchar *)&(*last);
scanner.line = 1; // start with line_no 1
scanner.error_proc = report_error;
scanner.file_name = filename.c_str();
// not used by the lexer
scanner.enable_ms_extensions = 0;
scanner.act_in_c99_mode = 0;
scanner.act_in_cpp0x_mode = 0;
boost::ignore_unused_variable_warning(language);
}
template <typename IteratorT, typename PositionT>
inline
lexer<IteratorT, PositionT>::~lexer()
{
boost::wave::cpplexer::re2clex::aq_terminate(scanner.eol_offsets);
free(scanner.bot);
}
///////////////////////////////////////////////////////////////////////////////
// get the next token from the input stream
template <typename IteratorT, typename PositionT>
inline boost::wave::cpplexer::lex_token<PositionT>
lexer<IteratorT, PositionT>::get()
{
using namespace boost::wave; // to import token ids to this scope
if (at_eof)
return boost::wave::cpplexer::lex_token<PositionT>(); // return T_EOI
token_id id = token_id(scan(&scanner));
string_t value((char const *)scanner.tok, scanner.cur-scanner.tok);
if (T_IDENTIFIER == id) {
// test identifier characters for validity (throws if invalid chars found)
boost::wave::cpplexer::impl::validate_identifier_name(value,
scanner.line, -1, filename);
}
else if (T_STRINGLIT == id || T_CHARLIT == id) {
// test literal characters for validity (throws if invalid chars found)
boost::wave::cpplexer::impl::validate_literal(value, scanner.line, -1,
filename);
}
else if (T_EOF == id) {
// 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;
}
return boost::wave::cpplexer::lex_token<PositionT>(id, value,
PositionT(filename, scanner.line, -1));
}
template <typename IteratorT, typename PositionT>
inline int
lexer<IteratorT, PositionT>::report_error(scanner_t *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(boost::wave::cpplexer::lexing_exception,
generic_lexing_error, buffer, s->line, -1, s->file_name);
}
///////////////////////////////////////////////////////////////////////////////
//
// lex_functor
//
///////////////////////////////////////////////////////////////////////////////
template <
typename IteratorT,
typename PositionT = boost::wave::util::file_position_t
>
class lex_functor
: public lex_input_interface<typename lexer<IteratorT, PositionT>::token_t>
{
public:
typedef typename lexer<IteratorT, PositionT>::token_t token_t;
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_t get() { return lexer.get(); }
void set_position(PositionT const &pos)
{ lexer.set_position(pos); }
private:
lexer<IteratorT, PositionT> lexer;
};
} // namespace re2clex
///////////////////////////////////////////////////////////////////////////////
//
// 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_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<boost::wave::cpplexer::lex_token<PositionT> > *
new_lexer_gen<IteratorT, PositionT>::new_lexer(IteratorT const &first,
IteratorT const &last, PositionT const &pos,
wave::language_support language)
{
return new re2clex::lex_functor<IteratorT, PositionT>(first, last, pos,
language);
}
#undef BOOST_WAVE_RE2C_NEW_LEXER_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace idllexer
} // namespace wave
} // namespace boost
#endif // !defined(IDL_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED)

View File

@@ -0,0 +1,43 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Explicit instantiation of the cpp_grammar template
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "idl.hpp"
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#include <string>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include "idllexer/idl_lex_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::idllexer::lex_iterator<
boost::wave::cpplexer::lex_token<> >
lex_t;
template struct boost::wave::grammars::cpp_grammar_gen<lex_t>;
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0

View File

@@ -0,0 +1,43 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Explicit instantiation of the defined_grammar template
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "idl.hpp"
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#include <string>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include "idllexer/idl_lex_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::idllexer::lex_iterator<
boost::wave::cpplexer::lex_token<> >
lex_t;
template struct boost::wave::grammars::defined_grammar_gen<lex_t>;
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0

View File

@@ -0,0 +1,43 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Explicit instantiation of the predefined_macros_grammar template
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "idl.hpp"
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#include <string>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include "idllexer/idl_lex_iterator.hpp"
#include <boost/wave/grammars/cpp_predef_macros_grammar.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// Explicit instantiation of the predefined_macros_grammar_gen template
// with the correct token type. This instantiates the corresponding pt_parse
// function, which in turn instantiates the cpp_predefined_macros_grammar
// object (see wave/grammars/cpp_predef_macros_grammar.hpp)
//
///////////////////////////////////////////////////////////////////////////////
typedef boost::wave::idllexer::lex_iterator<
boost::wave::cpplexer::lex_token<> >
lex_t;
template struct boost::wave::grammars::predefined_macros_grammar_gen<lex_t>;
#endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0

View File

@@ -0,0 +1,51 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Explicit instantiation of the lex_functor generation function
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "idl.hpp"
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0
#include <string>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include "idllexer/idl_lex_iterator.hpp"
///////////////////////////////////////////////////////////////////////////////
// The following file needs to be included only once throughout the whole
// program.
#include "idllexer/idl_re2c_lexer.hpp"
///////////////////////////////////////////////////////////////////////////////
//
// This instantiates the correct 'new_lexer' function, which generates the
// C++ lexer used in this sample. You will have to instantiate the
// new_lexer_gen<> template with the same iterator type, as you have used for
// instantiating the boost::wave::context<> object.
//
// 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 first
// parameter supplied while instantiating the boost::wave::context<> template
// (see the file cpp.cpp).
//
///////////////////////////////////////////////////////////////////////////////
template struct boost::wave::idllexer::new_lexer_gen<
BOOST_WAVE_STRINGTYPE::iterator>;
#endif // BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0

View File

@@ -0,0 +1,51 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Sample: IDL oriented preprocessor
Explicit instantiation of the lex_functor generation function
Copyright (c) 2001-2004 Hartmut Kaiser
http://spirit.sourceforge.net/
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)
=============================================================================*/
#include "idl.hpp"
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0
#include <string>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include "idllexer/idl_lex_iterator.hpp"
///////////////////////////////////////////////////////////////////////////////
// The following file needs to be included only once throughout the whole
// program.
#include "idllexer/idl_re2c_lexer.hpp"
///////////////////////////////////////////////////////////////////////////////
//
// If you've used another iterator type as std::string::iterator, you have to
// instantiate the new_lexer_gen<> template for this iterator type too.
// The reason is, that the library internally uses the new_lexer_gen<>
// template with a std::string::iterator. (You just have to undefine the
// following line.)
//
// 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 first
// parameter supplied while instantiating the boost::wave::context<> template
// (see the file cpp.cpp).
//
///////////////////////////////////////////////////////////////////////////////
template struct boost::wave::idllexer::new_lexer_gen<std::string::iterator>;
#endif // BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0