diff options
Diffstat (limited to 'modules/CIAO/CCF/CCF/CompilerElements')
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 |