|
|
parser.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_PARSER_HPP_ 00042 #define TOPPERS_PARSER_HPP_ 00043 00044 #include "toppers/codeset.hpp" 00045 #include <boost/spirit/core.hpp> 00046 #include <boost/spirit/actor.hpp> 00047 #include <boost/spirit/utility.hpp> 00048 #include <boost/spirit/dynamic.hpp> 00049 00050 namespace toppers 00051 { 00052 00053 namespace detail 00054 { 00055 00056 struct c_integer_suffix_parse_functor 00057 { 00058 typedef boost::spirit::nil_t result_t; 00059 template <class Scanner> 00060 int operator()( Scanner scan, result_t& ) const 00061 { 00062 using namespace boost::spirit; 00063 int length = 00064 as_lower_d 00065 [ 00066 ch_p( 'u' ) >> !( str_p( "ll" ) | 'l' | "i8" | "i16" | "i32" | "i64" ) 00067 | ( str_p( "ll" ) | 'l' | "i8" | "i16" | "i32" | "i64" ) >> !ch_p( 'u' ) 00068 ].parse( scan ).length(); 00069 return length; 00070 } 00071 }; 00072 00073 template <typename T> 00074 struct c_integer_constant_parse_functor 00075 { 00076 typedef T result_t; 00077 template <class Scanner> 00078 int operator()( Scanner scan, result_t& result ) const 00079 { 00080 using namespace boost::spirit; 00081 result_t x = T( 0 ); 00082 int length = 00083 ( 00084 if_p( '0' ) // 16進または8進 00085 [ 00086 !( 00087 ( ch_p( 'x' ) | 'X' ) >> uint_parser<T, 16>()[ assign_a( x ) ] 00088 | uint_parser<T, 8>()[ assign_a( x ) ] 00089 ) 00090 ] 00091 .else_p // 10進 00092 [ 00093 uint_parser<T, 10>()[ assign_a( x ) ] 00094 ] 00095 ).parse( scan ).length(); 00096 result = x; 00097 return length; 00098 } 00099 }; 00100 00101 template <typename T> 00102 struct c_integer_parse_functor 00103 { 00104 typedef T result_t; 00105 template <class Scanner> 00106 int operator()( Scanner scan, result_t& result ) const 00107 { 00108 using namespace boost::spirit; 00109 static const functor_parser<c_integer_constant_parse_functor<T> > c_int_const_p; 00110 static const functor_parser<c_integer_suffix_parse_functor> c_int_suffix_p; 00111 bool negative = false; 00112 result_t x; 00113 int length = 00114 ( 00115 !sign_p[ assign_a( negative ) ] >> lexeme_d[ c_int_const_p[ assign_a( x ) ] >> !c_int_suffix_p ] 00116 ).parse( scan ).length(); 00117 result = ( negative ? -x : x ); 00118 return length; 00119 } 00120 }; 00121 00122 template <int CodeSet = -1> struct mbchar_parse_functor; 00123 00124 template <> 00125 struct mbchar_parse_functor<ascii> 00126 { 00127 typedef boost::spirit::nil_t result_t; 00128 template <class Scanner> 00129 int operator()( Scanner scan, result_t& ) const 00130 { 00131 return boost::spirit::range_p( '\x01', '\x7f' ).parse( scan ).length(); 00132 } 00133 }; 00134 00135 template <> 00136 struct mbchar_parse_functor<shift_jis> 00137 { 00138 typedef boost::spirit::nil_t result_t; 00139 template <class Scanner> 00140 int operator()( Scanner scan, result_t& ) const 00141 { 00142 using namespace boost::spirit; 00143 int length = 00144 ( 00145 range_p( '\x01', '\x7f' ) // 半角英数字記号 00146 | range_p( '\xa1', '\xdf' ) // 半角カタカナ 00147 | ( chset<>( "\x81-\x9f\xe0-\xef" ) >> chset<>( "\x40-\x7e\x80-\xfc" ) ) // 全角 00148 ).parse( scan ).length(); 00149 return length; 00150 } 00151 }; 00152 00153 template <> 00154 struct mbchar_parse_functor<euc_jp> 00155 { 00156 typedef boost::spirit::nil_t result_t; 00157 template <class Scanner> 00158 int operator()( Scanner scan, result_t& ) const 00159 { 00160 using namespace boost::spirit; 00161 int length = 00162 ( 00163 range_p( '\x01', '\x7f' ) // 半角英数字記号 00164 | ( ch_p( '\x8e' ) >> range_p( '\xa1', '\xdf' ) ) // 半角カタカナ 00165 | ( !ch_p( '\x8f' ) >> range_p( '\xa1', '\xf0' ) >> range_p( '\xa1', '\xf0' ) ) // 全角 00166 ).parse( scan ).length(); 00167 return length; 00168 } 00169 }; 00170 00171 template <> 00172 struct mbchar_parse_functor<utf8> 00173 { 00174 typedef boost::spirit::nil_t result_t; 00175 template <class Scanner> 00176 int operator()( Scanner scan, result_t& ) const 00177 { 00178 using namespace boost::spirit; 00179 int length = 00180 ( 00181 range_p( '\x01', '\x7f' ) // 1バイト 00182 | ( range_p( '\xc0', '\xdf' ) >> range_p( '\x80', '\xbf' ) ) // 2バイト 00183 | ( range_p( '\xe0', '\xef' ) >> repeat_p( 2 )[ range_p( '\x80', '\xbf' ) ] ) // 3バイト 00184 | ( range_p( '\xf0', '\xf7' ) >> repeat_p( 3 )[ range_p( '\x80', '\xbf' ) ] ) // 4バイト 00185 | ( range_p( '\xf8', '\xfb' ) >> repeat_p( 4 )[ range_p( '\x80', '\xbf' ) ] ) // 5バイト 00186 | ( range_p( '\xfc', '\xfd' ) >> repeat_p( 5 )[ range_p( '\x80', '\xbf' ) ] ) // 6バイト 00187 ).parse( scan ).length(); 00188 return length; 00189 } 00190 }; 00191 00192 template <> 00193 struct mbchar_parse_functor<-1> 00194 { 00195 typedef boost::spirit::nil_t result_t; 00196 explicit mbchar_parse_functor( codeset_t codeset = ascii ) : codeset_( codeset ) {} 00197 template <class Scanner> 00198 int operator()( Scanner scan, result_t& result ) const 00199 { 00200 int length; 00201 switch ( codeset_ ) 00202 { 00203 case ascii: 00204 { 00205 static mbchar_parse_functor<ascii> f; 00206 length = f( scan, result ); 00207 } 00208 break; 00209 case shift_jis: 00210 { 00211 static mbchar_parse_functor<shift_jis> f; 00212 length = f( scan, result ); 00213 } 00214 break; 00215 case euc_jp: 00216 { 00217 static mbchar_parse_functor<euc_jp> f; 00218 length = f( scan, result ); 00219 } 00220 break; 00221 case utf8: 00222 { 00223 static mbchar_parse_functor<utf8> f; 00224 length = f( scan, result ); 00225 } 00226 break; 00227 default: 00228 length = -1; 00229 break; 00230 } 00231 return length; 00232 } 00233 codeset_t codeset_; 00234 }; 00235 00236 struct ucn_parse_functor 00237 { 00238 typedef long result_t; 00239 template <class Scanner> 00240 int operator()( Scanner scan, result_t& result ) const 00241 { 00242 using namespace boost::spirit; 00243 result_t x; 00244 int length = 00245 ( 00246 lexeme_d 00247 [ 00248 ch_p( '\\' ) >> 00249 ( 00250 ( 'U' >> int_parser<long, 16, 8, 8>()[ assign_a( x ) ] ) // \Uhhhhhhhh形式 00251 | ( 'u' >> int_parser<long, 16, 4, 4>()[ assign_a( x ) ] ) // \uhhhh形式 00252 ) 00253 ] 00254 ).parse( scan ).length(); 00255 if ( ( x < 0xa0 && !( x == 0x24 || x == 0x40 || x == 0x60 ) ) 00256 || ( 0xd800 <= x && x <= 0xdfff ) 00257 || 0x10ffff < x ) // 国際文字名に使えない値(JIS X3010:2003 6.4.3) 00258 { 00259 x = -1; 00260 } 00261 result = x; 00262 return length; 00263 } 00264 }; 00265 00266 template <int CodeSet = -1> struct c_strlit_parse_functor; 00267 00268 template <int CodeSet> 00269 struct c_strlit_parse_functor 00270 { 00271 typedef boost::spirit::nil_t result_t; 00272 template <class Scanner> 00273 int operator()( Scanner scan, result_t& result ) const 00274 { 00275 using namespace boost::spirit; 00276 static const functor_parser<detail::mbchar_parse_functor<CodeSet> > mbchar_p; 00277 static const functor_parser<detail::ucn_parse_functor> ucn_p; 00278 int length = 00279 ( 00280 confix_p( '\"', *( "\\\"" | mbchar_p - '\\' | ucn_p | c_escape_ch_p ), '\"' ) 00281 ).parse( scan ).length(); 00282 return length; 00283 } 00284 }; 00285 00286 template <> 00287 struct c_strlit_parse_functor<-1> 00288 { 00289 typedef boost::spirit::nil_t result_t; 00290 explicit c_strlit_parse_functor( codeset_t codeset = ascii ) : codeset_( codeset ) {} 00291 template <class Scanner> 00292 int operator()( Scanner scan, result_t& result ) const 00293 { 00294 using namespace boost::spirit; 00295 const mbchar_parse_functor<> functor( codeset_ ); 00296 const functor_parser<detail::mbchar_parse_functor<> > mbchar_p( functor ); 00297 static const functor_parser<detail::ucn_parse_functor> ucn_p; 00298 int length = 00299 ( 00300 confix_p( '\"', *( "\\\"" | ( mbchar_p - ch_p( '\\' ) ) | ucn_p | c_escape_ch_p ), '\"' ) 00301 ).parse( scan ).length(); 00302 return length; 00303 } 00304 codeset_t codeset_; 00305 }; 00306 00307 template <int CodeSet = -1> struct c_chlit_parse_functor; 00308 00309 template <int CodeSet> 00310 struct c_chlit_parse_functor 00311 { 00312 typedef boost::spirit::nil_t result_t; 00313 template <class Scanner> 00314 int operator()( Scanner scan, result_t& result ) const 00315 { 00316 using namespace boost::spirit; 00317 static const functor_parser<detail::mbchar_parse_functor<CodeSet> > mbchar_p; 00318 static const functor_parser<detail::ucn_parse_functor> ucn_p; 00319 int length = 00320 ( 00321 confix_p( '\'', +( "\\\'" | mbchar_p - '\\' | ucn_p | c_escape_ch_p ), '\'' ) 00322 ).parse( scan ).length(); 00323 return length; 00324 } 00325 }; 00326 00327 template <> 00328 struct c_chlit_parse_functor<-1> 00329 { 00330 typedef boost::spirit::nil_t result_t; 00331 explicit c_chlit_parse_functor( codeset_t codeset = ascii ) : codeset_( codeset ) {} 00332 template <class Scanner> 00333 int operator()( Scanner scan, result_t& result ) const 00334 { 00335 using namespace boost::spirit; 00336 const mbchar_parse_functor<> functor( codeset_ ); 00337 const functor_parser<detail::mbchar_parse_functor<> > mbchar_p( functor ); 00338 static const functor_parser<detail::ucn_parse_functor> ucn_p; 00339 int length = 00340 ( 00341 confix_p( '\'', +( "\\\'" | mbchar_p - '\\' | ucn_p | c_escape_ch_p ), '\'' ) 00342 ).parse( scan ).length(); 00343 return length; 00344 } 00345 codeset_t codeset_; 00346 }; 00347 00348 extern const char* const c_keywords[]; 00349 extern const char* const c_plus_plus_keywords[]; 00350 00351 struct c_identifier_parse_functor 00352 { 00353 typedef boost::spirit::nil_t result_t; 00354 template <class Scanner> 00355 int operator()( Scanner scan, result_t& result ) const 00356 { 00357 using namespace boost::spirit; 00358 static const functor_parser<detail::ucn_parse_functor> ucn_p; 00359 int length; 00360 typename Scanner::iterator_t const first( scan.first ); 00361 00362 if ( ucn_ ) 00363 { 00364 length = 00365 ( 00366 lexeme_d 00367 [ 00368 ( alpha_p | '_' | ucn_p ) >> 00369 *( alnum_p | '_' | ucn_p ) 00370 ] 00371 ).parse( scan ).length(); 00372 } 00373 else 00374 { 00375 length = 00376 ( 00377 lexeme_d 00378 [ 00379 ( alpha_p | '_' ) >> 00380 *( alnum_p | '_' ) 00381 ] 00382 ).parse( scan ).length(); 00383 } 00384 std::string token( first, scan.first ); 00385 00386 for ( int i = 0; c_keywords[i] != 0; i++ ) 00387 { 00388 if ( token == c_keywords[i] ) 00389 { 00390 length = -1; 00391 break; 00392 } 00393 } 00394 if ( c_plus_plus_ ) 00395 { 00396 for ( int i = 0; c_plus_plus_keywords[i] != 0; i++ ) 00397 { 00398 if ( token == c_plus_plus_keywords[i] ) 00399 { 00400 length = -1; 00401 break; 00402 } 00403 } 00404 } 00405 return length; 00406 } 00407 explicit c_identifier_parse_functor( bool ucn = false, bool c_plus_plus = false ) 00408 : ucn_( ucn ), c_plus_plus_( c_plus_plus ) 00409 { 00410 } 00411 00412 bool ucn_; 00413 bool c_plus_plus_; 00414 }; 00415 00416 } 00417 00424 template <typename T> 00425 inline const boost::spirit::functor_parser<detail::c_integer_parse_functor<T> > c_int_parser() 00426 { 00427 return boost::spirit::functor_parser<detail::c_integer_parse_functor<T> >(); 00428 } 00429 00430 extern const boost::spirit::functor_parser<detail::c_integer_parse_functor<int> > c_int_p; 00431 extern const boost::spirit::functor_parser<detail::c_integer_parse_functor<unsigned> > c_uint_p; 00432 00440 template <int CodeSet> 00441 inline const boost::spirit::functor_parser<detail::mbchar_parse_functor<CodeSet> > mbchar_parser() 00442 { 00443 return boost::spirit::functor_parser<detail::mbchar_parse_functor<CodeSet> >(); 00444 } 00445 inline const boost::spirit::functor_parser<detail::mbchar_parse_functor<> > mbchar_parser( codeset_t codeset ) 00446 { 00447 return boost::spirit::functor_parser<detail::mbchar_parse_functor<> >( detail::mbchar_parse_functor<>( codeset ) ); 00448 } 00449 00450 extern const boost::spirit::functor_parser<detail::mbchar_parse_functor<ascii> > ascii_p; 00451 extern const boost::spirit::functor_parser<detail::mbchar_parse_functor<shift_jis> > shift_jis_p; 00452 extern const boost::spirit::functor_parser<detail::mbchar_parse_functor<euc_jp> > euc_jp_p; 00453 extern const boost::spirit::functor_parser<detail::mbchar_parse_functor<utf8> > utf8_p; 00454 00462 inline const boost::spirit::functor_parser<detail::ucn_parse_functor> ucn_parser() 00463 { 00464 return boost::spirit::functor_parser<detail::ucn_parse_functor>(); 00465 } 00466 00467 extern const boost::spirit::functor_parser<detail::ucn_parse_functor> ucn_p; 00468 00475 template <int CodeSet> 00476 inline const boost::spirit::functor_parser<detail::c_strlit_parse_functor<CodeSet> > c_strlit_parser() 00477 { 00478 return boost::spirit::functor_parser<detail::c_strlit_parse_functor<CodeSet> >(); 00479 } 00480 00481 typedef boost::spirit::functor_parser<detail::c_strlit_parse_functor<> > c_strlit_parser_t; 00482 00489 inline const boost::spirit::functor_parser<detail::c_strlit_parse_functor<> > c_strlit_parser( codeset_t codeset ) 00490 { 00491 return boost::spirit::functor_parser<detail::c_strlit_parse_functor<> >( detail::c_strlit_parse_functor<>( codeset ) ); 00492 } 00493 00494 extern const boost::spirit::functor_parser<detail::c_strlit_parse_functor<ascii> > ascii_str_p; 00495 extern const boost::spirit::functor_parser<detail::c_strlit_parse_functor<shift_jis> > shift_jis_str_p; 00496 extern const boost::spirit::functor_parser<detail::c_strlit_parse_functor<euc_jp> > euc_jp_str_p; 00497 extern const boost::spirit::functor_parser<detail::c_strlit_parse_functor<utf8> > utf8_str_p; 00498 00505 template <int CodeSet> 00506 inline const boost::spirit::functor_parser<detail::c_chlit_parse_functor<CodeSet> > c_chlit_parser() 00507 { 00508 return boost::spirit::functor_parser<detail::c_chlit_parse_functor<CodeSet> >(); 00509 } 00510 00511 typedef boost::spirit::functor_parser<detail::c_chlit_parse_functor<> > c_chlit_parser_t; 00512 00519 inline const boost::spirit::functor_parser<detail::c_chlit_parse_functor<> > c_chlit_parser( codeset_t codeset ) 00520 { 00521 return boost::spirit::functor_parser<detail::c_chlit_parse_functor<> >( detail::c_chlit_parse_functor<>( codeset ) ); 00522 } 00523 00524 extern const boost::spirit::functor_parser<detail::c_chlit_parse_functor<ascii> > ascii_ch_p; 00525 extern const boost::spirit::functor_parser<detail::c_chlit_parse_functor<shift_jis> > shift_jis_ch_p; 00526 extern const boost::spirit::functor_parser<detail::c_chlit_parse_functor<euc_jp> > euc_jp_ch_p; 00527 extern const boost::spirit::functor_parser<detail::c_chlit_parse_functor<utf8> > utf8_ch_p; 00528 00529 typedef boost::spirit::functor_parser<detail::c_identifier_parse_functor> c_ident_parser_t; 00530 00543 inline const boost::spirit::functor_parser<detail::c_identifier_parse_functor> c_ident_parser( bool ucn = false, bool c_plus_plus = false ) 00544 { 00545 return boost::spirit::functor_parser<detail::c_identifier_parse_functor>( detail::c_identifier_parse_functor( ucn, c_plus_plus ) ); 00546 } 00547 00548 extern const boost::spirit::functor_parser<detail::c_identifier_parse_functor> c_ident_p; 00549 extern const boost::spirit::functor_parser<detail::c_identifier_parse_functor> c99_ident_p; 00550 extern const boost::spirit::functor_parser<detail::c_identifier_parse_functor> c_plus_plus_ident_p; 00551 00552 } 00553 00554 #endif // ! TOPPERS_PARSER_HPP_ Copyright © 2006 by TAKAGI Nobuhisa. このページは Wed Apr 12 16:31:57 2006 に Doxygen によって生成されました。 |