|
|
c_pp_line.hpp説明を見る。00001 /* 00002 * TOPPERS/FDMP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Function Distributed Multiprocessor Kernel 00005 * 00006 * Copyright (C) 2005 by Takagi Nobuhisa 00007 * 00008 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 00009 * によって公表されている GNU General Public License の Version 2 に記 00010 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア 00011 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 00012 * 利用と呼ぶ)することを無償で許諾する. 00013 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00014 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00015 * スコード中に含まれていること. 00016 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00017 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00018 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00019 * の無保証規定を掲載すること. 00020 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00021 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00022 * と. 00023 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00024 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00025 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00026 * 報告すること. 00027 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00028 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00029 * 00030 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00031 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 00032 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 00033 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. 00034 * 00035 */ 00036 00041 #ifndef TOPPERS_C_PP_LINE_HPP_ 00042 #define TOPPERS_C_PP_LINE_HPP_ 00043 00044 #include "toppers/text_line.hpp" 00045 #include "toppers/parser.hpp" 00046 #include <vector> 00047 #include <functional> 00048 #include <boost/shared_ptr.hpp> 00049 00050 namespace toppers 00051 { 00052 00053 namespace detail 00054 { 00055 00056 struct c_pp_line_parser : boost::spirit::grammar<c_pp_line_parser> 00057 { 00058 template <class Scanner> 00059 struct definition 00060 { 00061 typedef boost::spirit::rule<Scanner> rule_t; 00062 rule_t r; 00063 definition( const c_pp_line_parser& self ) 00064 { 00065 using namespace boost::spirit; 00066 r = ( 00067 '#' >> lexeme_d[ str_p( "line" ) >> space_p >> uint_p[ assign_a( self.line_ ) ] ] >> 00068 c_strlit_parser( self.codeset_ )[ assign_a( self.file_ ) ] 00069 ) 00070 | ( 00071 '#' >> 00072 uint_p[ assign_a( self.line_ ) ] >> 00073 c_strlit_parser( self.codeset_ )[ assign_a( self.file_ ) ] >> 00074 *anychar_p 00075 ); 00076 } 00077 const rule_t& start() const { return r; } 00078 }; 00079 00080 c_pp_line_parser( long& line, std::string& file, codeset_t codeset = ascii ) 00081 : line_( line ), file_( file ), codeset_( codeset ) 00082 { 00083 } 00084 00085 long& line_; 00086 std::string& file_; 00087 codeset_t codeset_; 00088 }; 00089 00090 struct c_pp_pragma_parser : boost::spirit::grammar<c_pp_pragma_parser> 00091 { 00092 template <class Scanner> 00093 struct definition 00094 { 00095 typedef boost::spirit::rule<Scanner> rule_t; 00096 rule_t r; 00097 definition( const c_pp_pragma_parser& self ) 00098 { 00099 using namespace boost::spirit; 00100 r = '#' >> lexeme_d[ str_p( "pragma" ) >> space_p >> ( +anychar_p )[ assign_a( self.parameter_ ) ] ]; 00101 } 00102 const rule_t& start() const { return r; } 00103 }; 00104 00105 c_pp_pragma_parser( std::string& parameter ) : parameter_( parameter ) 00106 { 00107 } 00108 std::string& parameter_; 00109 }; 00110 00111 } 00112 00119 template <class Container> 00120 class c_pp_line : public std::binary_function<Container, line_buf, void> 00121 { 00122 public: 00123 typedef Container conatiner; 00124 00129 explicit c_pp_line( codeset_t codeset = ascii ) 00130 : codeset_( codeset ), pragmas_( new std::vector<line_buf> ) 00131 { 00132 } 00138 void operator()( conatiner& cont, line_buf& buf ) 00139 { 00140 using namespace boost::spirit; 00141 long line; 00142 std::string file; 00143 detail::c_pp_line_parser c_pp_line_p( line, file, codeset_ ); 00144 00145 if ( parse( buf.buf_.begin(), buf.buf_.end(), c_pp_line_p, space_p ).full ) // #line指令の処理 00146 { 00147 using namespace boost::filesystem; 00148 buf.line_.line_ = line; 00149 assert( file.size() >= 2 ); 00150 try 00151 { 00152 std::string file_name( file.substr( 1, file.size()-2 ) ); 00153 buf.line_.file_ = path( file_name, native ); 00154 } 00155 catch ( ... ) 00156 { 00157 // GNUのプリプロセッサはファイル名に相当する部分が<built-n>や<command line> 00158 // となる場合があるため、例外が発生する可能性あり 00159 buf.line_.file_ = path( "unknown", native ); 00160 } 00161 } 00162 else 00163 { 00164 std::string param; 00165 detail::c_pp_pragma_parser c_pp_pragma_p( param ); 00166 00167 if ( parse( buf.buf_.begin(), buf.buf_.end(), c_pp_pragma_p, space_p ).full ) // #pragma指令の処理 00168 { 00169 line_buf t( buf ); 00170 t.buf_ = param; 00171 pragmas_->push_back( t ); 00172 } 00173 else 00174 { 00175 std::string::size_type pos = buf.buf_.find_first_not_of( " \t" ); 00176 if ( pos == std::string::npos || buf.buf_[pos] != '#' ) 00177 { 00178 cont.push_back( buf ); 00179 } 00180 ++buf.line_.line_; 00181 } 00182 } 00183 buf.buf_.clear(); 00184 } 00189 const std::vector<line_buf>& pragmas() const { return *pragmas_; } 00190 private: 00191 codeset_t codeset_; 00192 boost::shared_ptr<std::vector<line_buf> > pragmas_; 00193 }; 00194 00195 } 00196 00197 #endif // ! TOPPERS_C_PP_LINE_HPP_ Copyright © 2006 by TAKAGI Nobuhisa. このページは Wed Apr 12 16:31:55 2006 に Doxygen によって生成されました。 |