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 によって生成されました。