summaryrefslogtreecommitdiff
path: root/modules/CIAO/CCF/CCF/CompilerElements
diff options
context:
space:
mode:
Diffstat (limited to 'modules/CIAO/CCF/CCF/CompilerElements')
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/CompilerElements.mpc7
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/Context.hpp112
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/Diagnostic.hpp192
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/ExH.hpp12
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/FileSystem.hpp33
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/Introspection.cpp26
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/Introspection.hpp12
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.cpp955
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.hpp45
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.cpp57
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.hpp58
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/ReferenceCounting.hpp12
-rw-r--r--modules/CIAO/CCF/CCF/CompilerElements/TokenStream.hpp82
13 files changed, 1603 insertions, 0 deletions
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/CompilerElements.mpc b/modules/CIAO/CCF/CCF/CompilerElements/CompilerElements.mpc
new file mode 100644
index 00000000000..54b81f8c557
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/CompilerElements.mpc
@@ -0,0 +1,7 @@
+//$Id$
+
+project(CompilerElements): cidlc {
+ sharedname =
+ staticname = CompilerElements
+ libout = ..
+}
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/Context.hpp b/modules/CIAO/CCF/CCF/CompilerElements/Context.hpp
new file mode 100644
index 00000000000..fe799e32b48
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/Context.hpp
@@ -0,0 +1,112 @@
+// file : CCF/CompilerElements/Context.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_COMPILER_ELEMENTS_CONTEXT_HPP
+#define CCF_COMPILER_ELEMENTS_CONTEXT_HPP
+
+#include <map>
+#include <string>
+#include <Utility/Hetero/Container.hpp>
+
+namespace CCF
+{
+ namespace CompilerElements
+ {
+ class Context
+ {
+ typedef
+ std::map<std::string, Utility::Hetero::Container>
+ Map;
+
+ public:
+ Context ()
+ {
+ }
+
+ public:
+ class NotFound {};
+ class Typing {};
+
+ Map::size_type
+ count (char const* key) const throw ()
+ {
+ return map_.count (key);
+ }
+
+ template <typename T>
+ T const&
+ get (char const* key) const throw (NotFound, Typing)
+ {
+ Map::const_iterator i = map_.find (key);
+ if (i == map_.end ()) throw NotFound ();
+
+ try
+ {
+ return i->second. template value<T> ();
+ }
+ catch (Utility::Hetero::Typing const&)
+ {
+ throw Typing ();
+ }
+
+ }
+
+ template <typename T>
+ T const&
+ get (char const* key, T const& def) const throw (Typing)
+ {
+ Map::const_iterator i = map_.find (key);
+ if (i == map_.end ()) return def;
+
+ try
+ {
+ return i->second. template value<T> ();
+ }
+ catch (Utility::Hetero::Typing const&)
+ {
+ throw Typing ();
+ }
+ }
+
+ template <typename T>
+ void
+ set (char const* key, T const& value) throw (Typing)
+ {
+ try
+ {
+ if (!map_.insert (std::pair<std::string,
+ Utility::Hetero::Container>(key, value)).second)
+ {
+ Map::iterator i = map_.find (key);
+ i->second.template value <T> () = value;
+ }
+ }
+ catch (Utility::Hetero::Typing const&)
+ {
+ throw Typing ();
+ }
+ }
+
+ void
+ remove (char const* key) throw (NotFound)
+ {
+ Map::iterator i (map_.find (key));
+
+ if (i == map_.end ()) throw NotFound ();
+
+ map_.erase (i);
+ }
+
+ private:
+ Map map_;
+
+ private:
+ // Copy semanic is not supported.
+ Context (Context const&) throw ();
+ Context& operator= (Context const&) throw ();
+ };
+ }
+}
+
+#endif // CCF_COMPILER_ELEMENTS_CONTEXT_HPP
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/Diagnostic.hpp b/modules/CIAO/CCF/CCF/CompilerElements/Diagnostic.hpp
new file mode 100644
index 00000000000..34eb0006b69
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/Diagnostic.hpp
@@ -0,0 +1,192 @@
+// file : CCF/CompilerElements/Diagnostic.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_DIAGNOSTIC_HPP
+#define CCF_DIAGNOSTIC_HPP
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+#include "CCF/CompilerElements/ExH.hpp"
+
+//@@ Should be inside CCF namespace
+
+namespace Diagnostic
+{
+ //
+ //
+ //
+ class Record : public std::ostringstream
+ {
+ public:
+
+ struct Type
+ {
+ enum Value
+ {
+ INFO,
+ WARNING,
+ ERROR
+ };
+ };
+
+ Record (Type::Value type,
+ std::string file,
+ unsigned long line,
+ std::string description = "")
+ : std::ostringstream (description),
+ type_ (type),
+ file_ (file),
+ line_ (line)
+ {
+ }
+
+ public:
+
+ Type::Value
+ type () const
+ {
+ return type_;
+ }
+
+ std::string
+ file () const
+ {
+ return file_;
+ }
+
+ unsigned long line () const
+ {
+ return line_;
+ }
+
+ std::string
+ description () const
+ {
+ return str ();
+ }
+
+ private:
+ Type::Value type_;
+ std::string file_;
+ unsigned long line_;
+ };
+
+
+ //
+ //
+ //
+ struct Info : public Record
+ {
+ Info (std::string file,
+ unsigned long line,
+ std::string description = "")
+ : Record (Type::INFO, file, line, description)
+ {
+ }
+ };
+
+
+ //
+ //
+ //
+ struct Warning : public Record
+ {
+ Warning (std::string file,
+ unsigned long line,
+ std::string description = "")
+ : Record (Type::WARNING, file, line, description)
+ {
+ }
+ };
+
+
+ //
+ //
+ //
+ struct Error : public Record
+ {
+ Error (std::string file,
+ unsigned long line,
+ std::string description = "")
+ : Record (Type::ERROR, file, line, description)
+ {
+ }
+ };
+
+
+ //
+ //
+ //
+ class Stream
+ {
+ public:
+
+ Stream ()
+ : info_count_ (0),
+ warning_count_ (0),
+ error_count_ (0)
+ {
+ }
+
+
+ Stream&
+ operator<< (Record const& msg)
+ {
+ std::cerr << msg.file () << ":" << msg.line () << ": "
+ << msg.description () << std::endl;
+
+ switch (msg.type ())
+ {
+ case Record::Type::INFO:
+ {
+ info_count_++;
+ break;
+ }
+ case Record::Type::WARNING:
+ {
+ warning_count_++;
+ }
+ case Record::Type::ERROR:
+ {
+ error_count_++;
+ }
+ }
+
+ return *this;
+ }
+
+ public:
+ unsigned long
+ info_count ()
+ {
+ return info_count_;
+ }
+
+ unsigned long
+ warning_coun ()
+ {
+ return warning_count_;
+ }
+
+ unsigned long
+ error_count ()
+ {
+ return error_count_;
+ }
+
+ private:
+ unsigned long info_count_;
+ unsigned long warning_count_;
+ unsigned long error_count_;
+
+ private:
+ // Copy semanic is not supported.
+ Stream (Stream const&) throw ();
+ Stream& operator= (Stream const&) throw ();
+ };
+}
+
+#endif // CCF_DIAGNOSTIC_HPP
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/ExH.hpp b/modules/CIAO/CCF/CCF/CompilerElements/ExH.hpp
new file mode 100644
index 00000000000..ad7e1b71950
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/ExH.hpp
@@ -0,0 +1,12 @@
+// file : CCF/CompilerElements/ExH.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_RUNTIME_EX_H_H
+#define CCF_RUNTIME_EX_H_H
+
+#include "Utility/ExH/ExH.hpp"
+
+namespace ExH = Utility::ExH;
+
+#endif // CCF_RUNTIME_EX_H_H
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/FileSystem.hpp b/modules/CIAO/CCF/CCF/CompilerElements/FileSystem.hpp
new file mode 100644
index 00000000000..ba9483f04e6
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/FileSystem.hpp
@@ -0,0 +1,33 @@
+// file : CCF/CompilerElements/FileSystem.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_RUNTIME_FILE_SYSTEM_HPP
+#define CCF_RUNTIME_FILE_SYSTEM_HPP
+
+#include <string>
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/exception.hpp>
+#include <boost/filesystem/operations.hpp>
+
+namespace fs
+{
+ using namespace boost::filesystem;
+
+ inline path
+ normalize (path const& p)
+ {
+ path result;
+
+ for (path::iterator i (p.begin ()), e (p.end ()); i != e; ++i)
+ {
+ if (*i != ".") result /= path (*i, native);
+ }
+
+ return result;
+ }
+}
+
+#endif // CCF_RUNTIME_FILE_SYSTEM_HPP
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/Introspection.cpp b/modules/CIAO/CCF/CCF/CompilerElements/Introspection.cpp
new file mode 100644
index 00000000000..9e625e0272a
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/Introspection.cpp
@@ -0,0 +1,26 @@
+// file : CCF/CompilerElements/Introspection.cpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+//
+// This is a hack to avoid link dependency on Utility library.
+//
+
+#include "Utility/Introspection/Object.hpp"
+
+namespace Utility
+{
+ namespace Introspection
+ {
+ namespace
+ {
+ TypeInfo object_ (typeid (Object));
+ }
+
+ TypeInfo const& Object::
+ static_type_info () throw ()
+ {
+ return object_;
+ }
+ }
+}
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/Introspection.hpp b/modules/CIAO/CCF/CCF/CompilerElements/Introspection.hpp
new file mode 100644
index 00000000000..898e596fa88
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/Introspection.hpp
@@ -0,0 +1,12 @@
+// file : CCF/CompilerElements/Introspection.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_RUNTIME_INTROSPECTION_HPP
+#define CCF_RUNTIME_INTROSPECTION_HPP
+
+#include "Utility/Introspection/Introspection.hpp"
+
+namespace Introspection = Utility::Introspection;
+
+#endif // CCF_RUNTIME_INTROSPECTION_HPP
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.cpp b/modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.cpp
new file mode 100644
index 00000000000..e52750ba74e
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.cpp
@@ -0,0 +1,955 @@
+// file : CCF/CompilerElements/Preprocessor.cpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#include <deque>
+#include <locale>
+#include <string>
+
+#include "CCF/CompilerElements/Preprocessor.hpp"
+
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+using std::string;
+
+namespace CCF
+{
+ namespace CompilerElements
+ {
+ namespace CPP
+ {
+ /*
+ namespace Phase2
+ {
+ class TokenPrototype
+ {
+ public:
+ struct Type
+ {
+ enum Value
+ {
+ punctuation,
+ keyword,
+ identifier
+ eos
+ };
+ };
+
+ TokenPrototype (Type::Value type, string const& lexeme)
+ : type_ (type), lexeme_ (lexeme)
+ {
+ }
+
+ Type::Value
+ type () const
+ {
+ return type_;
+ }
+
+ string
+ lexeme () const
+ {
+ return lexeme_;
+ }
+
+ private:
+ Type::Value type_;
+ string lexeme_;
+ };
+
+ bool
+ operator== (TokenPrototype const& a, TokenPrototype const& b)
+ {
+ return a.type () == b.type () && a.lexeme () == b.lexeme ();
+ }
+
+ class Token : public TokenPrototype
+ {
+ public:
+ Token (Type::Value type,
+ string const& lexeme,
+ unsigned long line)
+ : TokenPrototype (type, lexeme), line_ (line)
+ {
+ }
+
+ unsigned long
+ line () const
+ {
+ return line_;
+ }
+
+ private:
+ unsigned long line_;
+ };
+
+
+ class Scanner : public TokenStream<Token>
+ {
+ public:
+ Scanner (TokenStream<CPP::Token>& is)
+ : is_ (is)
+ {
+ }
+
+ virtual Token
+ next ()
+ {
+ try
+ {
+ InToken t (get_ns ());
+
+ switch (t)
+ {
+ case '#':
+ {
+ return Token (Token::Type::punctuation, "#", t.line ());
+ }
+ case '\n':
+ {
+ return Token (Token::Type::punctuation, "\n", t.line ());
+ }
+ }
+ }
+ catch (EOS const&)
+ {
+ }
+ }
+
+ private:
+ typedef
+ CPP::Token
+ InToken;
+
+ class EOS {};
+
+ InToken
+ get () throw (EOS)
+ {
+ if (ibuffer_.empty ())
+ {
+ InToken t (is_.next ());
+ if (t == InToken::eos) throw EOS ();
+ return t;
+ }
+ else
+ {
+ InToken t (ibuffer_.front ());
+ ibuffer_.pop_front ();
+
+ if (t == InToken::eos) throw EOS ();
+ return t;
+ }
+ }
+
+ // Get first non-space token
+ //
+ InToken
+ get_ns () throw (EOS)
+ {
+ InToken t (get ());
+
+ while (is_space (t)) t = get ();
+ }
+
+ bool
+ is_space (InToken const& t)
+ {
+ return t == ' ' || t == '\t';
+ }
+
+ private:
+ TokenStream<CPP::Token>& is_;
+ std::deque<InTokent> ibuffer_;
+ };
+ }
+ */
+
+ // PreprocessorImpl
+ //
+ //
+ class Preprocessor::PreprocessorImpl : public TokenStream<Token>
+ {
+ public:
+ virtual
+ ~PreprocessorImpl ()
+ {
+ }
+
+ PreprocessorImpl (TokenStream<char>& is, Symbols const& symbols)
+ : loc_ ("C"),
+ state_ (State::preprocessing),
+ ln_ (1),
+ is_ (is),
+ dsa_ (copy_),
+ symbols_ (symbols),
+ balance_ (0),
+ skip_balance_ (0)
+ {
+ }
+
+ virtual Token
+ next ()
+ {
+ while (true)
+ {
+ if (line_.empty ())
+ scan_line ();
+
+ Token t (line_.front ());
+ line_.pop_front ();
+
+ if (skip_balance_ != 0 && t != Token::eos)
+ continue;
+
+ return t;
+ }
+ }
+
+ private:
+
+ // Line-scanning
+ //
+ //
+
+ class DequeStreamAdapter : public TokenStream<Token>
+ {
+ public:
+ DequeStreamAdapter (std::deque<Token>& d)
+ : d_ (d)
+ {
+ }
+
+ virtual Token
+ next ()
+ {
+ Token t (d_.front ());
+ d_.pop_front ();
+ return t;
+ }
+
+ private:
+ std::deque<Token>& d_;
+ };
+
+ void
+ scan_line ()
+ {
+ bool eos (false);
+
+ while (line_.empty () && !eos)
+ {
+ for (;;)
+ {
+ Token t (next_token ());
+
+ if (t == Token::eos)
+ {
+ eos = true;
+
+ // Add new line if it's missing at the end of line.
+ //
+ if (!line_.empty () && line_.back () != '\n')
+ {
+ //@@ should issue a warning here
+ //
+ line_.push_back (Token ('\n', line_.back ().line ()));
+ }
+ }
+ else
+ {
+ line_.push_back (t);
+ }
+
+ if (eos || t == '\n') break;
+ }
+
+ /*
+ cerr << "line: \'";
+
+ for (std::deque<Token>::iterator
+ i (line_.begin ()), e (line_.end ()); i != e; ++i)
+ {
+ if (*i != Token::eos) cerr << *i;
+ }
+
+ cerr << '\'' << endl;
+ */
+
+ // Check if it is a PP directive
+ //
+
+ if (!line_.empty ())
+ {
+ copy_ = line_;
+ ls_buffer_.clear ();
+ copy_.push_back (Token::eos); // add eos
+
+ try
+ {
+ Token t (ls_get_ns ());
+
+ // cerr << "t = \'" << t << '\'' << endl;
+
+ if (t == '#')
+ {
+ scan_directive ();
+ }
+ }
+ catch (EOS const&)
+ {
+ // cerr << "EOS" << endl;
+
+ // error condition?
+ Token t ('\n', line_.front ().line ());
+ line_.clear ();
+ line_.push_back (t);
+ }
+ }
+ }
+
+ if (eos)
+ {
+ if (balance_ > 0)
+ {
+ cerr << "missing endif directive at the end of file" << endl;
+ }
+
+ line_.push_back (Token::eos);
+ }
+ }
+
+
+ void
+ scan_directive ()
+ {
+ Token t (ls_get_ns ());
+
+ string lexeme;
+
+ if (std::isalpha<char> (t, loc_))
+ {
+ for (;std::isalpha<char> (t, loc_); t = ls_get ())
+ lexeme += t;
+
+ ls_ret (t);
+ }
+
+ // cerr << "lexeme " << lexeme << endl;
+
+ if (lexeme == "include")
+ {
+ scan_include ();
+ return;
+ }
+ else if (lexeme == "if")
+ {
+ ++balance_;
+ }
+ else if (lexeme == "ifdef" || lexeme == "ifndef")
+ {
+ ++balance_;
+
+ string symbol;
+ Token t (ls_get_ns ());
+
+
+ if (is_first_id_char (t))
+ {
+ for (;is_id_char (t); t = ls_get ())
+ symbol += t;
+ ls_ret (t);
+ }
+
+ if (!symbol.empty ())
+ {
+ //cerr << "symbol " << symbol << endl;
+
+ if (skip_balance_ == 0) // Unless we are already skipping.
+ {
+ bool defined (symbols_.find (symbol) != symbols_.end ());
+
+ if ((!defined && lexeme == "ifdef") ||
+ (defined && lexeme == "ifndef"))
+ skip_balance_ = balance_;
+ }
+ }
+ else
+ {
+ cerr << t.line () << ": no symbol specified for " << lexeme
+ << " directive" << endl;
+ throw EOS (); //@@ tmp
+ }
+ }
+ else if (lexeme == "elif" || lexeme == "else")
+ {
+ // For now we treat elif just like else.
+ //
+ if (skip_balance_ == balance_)
+ skip_balance_ = 0;
+ else if (skip_balance_ == 0) // Unless we are already skipping.
+ skip_balance_ = balance_; // Start skipping now.
+ }
+ else if (lexeme == "endif")
+ {
+ if (skip_balance_ == balance_)
+ skip_balance_ = 0;
+
+ if (balance_ > 0)
+ --balance_;
+ else
+ {
+ cerr << t.line () << ": extraneous endif directive" << endl;
+ throw EOS (); //@@ tmp
+ }
+ }
+ else if (lexeme == "error")
+ {
+ if (skip_balance_ == 0)
+ {
+ string msg;
+ Token t (ls_get_ns ());
+
+ if (t != '\n')
+ {
+ for (;t != '\n'; t = ls_get ())
+ msg += t;
+ ls_ret (t);
+ }
+
+ cerr << t.line () << ": error: " << msg << endl;
+ throw EOS (); //@@ tmp
+ }
+ }
+
+ // By default we replace this directive with a newline.
+ //
+ {
+ Token t ('\n', line_.front ().line ());
+ line_.clear ();
+ line_.push_back (t);
+ }
+ }
+
+ void
+ scan_include ()
+ {
+ Token t (ls_get_ns ());
+
+ char finilizer;
+
+ switch (t)
+ {
+ case '\"':
+ {
+ finilizer = '\"';
+ break;
+
+ }
+ case '<':
+ {
+ finilizer = '>';
+ break;
+ }
+ default:
+ {
+ cerr << t.line () << ": invalid include directive" << endl;
+ throw EOS (); //@@ tmp
+ }
+ }
+
+ string path;
+
+ for (t = ls_get (); t != finilizer && t != '\n'; t = ls_get ())
+ {
+ path += t;
+ }
+
+ if (t != finilizer)
+ {
+ cerr << t.line () << ": invalid include directive" << endl;
+ throw EOS (); // @@ tmp
+ }
+
+ string repl (finilizer == '>' ? "__binclude \"" : "__qinclude \"");
+ repl += path + "\";\n";
+
+ line_.clear ();
+
+ for (string::const_iterator i (repl.begin ()), e (repl.end ());
+ i != e; ++i)
+ {
+ line_.push_back (Token (*i, t.line ()));
+ }
+ }
+
+ // Char-scanning
+ //
+ //
+
+ Token
+ next_token ()
+ {
+ if (!obuffer_.empty ())
+ {
+ Token t (obuffer_.front ());
+ obuffer_.pop_front ();
+ return t;
+ }
+
+ try
+ {
+ switch (state_)
+ {
+ case State::preprocessing:
+ {
+ return preprocessing ();
+ }
+ case State::string_literal:
+ {
+ return string_literal ();
+ }
+ case State::char_literal:
+ {
+ return char_literal ();
+ }
+ }
+ }
+ catch (EOS const&)
+ {
+ }
+
+ return Token::eos;
+ }
+
+ Token
+ preprocessing ()
+ {
+ unsigned long l (ln_);
+ char_type c (get ());
+
+ switch (c)
+ {
+ case '\'':
+ {
+ state_ = State::char_literal;
+ break;
+ }
+ case '\"':
+ {
+ state_ = State::string_literal;
+ break;
+ }
+ case '\\':
+ {
+ return escape ();
+ }
+ case '\n':
+ {
+ ++ln_;
+ break;
+ }
+ case '/':
+ {
+ return slash ();
+ }
+ }
+
+ return Token (c, l);
+ }
+
+
+ Token
+ string_literal ()
+ {
+ unsigned long l (ln_);
+ char_type c (get ());
+
+ switch (c)
+ {
+ case '\"':
+ {
+ state_ = State::preprocessing;
+ break;
+ }
+ case '\\':
+ {
+ return escape ();
+ }
+ case '\n':
+ {
+ ++ln_;
+ break;
+ }
+ }
+
+ return Token (c, l);
+ }
+
+
+ Token
+ char_literal ()
+ {
+ unsigned long l (ln_);
+ char_type c (get ());
+
+ switch (c)
+ {
+ case '\'':
+ {
+ state_ = State::preprocessing;
+ break;
+ }
+ case '\\':
+ {
+ return escape ();
+ }
+ case '\n':
+ {
+ ++ln_;
+ break;
+ }
+ }
+
+ return Token (c, l);
+ }
+
+
+ Token
+ escape ()
+ {
+ try
+ {
+ char_type c (get ());
+
+ switch (c)
+ {
+ case '\n':
+ {
+ ++ln_;
+ return next_token ();
+ }
+ case '\'':
+ {
+ if (state_ != State::char_literal &&
+ state_ != State::string_literal)
+ {
+ state_ = State::char_literal;
+ }
+
+ put (Token ('\'', ln_));
+ return Token ('\\', ln_);
+ }
+ case '\"':
+ {
+ if (state_ != State::char_literal &&
+ state_ != State::string_literal)
+ {
+ state_ = State::string_literal;
+ }
+
+ put (Token ('\"', ln_));
+ return Token ('\\', ln_);
+ }
+ default:
+ {
+ ret (c);
+ return Token ('\\', ln_);
+ }
+ }
+ }
+ catch (EOS const&)
+ {
+ ret_eos ();
+ return Token ('\\', ln_);
+ }
+ }
+
+
+ Token
+ slash ()
+ {
+ unsigned long l (ln_);
+
+ try
+ {
+ char_type c (get ());
+
+ switch (c)
+ {
+ case '*': // C comment
+ {
+ return c_comment ();
+ }
+ case '/': // C++ comment
+ {
+ return cxx_comment ();
+ }
+ default:
+ {
+ ret (c);
+ break;
+ }
+ }
+ }
+ catch (EOS const&)
+ {
+ ret_eos ();
+ }
+
+ return Token ('/', l);
+ }
+
+
+ Token
+ c_comment ()
+ {
+ // Replace the whole C comment with the single space.
+ //
+ unsigned long l (ln_);
+
+ try
+ {
+ char_type c (get ());
+
+ for (bool done (false); !done;)
+ {
+ switch (c)
+ {
+ case '\n':
+ {
+ ++ln_;
+ break;
+ }
+ case '*':
+ {
+ c = get ();
+ if (c == '/') done = true;
+ continue;
+ }
+ }
+
+ c = get ();
+ }
+ }
+ catch (EOS const&)
+ {
+ put (Token::eos);
+ }
+
+ return Token (' ', l);
+ }
+
+
+ Token
+ cxx_comment ()
+ {
+ // Replace the whole C++ comment with the single space.
+ //
+ unsigned long l (ln_);
+
+ try
+ {
+ for (bool done (false); !done;)
+ {
+ char_type c (get ());
+
+ switch (c)
+ {
+ case '\n':
+ {
+ ++ln_;
+ done = true;
+ break;
+ }
+ }
+ }
+ }
+ catch (EOS const&)
+ {
+ put (Token::eos);
+ }
+
+ return Token ('\n', l);
+ }
+
+ // Low-level utility functions.
+ //
+ private:
+ typedef
+ TokenStream<char>::int_type
+ int_type;
+
+ typedef
+ TokenStream<char>::char_type
+ char_type;
+
+ char_type
+ to_char_type (int_type i)
+ {
+ return TokenStream<char>::to_char_type (i);
+ }
+
+ bool
+ eos (int_type i)
+ {
+ return TokenStream<char>::eos () == i;
+ }
+
+ class EOS {};
+
+ char_type
+ get () throw (EOS)
+ {
+ int_type i;
+
+ if (ibuffer_.empty ())
+ {
+ i = is_.next ();
+ }
+ else
+ {
+ i = ibuffer_.front ();
+ ibuffer_.pop_front ();
+ }
+
+ if (eos (i)) throw EOS ();
+
+ return to_char_type (i);
+ }
+
+ void
+ ret (char_type t)
+ {
+ ibuffer_.push_front (t);
+ }
+
+ void
+ ret_eos ()
+ {
+ ibuffer_.push_front (TokenStream<char>::eos ());
+ }
+
+ void
+ put (Token const& t)
+ {
+ obuffer_.push_back (t);
+ }
+
+
+ // line-scanner utility functions
+ //
+ //
+ void
+ ls_ret (Token const& t)
+ {
+ ls_buffer_.push_front (t);
+ }
+
+ Token
+ ls_get () throw (EOS)
+ {
+ if (ls_buffer_.empty ())
+ {
+ Token t (dsa_.next ());
+ if (t == Token::eos) throw EOS ();
+ return t;
+ }
+ else
+ {
+ Token t (ls_buffer_.front ());
+ ls_buffer_.pop_front ();
+
+ if (t == Token::eos) throw EOS ();
+ return t;
+ }
+ }
+
+ // Get first non-space token
+ //
+ Token
+ ls_get_ns () throw (EOS)
+ {
+ Token t (ls_get ());
+
+ while (ls_is_space (t)) t = ls_get ();
+ return t;
+ }
+
+ bool
+ ls_is_space (Token const& t)
+ {
+ return t == ' ' || t == '\t';
+ }
+
+ bool
+ is_first_id_char (Token const& t)
+ {
+ return std::isalpha<char> (t, loc_) || t == '_';
+ }
+
+ bool
+ is_id_char (Token const& t)
+ {
+ return std::isalnum<char> (t, loc_) || t == '_';
+ }
+
+ private:
+ struct State
+ {
+ enum Value
+ {
+ preprocessing,
+ string_literal,
+ char_literal
+ };
+ };
+
+ std::locale loc_;
+
+ State::Value state_;
+ unsigned long ln_;
+
+ TokenStream<char>& is_;
+
+ std::deque<int_type> ibuffer_;
+ std::deque<Token> obuffer_;
+
+ std::deque<Token> line_;
+
+ std::deque<Token> copy_;
+ DequeStreamAdapter dsa_;
+ std::deque<Token> ls_buffer_;
+
+ Symbols symbols_;
+ unsigned long balance_; // Current #if*/#endif balance.
+ unsigned long skip_balance_; // #if*/#endif balance at which we began
+ // skipping. 0 indicates no skipping.
+
+ };
+
+
+ // Preprocessor
+ //
+ //
+ Preprocessor::
+ ~Preprocessor ()
+ {
+ }
+
+ Preprocessor::
+ Preprocessor (TokenStream<char>& is, Symbols const& symbols)
+ : impl_ (new PreprocessorImpl (is, symbols))
+ {
+ }
+
+ Token Preprocessor::
+ next ()
+ {
+ return impl_->next ();
+ }
+ }
+ }
+}
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.hpp b/modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.hpp
new file mode 100644
index 00000000000..994c889a3f8
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/Preprocessor.hpp
@@ -0,0 +1,45 @@
+// file : CCF/CompilerElements/Preprocessor.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_COMPILER_ELEMENTS_PREPROCESSOR_HPP
+#define CCF_COMPILER_ELEMENTS_PREPROCESSOR_HPP
+
+#include <memory>
+#include <string>
+#include <set>
+
+#include "CCF/CompilerElements/TokenStream.hpp"
+#include "CCF/CompilerElements/PreprocessorToken.hpp"
+
+namespace CCF
+{
+ namespace CompilerElements
+ {
+ namespace CPP
+ {
+ typedef
+ std::set<std::string>
+ Symbols;
+
+ class Preprocessor : public TokenStream<Token>
+ {
+ public:
+ virtual
+ ~Preprocessor ();
+
+ Preprocessor (TokenStream<char>& is, Symbols const&);
+
+ virtual Token
+ next ();
+
+ private:
+ class PreprocessorImpl;
+
+ std::auto_ptr<PreprocessorImpl> impl_;
+ };
+ }
+ }
+}
+
+#endif // CCF_COMPILER_ELEMENTS_PREPROCESSOR_HPP
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.cpp b/modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.cpp
new file mode 100644
index 00000000000..5f3e629243e
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.cpp
@@ -0,0 +1,57 @@
+// file : CCF/CompilerElements/PreprocessorToken.cpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#include "CCF/CompilerElements/PreprocessorToken.hpp"
+
+namespace CCF
+{
+ namespace CompilerElements
+ {
+ namespace CPP
+ {
+ Token const Token::eos;
+
+ Token::
+ Token (char c, unsigned long line)
+ : c_ (traits::to_int_type (c)), line_ (line)
+ {
+ }
+
+ Token::
+ Token ()
+ : c_ (traits::eof ()), line_ (0)
+ {
+ }
+
+ Token::
+ operator char () const throw (EOS)
+ {
+ if (*this == eos) throw EOS ();
+
+ return traits::to_char_type (c_);
+ }
+
+
+ unsigned long Token::
+ line () const throw (EOS)
+ {
+ if (*this == eos) throw EOS ();
+
+ return line_;
+ }
+
+ bool
+ operator== (Token const& a, Token const& b)
+ {
+ return a.c_ == b.c_;
+ }
+
+ bool
+ operator!= (Token const& a, Token const& b)
+ {
+ return a.c_ != b.c_;
+ }
+ }
+ }
+}
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.hpp b/modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.hpp
new file mode 100644
index 00000000000..5c82076a01c
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/PreprocessorToken.hpp
@@ -0,0 +1,58 @@
+// file : CCF/CompilerElements/PreprocessorToken.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_COMPILER_ELEMENTS_PREPROCESSOR_TOKEN_HPP
+#define CCF_COMPILER_ELEMENTS_PREPROCESSOR_TOKEN_HPP
+
+#include <string>
+
+//@@ It is probably a good idea to move preprocessor into a
+// separate library.
+//
+
+namespace CCF
+{
+ namespace CompilerElements
+ {
+ namespace CPP
+ {
+ class Token
+ {
+ public:
+ static Token const eos;
+
+ public:
+ Token (char c, unsigned long line);
+
+ class EOS {};
+
+ operator char () const throw (EOS);
+
+ unsigned long
+ line () const throw (EOS);
+
+ friend bool
+ operator== (Token const& a, Token const& b);
+
+ friend bool
+ operator!= (Token const& a, Token const& b);
+
+ private:
+ // Constructs eos token.
+ //
+ Token ();
+
+ private:
+ typedef
+ std::char_traits<char>
+ traits;
+
+ traits::int_type c_;
+ unsigned long line_;
+ };
+ }
+ }
+}
+
+#endif // CCF_COMPILER_ELEMENTS_PREPROCESSOR_TOKEN_HPP
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/ReferenceCounting.hpp b/modules/CIAO/CCF/CCF/CompilerElements/ReferenceCounting.hpp
new file mode 100644
index 00000000000..0c3e0057d59
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/ReferenceCounting.hpp
@@ -0,0 +1,12 @@
+// file : CCF/CompilerElements/ReferenceCounting.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_RUNTIME_REFERENCE_COUNTING_H
+#define CCF_RUNTIME_REFERENCE_COUNTING_H
+
+#include "Utility/ReferenceCounting/ReferenceCounting.hpp"
+
+namespace ReferenceCounting = Utility::ReferenceCounting;
+
+#endif // CCF_RUNTIME_REFERENCE_COUNTING_H
diff --git a/modules/CIAO/CCF/CCF/CompilerElements/TokenStream.hpp b/modules/CIAO/CCF/CCF/CompilerElements/TokenStream.hpp
new file mode 100644
index 00000000000..f1d3ab4fb8c
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CompilerElements/TokenStream.hpp
@@ -0,0 +1,82 @@
+// file : CCF/CompilerElements/TokenStream.hpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_COMPILER_ELEMENTS_TOKEN_STREAM_HPP
+#define CCF_COMPILER_ELEMENTS_TOKEN_STREAM_HPP
+
+#include <string>
+#include <istream>
+
+namespace CCF
+{
+ namespace CompilerElements
+ {
+ template <typename Token>
+ class TokenStream
+ {
+ public:
+ // (JP 06-04-06) Not required by C++ spec, but it
+ // eliminates buggy GCC warnings.
+ virtual ~TokenStream () {}
+
+ virtual Token
+ next () = 0;
+ };
+
+ template <>
+ class TokenStream<char>
+ {
+ public:
+ typedef
+ std::char_traits<char>
+ traits;
+
+ typedef
+ traits::int_type
+ int_type;
+
+ typedef
+ traits::char_type
+ char_type;
+
+ public:
+ virtual int_type
+ next () = 0;
+
+ static char_type
+ to_char_type (int_type i)
+ {
+ return traits::to_char_type (i);
+ }
+
+ static int_type
+ eos ()
+ {
+ return traits::eof ();
+ }
+ };
+
+ class InputStreamAdapter : public TokenStream<char>
+ {
+ public:
+ InputStreamAdapter (std::istream& is)
+ : is_ (is)
+ {
+ }
+
+ public:
+
+ virtual int_type
+ next ()
+ {
+ return is_.get ();
+ }
+
+ private:
+ std::istream& is_;
+ };
+ }
+}
+
+#endif // CCF_COMPILER_ELEMENTS_TOKEN_STREAM_HPP