source: cfg_oil/trunk/toppers/c_expr.hpp@ 8

Last change on this file since 8 was 8, checked in by msugi, 14 years ago

ディレクトリ構造の作成,ソース一式とReleaseビルドのコミット.

File size: 15.5 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
6 *
7 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
8 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
9 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
10 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
11 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
12 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
13 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
14 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
15ƒƒ“ƒgi—˜—p
16 * ŽÒƒ}ƒjƒ…
17ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
18 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
19 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
20 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
21 * ‚ƁD
22 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
23ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
24ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
25 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
26 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
27 * •ñ‚·‚邱‚ƁD
28 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
29 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
30 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
31 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
32 * –Ɛӂ·‚邱‚ƁD
33 *
34 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
35 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
36 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
37 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
38 * ‚̐ӔC‚𕉂í‚È‚¢D
39 *
40 */
41
42/*!
43 * \file toppers/c_expr.hpp
44 * \brief CŒ¾Œê‚ÌŽ®‚̍\•¶‰ðÍ‚ÉŠÖ‚·‚ééŒ¾’è‹`
45 *
46 * ‚±‚̃tƒ@ƒCƒ‹‚Å’è‹`‚³‚ê‚éƒNƒ‰ƒX
47 * \code
48 * struct c_expr_parser_base< Derived >;
49 * struct c_expr_parser;
50 * struct c_const_expr_parser;
51 * \endcode
52 */
53#ifndef TOPPERS_C_EXPR_HPP_
54#define TOPPERS_C_EXPR_HPP_
55
56#include "toppers/c_parser.hpp"
57#include <boost/cstdint.hpp>
58
59namespace toppers
60{
61
62 /*!
63 * \struct c_expr_parser_base c_expr.hpp "toppers/c_expr.hpp"
64 * \brief CŒ¾Œê‚ÌŽ®‚ð\•¶‰ðÍ‚·‚邽‚ß‚ÌŠî’êƒNƒ‰ƒX
65 *
66 * ŽÀÛ‚ÉŽg—p‚·‚éÛ‚́A c_expr_parser_base ‚¨‚æ‚Ñ c_expr_parser_base::definition
67 * ƒNƒ‰ƒX‚ð”h¶‚·‚é•K—v‚ª‚ ‚è‚Ü‚·B c_expr_parser_base::definition ‚Ì”h¶ƒNƒ‰ƒX‚ł́A
68 * start ƒƒ“ƒoŠÖ”‚ð’è‹`‚µ‚āA\•¶’†‚Ì•K—v‚ȃ‹[ƒ‹‚ðŽæ‚èo‚·‚悤‚É‚µ‚Ä‚­‚¾‚³‚¢B
69 * ‚±‚¤‚·‚邱‚ƂŁA’萔Ž®‚Ì•¶–@AˆêŽŸŽ®‚Ì•¶–@‚Æ‚¢‚Á‚½‚悤‚ɁACŒ¾Œê‚Ì•¶–@‚̃Tƒu
70 * ƒZƒbƒg‚ð—eˆÕ‚ɍì‚èo‚·‚±‚Æ‚ª‚Å‚«‚Ü‚·B
71 *
72 * \code
73 * // ˆêŽŸŽ®‚ðŽæ‚èo‚·—á
74 * struct c_primary_expression : c_expr_parser_base< c_primary_expression >
75 * {
76 * template < class Scanner >
77 * struct definition : c_expr_parser_base< c_primary_expression >::definition
78 * {
79 * rule_t const& start() const { return primary_expression; }
80 * };
81 * };
82 * \endcode
83 */
84 template < class Derived >
85 struct c_expr_parser_base : boost::spirit::grammar< Derived >
86 {
87 public:
88 /*!
89 * \struct definition c_expr.hpp "toppers/c_expr.hpp"
90 * \brief •¶–@’è‹`
91 */
92 template < class Scanner >
93 struct definition
94 {
95 typedef boost::spirit::rule< Scanner > rule_t;
96 rule_t primary_expression,
97 expression,
98 constant_expression,
99 conditional_expression,
100 assignment_expression,
101 assignment_operator,
102 postfix_expression,
103 unary_expression,
104 unary_operator,
105 cast_expression,
106 multiplicative_expression,
107 additive_expression,
108 shift_expression,
109 relational_expression,
110 equality_expression,
111 AND_expression,
112 exclusive_OR_expression,
113 inclusive_OR_expression,
114 logical_AND_expression,
115 logical_OR_expression,
116 string_literal,
117 constant,
118 floating_constant,
119 decimal_floating_constant,
120 hexadecimal_floating_constant,
121 integer_constant,
122 character_constant,
123 declaration_specifiers,
124 type_name,
125 specifier_qualifier_list,
126 storage_class_specifier,
127 type_specifier,
128 type_qualifier,
129 declarator,
130 direct_declarator,
131 struct_or_union_specifier,
132 struct_declaration,
133 struct_declarator,
134 enum_specifier,
135 enumerator,
136 abstract_declarator,
137 pointer,
138 parameter_type_list,
139 parameter_list,
140 parameter_declaration,
141 direct_abstract_declarator;
142
143 c_ident_parser_t identifier;
144 c_strlit_parser_t c_strlit_p;
145 c_chlit_parser_t c_chlit_p;
146
147 /*!
148 * \brief ƒRƒ“ƒXƒgƒ‰ƒNƒ^
149 * \param self •¶–@ƒNƒ‰ƒXi c_expr_parser_base< Derived > ƒNƒ‰ƒX‚©‚ç‚ÌŒp³j‚Ö‚ÌŽQÆ
150 */
151 definition( Derived const& self )
152 : identifier( c_ident_parser( self.ucn_, self.c_plus_plus_ ) ),
153 c_strlit_p( c_strlit_parser( self.codeset_ ) ),
154 c_chlit_p( c_chlit_parser( self.codeset_ ) )
155 {
156 using namespace boost::spirit;
157 static functor_parser< detail::c_integer_constant_parse_functor< boost::uintmax_t > > const c_int_const_p;
158 static functor_parser< detail::c_integer_suffix_parse_functor > const c_int_suffix_p;
159
160 primary_expression = // •¡‡ƒŠƒeƒ‰ƒ‹–¢‘Ήž
161 identifier
162 | constant
163 | string_literal
164 | ( '(' >> expression >> ')' );
165 expression =
166 assignment_expression % ',';
167 constant_expression =
168 conditional_expression;
169 conditional_expression =
170 logical_OR_expression >> *( '\?' >> expression >> ':' >> logical_OR_expression );
171 assignment_expression =
172 *( unary_expression >> assignment_operator ) >> conditional_expression;
173 assignment_operator =
174 ch_p( '=' ) | "*=" | "/=" | "%=" | "+=" | "?=" | "<<=" | ">>=" | "&=" | "^=" | "|=";
175 postfix_expression =
176 primary_expression >>
177 *(
178 ( '[' >> expression >> ']' )
179 | ( '(' >> list_p( assignment_expression, ',' ) >> ')' )
180 | ( '.' >> identifier )
181 | ( "->" >> identifier )
182 | "++"
183 | "--"
184 );
185 unary_expression =
186 *( str_p( "++" ) || "--" ) >>
187 (
188 ( "sizeof" >> unary_expression )
189 | ( str_p( "sizeof" ) >> '(' >> type_name >> ')' )
190 | postfix_expression
191 | ( unary_operator >> cast_expression )
192 );
193 unary_operator =
194 chset<>( "&*~!+-" );
195 cast_expression =
196 *( '(' >> type_name >> ')' ) >> unary_expression
197 | +( '(' >> ( type_name | identifier ) >> ')' ); // \•¶‰ðÍ‚ÉŽ¸”s‚·‚é•s‹ï‡‘΍ô
198 multiplicative_expression =
199 cast_expression >>
200 *(
201 ( '*' >> cast_expression )
202 | ( '/' >> cast_expression )
203 | ( '%' >> cast_expression )
204 );
205 additive_expression =
206 multiplicative_expression >>
207 *(
208 ( '+' >> multiplicative_expression )
209 | ( '-' >> multiplicative_expression )
210 );
211 shift_expression =
212 additive_expression >>
213 *(
214 ( "<<" >> additive_expression )
215 | ( ">>" >> additive_expression )
216 );
217 relational_expression =
218 shift_expression >>
219 *(
220 ( '<' >> shift_expression )
221 | ( '>' >> shift_expression )
222 | ( "<=" >> shift_expression )
223 | ( ">=" >> shift_expression )
224 );
225 equality_expression =
226 relational_expression >>
227 *(
228 ( "==" >> relational_expression )
229 | ( "!=" >> relational_expression )
230 );
231 AND_expression =
232 equality_expression >> *( '&' >> equality_expression );
233 exclusive_OR_expression =
234 AND_expression >> *( '^' >> AND_expression );
235 inclusive_OR_expression =
236 exclusive_OR_expression >> *( '|' >> exclusive_OR_expression );
237 logical_AND_expression =
238 inclusive_OR_expression >> *( "&&" >> inclusive_OR_expression );
239 logical_OR_expression =
240 logical_AND_expression >> *( "||" >> logical_AND_expression );
241 string_literal =
242 c_strlit_p
243 | lexeme_d[ 'L' >> c_strlit_p ];
244 constant =
245 floating_constant
246 | integer_constant
247 | identifier // —ñ‹“’萔
248 | character_constant;
249 floating_constant =
250 decimal_floating_constant
251 | hexadecimal_floating_constant;
252 decimal_floating_constant =
253 lexeme_d
254 [
255 as_lower_d
256 [
257 ( ( *digit_p >> '.' >> +digit_p ) | ( +digit_p >> '.' ) ) >>
258 'e' >> !chset<>( "+-" ) >> +digit_p >>
259 !chset<>( "fl" )
260 ]
261 ];
262 hexadecimal_floating_constant =
263 lexeme_d
264 [
265 as_lower_d
266 [
267 "0x" >>
268 ( ( *xdigit_p >> '.' >> +xdigit_p ) | ( +xdigit_p >> '.' ) ) >>
269 'p' >> !chset<>( "+-" ) >> +digit_p >>
270 !chset<>( "fl" )
271 ]
272 ];
273 integer_constant =
274 lexeme_d[ c_int_const_p >> !c_int_suffix_p ];
275 character_constant =
276 c_chlit_p
277 | lexeme_d[ 'L' >> c_chlit_p ];
278 declaration_specifiers =
279 +( storage_class_specifier | type_specifier | type_qualifier );
280 type_name =
281 specifier_qualifier_list >> !abstract_declarator;
282 specifier_qualifier_list =
283 +( type_specifier | type_qualifier );
284 storage_class_specifier =
285 str_p( "auto" )
286 | "register"
287 | "static"
288 | "extern"
289 | "typedef";
290 type_specifier =
291 str_p( "void" ) | "char" | "short" | "int" | "long" | "float" | "double"
292 | "signed" | "unsigned"
293 | identifier
294 | struct_or_union_specifier
295 | enum_specifier;
296 type_qualifier =
297 str_p( "const" ) | "volatile" | "restrict";
298 declarator =
299 !pointer >> direct_declarator;
300 direct_declarator =
301 ( identifier | ( '(' >> declarator >> ')' ) )
302 >>
303 *(
304 ( '[' >> !constant_expression >> ']' )
305 | ( '(' >> parameter_type_list >> ')' )
306 | ( '(' >> !( identifier % ',' ) >> ')' )
307 );
308 struct_or_union_specifier =
309 lexeme_d[ ( str_p( "struct" ) | "union" ) >> +space_p >> identifier ]
310 | ( lexeme_d[ ( str_p( "struct" ) | "union" ) >> +space_p >> !identifier ] >> '{' >> +struct_declaration >> '}' );
311 struct_declaration =
312 specifier_qualifier_list >> !list_p( struct_declarator, ',' ) >> ';';
313 // lisp_p( struct_declarator, ',' )‚ðÈ—ª‰Â”\‚Æ‚µ‚Ä‚¢‚é‚̂́A
314 // struct_declarator ‚Ì identifier ‚ð specifier_qualifier_list ‚ª
315 // typedef –¼‚ƊԈႤ‚±‚Æ‚ð‰ñ”ð‚·‚é‚½‚ß
316 struct_declarator =
317 ( !declarator >> ':' >> constant_expression ) // ƒrƒbƒgƒtƒB[ƒ‹ƒh
318 | declarator;
319 enum_specifier =
320 ( lexeme_d[ "enum" >> +space_p >> !identifier ] >> '{' >> list_p( enumerator, ',', ',' ) >> '}' ) // C99‚Å‚Í––”ö‚̃Jƒ“ƒ}‚ª‚ ‚Á‚Ä‚à‚æ‚¢
321 | lexeme_d[ "enum" >> +space_p >> identifier ];
322 enumerator =
323 identifier >> !( '=' >> constant_expression );
324 abstract_declarator =
325 ( !pointer >> direct_abstract_declarator )
326 | pointer;
327 pointer =
328 +( '*' >> *type_qualifier );
329 parameter_type_list =
330 parameter_list >> !( ch_p( ',' ) >> "..." ); // ‰Â•ÏŒÂˆø”
331 parameter_list =
332 parameter_declaration % ',';
333 parameter_declaration =
334 ( declaration_specifiers >> declarator )
335 | ( declaration_specifiers >> !abstract_declarator );
336 direct_abstract_declarator =
337 (
338 !( '(' >> abstract_declarator >> ')' ) >>
339 +(
340 ( '[' >> !constant_expression >> ']' )
341 | ( '(' >> !parameter_type_list >> ')' )
342 )
343 )
344 | ( '(' >> abstract_declarator >> ')' );
345 }
346 };
347 bool ucn_;
348 codeset_t codeset_;
349 bool c_plus_plus_;
350
351 /*!
352 * \brief ƒRƒ“ƒXƒgƒ‰ƒNƒ^
353 * \param ucn ‘Û•¶Žš–¼‚ɑΉž‚·‚éê‡‚Í true ‚ðŽw’è‚·‚é
354 * \param codeset •¶ŽšƒR[ƒh
355 * \param c_plus_plus C++ ‚ɑΉž‚·‚éê‡‚Í true ‚ðŽw’è‚·‚é
356 */
357 explicit c_expr_parser_base( bool ucn = false, codeset_t codeset = ascii, bool c_plus_plus = false )
358 : ucn_( ucn ), codeset_( codeset ), c_plus_plus_( c_plus_plus )
359 {
360 }
361 };
362
363 /*!
364 * \class c_expr_parser c_expr.hpp "toppers/c_expr.hpp"
365 * \brief CŒ¾Œê‚ÌŽ®‚̍\•¶‰ðÍƒNƒ‰ƒX
366 */
367 struct c_expr_parser : c_expr_parser_base< c_expr_parser >
368 {
369 typedef c_expr_parser_base< c_expr_parser > base_t;
370
371 /*!
372 * \struct definition c_expr.hpp "toppers/c_expr.hpp"
373 * \brief •¶–@’è‹`
374 */
375 template < class Scanner >
376 struct definition : base_t::definition< Scanner >
377 {
378 typedef typename base_t::definition< Scanner >::rule_t rule_t;
379
380 definition( c_expr_parser const& self ) : base_t::definition< Scanner >( self ) {}
381 rule_t const& start() const { return base_t::definition< Scanner >::expression; };
382 };
383
384 /*!
385 * \brief ƒRƒ“ƒXƒgƒ‰ƒNƒ^
386 * \param ucn ‘Û•¶Žš–¼‚ɑΉž‚·‚éê‡‚Í true ‚ðŽw’è‚·‚é
387 * \param codeset •¶ŽšƒR[ƒh
388 */
389 explicit c_expr_parser( bool ucn = false, codeset_t codeset = ascii )
390 : c_expr_parser_base< c_expr_parser >( ucn, codeset )
391 {
392 }
393 };
394
395 /*!
396 * \class c_const_expr_parser c_expr.hpp "toppers/c_expr.hpp"
397 * \brief CŒ¾Œê‚̒萔Ž®‚̍\•¶‰ðÍƒNƒ‰ƒX
398 */
399 struct c_const_expr_parser : c_expr_parser_base< c_const_expr_parser >
400 {
401 typedef c_expr_parser_base< c_const_expr_parser > base_t;
402
403 /*!
404 * \struct definition c_expr.hpp "toppers/c_expr.hpp"
405 * \brief •¶–@’è‹`
406 */
407 template < class Scanner >
408 struct definition : base_t::definition< Scanner >
409 {
410 typedef typename base_t::definition< Scanner >::rule_t rule_t;
411
412 definition( c_const_expr_parser const& self ) : base_t::definition< Scanner >( self ) {}
413 rule_t const& start() const { return base_t::definition< Scanner >::constant_expression; };
414 };
415
416 /*!
417 * \brief ƒRƒ“ƒXƒgƒ‰ƒNƒ^
418 * \param ucn ‘Û•¶Žš–¼‚ɑΉž‚·‚éê‡‚Í true ‚ðŽw’è‚·‚é
419 * \param codeset •¶ŽšƒR[ƒh
420 */
421 explicit c_const_expr_parser( bool ucn = false, codeset_t codeset = ascii )
422 : c_expr_parser_base< c_const_expr_parser >( ucn, codeset )
423 {
424 }
425 };
426
427}
428
429#endif // ! TOPPERS_C_EXPR_HPP_
Note: See TracBrowser for help on using the repository browser.