OSDN Git Service

46127c7328f8d5875ee7c1126a936db8b01cc21d
[toppersasp4lpc/asp.git] / asp / cfg / toppers / itronx / static_api_parser.hpp
1 /*
2  *  TOPPERS Software
3  *      Toyohashi Open Platform for Embedded Real-Time Systems
4  *
5  *  Copyright (C) 2005-2010 by TAKAGI Nobuhisa
6  * 
7  *  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8  *  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9  *  変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12  *      スコード中に含まれていること.
13  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16  *      の無保証規定を掲載すること.
17  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19  *      と.
20  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
22  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23  *        報告すること.
24  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26  *      また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27  *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28  *      免責すること.
29  * 
30  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32  *  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33  *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34  *  の責任を負わない.
35  * 
36  */
37
38 /*!
39  *  \file   toppers/itronx/static_api_parser.hpp
40  *  \brief  静的APIの文法に関する宣言定義
41  *
42  *  このファイルで定義されるクラス
43  *  \code
44  *  struct static_api_parser;
45  *  struct static_api_parser::error_handler;
46  *  struct static_api_parser::definition< Scanner >;
47  *  \endcode
48  */
49 #ifndef TOPPERS_ITRONX_STATIC_API_PARSER_HPP_
50 #define TOPPERS_ITRONX_STATIC_API_PARSER_HPP_
51
52 #include "toppers/diagnostics.hpp"
53 #include "toppers/c_expr.hpp"
54 #include <boost/spirit/include/classic_error_handling.hpp>
55
56 namespace toppers
57 {
58   namespace itronx
59   {
60
61     /*!
62      *  \struct static_api_parser static_api_parser.hpp "toppers/itronx/static_api_parser.hpp"
63      *  \brief  静的APIの構文解析クラス
64      */
65     struct static_api_parser : boost::spirit::classic::grammar< static_api_parser >
66     {
67       enum rule_id_t
68       {
69         id_top = 1, id_api_name, id_parameter_list, id_parameter, id_packet, id_cexpr
70       };
71       enum expected_t
72       {
73         open_paren_expected, close_paren_expected, open_brace_expected, close_brace_expected,
74         comma_expected, semicolon_expected
75       };
76
77       /*!
78        *  \struct error_handler static_api_parser.hpp "toppers/itronx/static_api_parser.hpp"
79        *  \brief  静的APIの構文解析におけるエラー処理ファンクタ
80        */
81       struct error_handler
82       {
83         template < class Scanner, class Error >
84           boost::spirit::classic::error_status<> operator()( Scanner const& scan, Error const& error ) const
85         {
86           typename Error::iterator_t iter( error.where );
87           std::string str;
88           text_line ln;
89           if ( iter != scan.last )
90           {
91             while ( *iter != '\0' && *iter != '\n' )
92             {
93               ++iter;
94             }
95             str = '\"' + std::string( error.where, iter ) + '\"';
96             ln = get_text_line( error.where );
97           }
98           else
99           {
100             str = "\"end of file\"";
101             ln = get_text_line( iter - 1 );
102           }
103
104           switch ( error.descriptor )
105           {
106           case open_paren_expected:
107             toppers::fatal( ln, _( "missing `%1%\' before %2%" ), '(', str );
108             break;
109           case close_paren_expected:
110             toppers::fatal( ln, _( "missing `%1%\' before %2%" ), ')', str );
111             break;
112           case close_brace_expected:
113             toppers::fatal( ln, _( "missing `%1%\' before %2%" ), '}', str );
114             break;
115           case semicolon_expected:
116             toppers::fatal( ln, _( "missing `%1%\' before %2%" ), ';', str );
117             break;
118           }
119           return  boost::spirit::classic::error_status<>( boost::spirit::classic::error_status<>::fail );
120         }
121       };
122
123       /*!
124        *  \struct definition static_api_parser.hpp "toppers/itronx/static_api_parser.hpp" 
125        *  \brief  静的APIの構文解析における文法定義
126        */
127       template < class Scanner >
128         struct definition
129       {
130         typedef boost::spirit::classic::rule< Scanner, boost::spirit::classic::dynamic_parser_tag > rule_t;
131         typedef boost::spirit::classic::guard< expected_t > guard_t;
132         typedef boost::spirit::classic::assertion< expected_t > assertion_t;
133
134         c_strlit_parser_t const c_strlit_p;
135         c_ident_parser_t const c_ident_p;
136
137         rule_t  top, api_name, parameter_list, parameter, packet, cexpr;
138         guard_t guard_api, guard_packet;
139         assertion_t expect_open_paren,
140                     expect_close_paren,
141                     expect_close_brace,
142                     expect_comma, expect_semicolon;
143
144         /*!
145          *  \brief  コンストラクタ
146          *  \param  self  構文解析クラス(文法クラス)への参照
147          */
148         definition( static_api_parser const& self )
149           : c_strlit_p( c_strlit_parser( self.cexpr_p_.codeset_ ) ),
150             c_ident_p( c_ident_parser( self.cexpr_p_.ucn_, self.cexpr_p_.c_plus_plus_ ) ),
151             expect_open_paren( open_paren_expected ),
152             expect_close_paren( close_paren_expected ),
153             expect_close_brace( close_brace_expected ),
154             expect_comma( comma_expected ),
155             expect_semicolon( semicolon_expected )
156         {
157           using namespace boost::spirit::classic;
158           set_id();
159           top =
160               guard_api
161               (
162                 api_name >> 
163                   str_p( "(" ) >>
164                   !parameter_list >>
165                   expect_close_paren( str_p( ")" ) ) >>
166                   expect_semicolon( ch_p( ';' ) )
167               )
168               [
169                 error_handler()
170               ];
171           api_name =
172               c_ident_p[ push_back_a( self.tokens_ ) ];
173           parameter_list =
174               parameter % ',';
175           parameter =
176               packet | cexpr;
177           packet =
178               guard_packet
179               (
180                 str_p( "{" )[ push_back_a( self.tokens_ ) ] >>
181                 parameter_list >>
182                 expect_close_brace( str_p( "}" )[ push_back_a( self.tokens_ ) ] ) 
183               )
184               [
185                 error_handler()
186               ];
187           cexpr =
188               self.cexpr_p_[ push_back_a( self.tokens_ ) ];
189         }
190         void set_id()
191         {
192           top.set_id( id_top );
193           api_name.set_id( id_api_name );
194           parameter_list.set_id( id_parameter_list );
195           parameter.set_id( id_parameter );
196           packet.set_id( id_packet );
197           cexpr.set_id( id_cexpr );
198         }
199         rule_t const& start() const { return top; }
200       };
201       /*!
202        *  \brief  コンストラクタ
203        *  \param  tokens  静的APIの構成トークンの格納先
204        *  \param  cexpr_p C言語の定数式構文解析関数オブジェクト
205        */
206       explicit static_api_parser( std::vector< std::string >& tokens, c_const_expr_parser const& cexpr_p )
207         : tokens_( tokens ), cexpr_p_( cexpr_p )
208       {
209       }
210
211       std::vector< std::string >& tokens_;
212       c_const_expr_parser const& cexpr_p_;
213     };
214
215   }
216 }
217
218 #endif  // ! TOPPERS_ITRONX_STATIC_API_PARSER_HPP_