c_expr.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 
00048 #ifndef TOPPERS_C_EXPR_HPP_
00049 #define TOPPERS_C_EXPR_HPP_
00050 
00051 #include "toppers/parser.hpp"
00052 #include <boost/cstdint.hpp>
00053 
00054 namespace toppers
00055 {
00056 
00079   template <class Derived>
00080   struct c_expr_parser_base : boost::spirit::grammar<Derived>
00081   {
00082   public:
00087     template <class Scanner>
00088     struct definition
00089     {
00090       typedef boost::spirit::rule<Scanner> rule_t;
00091       rule_t  primary_expression,   
00092               expression,
00093               constant_expression,
00094               conditional_expression,
00095               assignment_expression,
00096               assignment_operator,
00097               postfix_expression,
00098               unary_expression,
00099               unary_operator,
00100               cast_expression,
00101               multiplicative_expression,
00102               additive_expression,
00103               shift_expression,
00104               relational_expression,
00105               equality_expression,
00106               AND_expression,
00107               exclusive_OR_expression,
00108               inclusive_OR_expression,
00109               logical_AND_expression,
00110               logical_OR_expression,
00111               string_literal,
00112               constant,
00113               floating_constant,
00114               decimal_floating_constant,
00115               hexadecimal_floating_constant,
00116               integer_constant,
00117               character_constant,
00118               declaration_specifiers,
00119               type_name,
00120               specifier_qualifier_list,
00121               storage_class_specifier,
00122               type_specifier,
00123               type_qualifier,
00124               declarator,
00125               direct_declarator,
00126               struct_or_union_specifier,
00127               struct_declaration,
00128               struct_declarator,
00129               enum_specifier,
00130               enumerator,
00131               abstract_declarator,
00132               pointer,
00133               parameter_type_list,
00134               parameter_list,
00135               parameter_declaration,
00136               direct_abstract_declarator;
00137 
00138       c_ident_parser_t identifier;
00139       c_strlit_parser_t c_strlit_p;
00140       c_chlit_parser_t c_chlit_p;
00141 
00146       definition( const Derived& self )
00147         : identifier( c_ident_parser( self.ucn_, self.c_plus_plus_ ) ),
00148           c_strlit_p( c_strlit_parser( self.codeset_ ) ),
00149           c_chlit_p( c_chlit_parser( self.codeset_ ) )
00150       {
00151         using namespace boost::spirit;
00152         static const functor_parser<detail::c_integer_constant_parse_functor<boost::uintmax_t> > c_int_const_p;
00153         static const functor_parser<detail::c_integer_suffix_parse_functor> c_int_suffix_p;
00154 
00155         primary_expression =  // 複合リテラル未対応
00156             identifier
00157           | constant
00158           | string_literal
00159           | ( '(' >> expression >> ')' );
00160         expression =
00161             assignment_expression % ',';
00162         constant_expression = 
00163             conditional_expression;
00164         conditional_expression =
00165             logical_OR_expression >> *( '\?' >> expression >> ':' >> logical_OR_expression );
00166         assignment_expression =
00167            *( unary_expression >> assignment_operator ) >> conditional_expression;
00168         assignment_operator =
00169             ch_p( '=' ) | "*=" | "/=" | "%=" | "+=" | "?=" | "<<=" | ">>=" | "&=" | "^=" | "|=";
00170         postfix_expression =
00171             primary_expression >>
00172           *(
00173                 ( '[' >> expression >> ']' )
00174               | ( '(' >> list_p( assignment_expression, ',' ) >> ')' )
00175               | ( '.' >> identifier )
00176               | ( "->" >> identifier )
00177               | "++"
00178               | "--"
00179             );
00180         unary_expression =
00181            *( str_p( "++" ) || "--" ) >>
00182             (
00183                 ( "sizeof" >> unary_expression )
00184               | ( str_p( "sizeof" ) >> '(' >> type_name >> ')' )
00185               | postfix_expression
00186               | ( unary_operator >> cast_expression )
00187             );
00188         unary_operator =
00189             chset<>( "&*~!+-" );
00190         cast_expression =
00191            *( '(' >> type_name >> ')' ) >> unary_expression;
00192         multiplicative_expression =
00193             cast_expression >>
00194            *(
00195                 ( '*' >> cast_expression )
00196               | ( '/' >> cast_expression )
00197               | ( '%' >> cast_expression )
00198             );
00199         additive_expression =
00200             multiplicative_expression >>
00201            *(
00202                 ( '+' >> multiplicative_expression )
00203               | ( '-' >> multiplicative_expression )
00204             );
00205         shift_expression =
00206             additive_expression >>
00207            *(
00208                 ( "<<" >> additive_expression )
00209               | ( ">>" >> additive_expression )
00210             );
00211         relational_expression =
00212             shift_expression >>
00213            *(
00214                 ( '<' >> shift_expression )
00215               | ( '>' >> shift_expression )
00216               | ( "<=" >> shift_expression )
00217               | ( ">=" >> shift_expression )
00218             );
00219         equality_expression =
00220             relational_expression >>
00221            *(
00222                 ( "==" >> relational_expression )
00223               | ( "!=" >> relational_expression )
00224             );
00225         AND_expression =
00226             equality_expression >> *( '&' >> equality_expression );
00227         exclusive_OR_expression =
00228             AND_expression >> *( '^' >> AND_expression );
00229         inclusive_OR_expression =
00230             exclusive_OR_expression >> *( '|' >> exclusive_OR_expression );
00231         logical_AND_expression =
00232             inclusive_OR_expression >> *( "&&" >> inclusive_OR_expression );
00233         logical_OR_expression =
00234             logical_AND_expression >> *( "||" >> logical_AND_expression );
00235         string_literal =
00236             c_strlit_p
00237           | lexeme_d[ 'L' >> c_strlit_p ];
00238         constant =
00239             floating_constant
00240           | integer_constant
00241           | identifier  // 列挙定数
00242           | character_constant;
00243         floating_constant =
00244             decimal_floating_constant
00245           | hexadecimal_floating_constant;
00246         decimal_floating_constant =
00247             lexeme_d
00248             [
00249               as_lower_d
00250               [
00251                 ( ( *digit_p >> '.' >> +digit_p ) | ( +digit_p >> '.' ) ) >>
00252                 'e' >> !chset<>( "+-" ) >> +digit_p >>
00253                 !chset<>( "fl" )
00254               ]
00255             ];
00256         hexadecimal_floating_constant =
00257             lexeme_d
00258             [
00259               as_lower_d
00260               [
00261                 "0x" >>
00262                 ( ( *xdigit_p >> '.' >> +xdigit_p ) | ( +xdigit_p >> '.' ) ) >>
00263                 'p' >> !chset<>( "+-" ) >> +digit_p >>
00264                 !chset<>( "fl" )
00265               ]
00266             ];
00267         integer_constant =
00268             lexeme_d[ c_int_const_p >> !c_int_suffix_p ];
00269         character_constant =
00270             c_chlit_p
00271           | lexeme_d[ 'L' >> c_chlit_p ];
00272         declaration_specifiers =
00273            +( storage_class_specifier | type_specifier | type_qualifier );
00274         type_name =
00275             specifier_qualifier_list >> !abstract_declarator;
00276         specifier_qualifier_list =
00277            +( type_specifier | type_qualifier );
00278         storage_class_specifier =
00279             str_p( "auto" )
00280           | "register"
00281           | "static"
00282           | "extern"
00283           | "typedef";
00284         type_specifier =
00285             str_p( "void" ) | "char" | "short" | "int" | "long" | "float" | "double"
00286           | "signed" | "unsigned"
00287           | identifier
00288           | struct_or_union_specifier
00289           | enum_specifier;
00290         type_qualifier =
00291             str_p( "const" ) | "volatile" | "restrict";
00292         declarator =
00293             !pointer >> direct_declarator;
00294         direct_declarator = 
00295             ( identifier | ( '(' >> declarator >> ')' ) )
00296             >>
00297           *(
00298                 ( '[' >> !constant_expression >> ']' )
00299               | ( '(' >> parameter_type_list >> ')' )
00300               | ( '(' >> !( identifier % ',' ) >> ')' )
00301             );
00302         struct_or_union_specifier =
00303             lexeme_d[ ( str_p( "struct" ) | "union" ) >> +space_p >> identifier ]
00304           | ( lexeme_d[ ( str_p( "struct" ) | "union" ) >> +space_p >> !identifier ] >> '{' >> +struct_declaration >> '}' );
00305         struct_declaration =
00306             specifier_qualifier_list >> !list_p( struct_declarator, ',' ) >> ';';
00307             // lisp_p( struct_declarator, ',' )を省略可能としているのは、
00308             // struct_declaratorのidentifierをspecifier_qualifier_listが
00309             // typedef名と間違うことを回避するため
00310         struct_declarator =
00311             ( !declarator >> ':' >> constant_expression ) // ビットフィールド
00312           | declarator;
00313         enum_specifier =
00314             ( lexeme_d[ "enum" >> +space_p >> !identifier ] >> '{' >> list_p( enumerator, ',', ',' ) >> '}' )   // C99では末尾のカンマがあってもよい
00315           | lexeme_d[ "enum" >> +space_p >> identifier ];
00316         enumerator =
00317             identifier >> !( '=' >> constant_expression );
00318         abstract_declarator =
00319             ( !pointer >> direct_abstract_declarator )
00320           | pointer;
00321         pointer =
00322            +( '*' >> *type_qualifier );
00323         parameter_type_list =
00324             parameter_list >> !( ch_p( ',' ) >> "..." );  // 可変個引数
00325         parameter_list =
00326             parameter_declaration % ',';
00327         parameter_declaration = 
00328             ( declaration_specifiers >> declarator )
00329           | ( declaration_specifiers >> !abstract_declarator );
00330         direct_abstract_declarator =
00331             (
00332              !( '(' >> abstract_declarator >> ')' ) >>
00333              +(
00334                   ( '[' >> !constant_expression >> ']' )
00335                 | ( '(' >> !parameter_type_list >> ')' ) 
00336               )
00337             )
00338           | ( '(' >> abstract_declarator >> ')' );
00339       }
00340     };
00341     bool ucn_;
00342     codeset_t codeset_;
00343     bool c_plus_plus_;
00344 
00351     explicit c_expr_parser_base( bool ucn = false, codeset_t codeset = ascii, bool c_plus_plus = false )
00352       : ucn_( ucn ), codeset_( codeset ), c_plus_plus_( c_plus_plus )
00353     {
00354     }
00355   };
00356 
00361   struct c_expr_parser : c_expr_parser_base<c_expr_parser>
00362   {
00363     typedef c_expr_parser_base<c_expr_parser> base_t;
00364 
00369     template <class Scanner>
00370     struct definition : base_t::definition<Scanner>
00371     {
00372       typedef typename base_t::definition<Scanner>::rule_t rule_t;
00373 
00374       definition( const c_expr_parser& self ) : base_t::definition<Scanner>( self ) {}
00375       const rule_t& start() const { return expression; };
00376     };
00377 
00383     explicit c_expr_parser( bool ucn = false, codeset_t codeset = ascii )
00384       : c_expr_parser_base<c_expr_parser>( ucn, codeset )
00385     {
00386     }
00387   };
00388 
00393   struct c_const_expr_parser : c_expr_parser_base<c_const_expr_parser>
00394   {
00395     typedef c_expr_parser_base<c_const_expr_parser> base_t;
00396 
00401     template <class Scanner>
00402     struct definition : base_t::definition<Scanner>
00403     {
00404       typedef typename base_t::definition<Scanner>::rule_t rule_t;
00405 
00406       definition( const c_const_expr_parser& self ) : base_t::definition<Scanner>( self ) {}
00407       const rule_t& start() const { return constant_expression; };
00408     };
00409 
00415     explicit c_const_expr_parser( bool ucn = false, codeset_t codeset = ascii )
00416       : c_expr_parser_base<c_const_expr_parser>( ucn, codeset )
00417     {
00418     }
00419   };
00420 
00421 }
00422 
00423 #endif  // ! TOPPERS_C_EXPR_HPP_

Copyright © 2006 by TAKAGI Nobuhisa.
このページは Wed Apr 12 16:31:55 2006 に Doxygen によって生成されました。