source: azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 28.0 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2018 by TOPPERS Project
7#--
8# 上記著作権者
9は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
10# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11# 変・再é…
12å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
13# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15# スコード中に含まれていること.
16# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17# 用できる形で再é…
18å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
19å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
20# 者
21マニュアルなど)に,上記の著作権表示,この利用条件および下記
22# の無保証規定を掲載すること.
23# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24# 用できない形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
26# と.
27# (a) 再é…
28å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
29マニュアルなど)に,上記の著
30# 作権表示,この利用条件および下記の無保証規定を掲載すること.
31# (b) 再é…
32å¸ƒã®å½¢æ…
33‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
34# 報告すること.
35# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36# 害からも,上記著作権者
37およびTOPPERSプロジェクトをå…
38è²¬ã™ã‚‹ã“と.
39# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
40# 由に基づく請求からも,上記著作権者
41およびTOPPERSプロジェクトを
42# å…
43è²¬ã™ã‚‹ã“と.
44#
45# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
46お
47# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
48# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
49# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
50# の責任を負わない.
51#
52# $Id$
53#++
54
55class C_parser
56rule
57# トップレベルの構文要素は C_parser
58all: C_parser
59
60# Expr
61########################## 式 ##########################
62# K&Rの文法(プログラミング言語C 第2版 付録)と一部異なる
63# argument_expression_list(関数引数), assignment_expression(代å…
64¥)がない
65# 式の result は、すべてé…
66åˆ—で第一要素が識別シンボル、第二要素以下が引数
67#
68# 2019/3/28 長島 下記のC99の構文に近づくよう変更
69#(読めないヘッダーファイルがあったため)
70# http://www.quut.com/c/ANSI-C-grammar-y-1999.html
71# å…
72ƒã€…
73のコメントと合わなくなっています
74
75primary_expression
76 : namespace_identifier
77 { result = [ :IDENTIFIER, val[0] ] } #1ok
78# : IDENTIFIER # mikan namespace への対応
79# { result = [ :IDENTIFIER, val[0] ] }
80# | TRUE
81# { result = [ :BOOL_CONSTANT, true ] }
82# | FALSE
83# { result = [ :BOOL_CONSTANT, false ] }
84 | INTEGER_CONSTANT
85 { result = [ :INTEGER_CONSTANT, val[0] ] }
86 | FLOATING_CONSTANT
87 { result = [ :FLOATING_CONSTANT, val[0] ] }
88 | OCTAL_CONSTANT
89 { result = [ :OCTAL_CONSTANT, val[0] ] }
90 | HEX_CONSTANT
91 { result = [ :HEX_CONSTANT, val[0] ] }
92 | CHARACTER_LITERAL
93 { result = [ :CHARACTER_LITERAL, val[0] ] }
94 | string_literal_list
95 { result = [ :STRING_LITERAL_LIST, val[0] ] }
96 | '(' expression ')'
97 { result = [ :PARENTHESES, val[1].get_elements ] }
98
99string_literal_list
100 : STRING_LITERAL
101 { result = [val[0]] }
102 | string_literal_list STRING_LITERAL
103 { result << val[1] }
104
105# 関数呼び出しと後置インクリメント、デクリメント演算子がない
106postfix_expression
107 : primary_expression
108 | postfix_expression '[' expression ']'
109 { result = [ :OP_SUBSC, val[0], val[2] ] }
110 | postfix_expression '(' ')'
111 | postfix_expression '(' argument_expression_list ')'
112 | postfix_expression type_qualifier '(' argument_expression_list ')' # intended __asm volatile ( " MNEMONIC OPERAND" );
113 | postfix_expression '.' IDENTIFIER
114 { result = [ :OP_DOT, val[0], val[2] ] }
115 | postfix_expression '->' IDENTIFIER
116 { result = [ :OP_REF, val[0], val[2] ] }
117 | postfix_expression '++' { result = val[0] } # ++, -- は無視する
118 | postfix_expression '--' { result = val[0] }
119 | '(' type_name ')' '{' initializer_list '}'
120 | '(' type_name ')' '{' initializer_list ',' '}'
121
122argument_expression_list
123 : assignment_expression
124 | argument_expression_list ',' assignment_expression
125
126
127# 前置インクリメント、デクリメント演算子がない
128unary_expression
129 : postfix_expression
130 | unary_operator cast_expression
131 { result = [ val[0], val[1] ] }
132 | SIZEOF unary_expression
133 { result = [ :OP_SIZEOF_EXPR, val[1] ] }
134 | SIZEOF '(' type_name ')'
135 { result = [ :OP_SIZEOF_TYPE, val[1] ] }
136 | '++' unary_expression { result = val[1] } # ++, -- は無視する
137 | '--' unary_expression { result = val[1] }
138
139unary_operator
140 : '&' { result = :OP_U_AMP }
141 | '*' { result = :OP_U_ASTER }
142 | '+' { result = :OP_U_PLUS }
143 | '-' { result = :OP_U_MINUS }
144 | '~' { result = :OP_U_TILDE }
145 | '!' { result = :OP_U_EXCLAM }
146
147cast_expression
148 : unary_expression
149 | '(' type_name ')' cast_expression
150 { result = [ :CAST, val[1], val[3] ] }
151
152multiplicative_expression
153 : cast_expression
154 | multiplicative_expression '*' cast_expression
155 { result = [ :OP_MULT, val[0], val[2] ] }
156 | multiplicative_expression '/' cast_expression
157 { result = [ :OP_DIV, val[0], val[2] ] }
158 | multiplicative_expression '%' cast_expression
159 { result = [ :OP_REMAIN, val[0], val[2] ] }
160
161additive_expression
162 : multiplicative_expression
163 | additive_expression '+' multiplicative_expression
164 { result = [ :OP_ADD, val[0], val[2] ] }
165 | additive_expression '-' multiplicative_expression
166 { result = [ :OP_SUB, val[0], val[2] ] }
167
168shift_expression
169 : additive_expression
170 | shift_expression '<<' additive_expression
171 { result = [ :OP_LSFT, val[0], val[2] ] }
172 | shift_expression '>>' additive_expression
173 { result = [ :OP_RSFT, val[0], val[2] ] }
174
175relational_expression
176 : shift_expression
177 | relational_expression '<' shift_expression
178 { result = [ :OP_LT, val[0], val[2] ] }
179 | relational_expression '>' shift_expression
180 { result = [ :OP_GT, val[0], val[2] ] }
181 | relational_expression '<=' shift_expression
182 { result = [ :OP_LE, val[0], val[2] ] }
183 | relational_expression '>=' shift_expression
184 { result = [ :OP_GE, val[0], val[2] ] }
185
186equality_expression
187 : relational_expression
188 | equality_expression '==' relational_expression
189 { result = [ :OP_EQ, val[0], val[2] ] }
190 | equality_expression '!=' relational_expression
191 { result = [ :OP_NE, val[0], val[2] ] }
192
193and_expression
194 : equality_expression
195 | and_expression '&' equality_expression
196 { result = [ :OP_AND, val[0], val[2] ] }
197
198exclusive_or_expression
199 : and_expression
200 | exclusive_or_expression '^' and_expression
201 { result = [ :OP_EOR, val[0], val[2] ] }
202
203inclusive_or_expression
204 : exclusive_or_expression
205 | inclusive_or_expression '|' exclusive_or_expression
206 { result = [ :OP_OR, val[0], val[2] ] }
207
208logical_and_expression
209 : inclusive_or_expression
210 | logical_and_expression '&&' inclusive_or_expression
211 { result = [ :OP_LAND, val[0], val[2] ] }
212
213logical_or_expression
214 : logical_and_expression
215 | logical_or_expression '||' logical_and_expression
216 { result = [ :OP_LOR, val[0], val[2] ] }
217
218conditional_expression
219 : logical_or_expression
220 | logical_or_expression '?' expression ':' conditional_expression
221 { result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ] }
222
223assignment_expression
224 : conditional_expression
225 | unary_expression assignment_operator assignment_expression
226
227assignment_operator
228 : '='
229 | '+='
230 | '-='
231 | '*='
232 | '/='
233 | '%='
234 | '<<='
235 | '>>='
236 | '&='
237 | '|='
238 | '^='
239
240expression
241 : assignment_expression
242 {
243 result = Expression.new( val[0] )
244 # result.print
245 }
246 | expression ',' assignment_expression
247 {
248 result = Expression.new( val[2] ) # ',' の後ろを採用
249 }
250
251constant_expression
252 : conditional_expression
253 {
254 result = Expression.new( val[0] )
255 # result.print
256# res = result.eval_const( nil )
257
258 # if res then
259 # puts "val: #{res}"
260 # else
261 # puts "val: nil"
262 # end
263 }
264
265# Types
266########################## 宣言 ##########################
267# 宣言もK&Rと一部異なる
268
269# declarationはセルの属性で使われる
270# K&Rとの違い: storage classが指定できない、型が省略できない
271declaration
272 : declaration_specifiers init_declarator_list ';'
273# : specifier_qualifier_list init_declarator_list ';'
274
275# declaration_specifiersは関数のパラメータで使われるが、
276# specifier_qualifier_listで十分かもしれない
277
278declaration_specifiers
279 : storage_class_specifier
280 {
281 result = CIntType.new( -3 ) # storage class は無視
282 }
283 | storage_class_specifier declaration_specifiers
284 {
285 result = val[1] # storage class は無視
286 }
287 | type_specifier
288 | type_specifier declaration_specifiers
289 {
290 result = val[1].merge val[0]
291 }
292 | type_qualifier
293 {
294 result = CIntType.new( -3 )
295 result.set_qualifier val[0]
296 }
297 | type_qualifier declaration_specifiers
298 {
299 val[1].set_qualifier val[0]
300 result = val[1]
301 }
302 | function_specifier
303 | function_specifier declaration_specifiers
304
305init_declarator_list
306 : init_declarator
307 { result = [val[0]] }
308 | init_declarator_list ',' init_declarator
309 { result << val[2] }
310
311init_declarator
312 : declarator
313 | declarator '=' initializer
314 { val[0].set_initializer( val[2] ) }
315
316storage_class_specifier
317 : EXTERN
318 | STATIC
319 | AUTO
320 | REGISTER
321
322type_specifier
323 : VOID
324 { set_no_type_name true; result = CVoidType.new }
325 | CHAR
326 { set_no_type_name true; result = CIntType.new(-11 ) }
327 | SHORT
328 { set_no_type_name true; result = CIntType.new( -2 ) }
329 | INT
330 { set_no_type_name true; result = CIntType.new( -3 ) }
331 | LONG
332 { set_no_type_name true; result = CIntType.new( -4 ) }
333 | FLOAT
334 { set_no_type_name true; result = CFloatType.new(-32) }
335 | DOUBLE
336 { set_no_type_name true; result = CFloatType.new(-64) }
337 | SIGNED
338 {
339 set_no_type_name true
340 result = CIntType.new( -3 )
341 result.set_sign :SIGNED
342 }
343 | UNSIGNED
344 {
345 set_no_type_name true
346 result = CIntType.new( -3 )
347 result.set_sign :UNSIGNED
348 }
349 | BOOL
350 { set_no_type_name true; result = CBoolType.new }
351 | struct_specifier
352 { set_no_type_name true; result = val[0] } # set_no_type_name true は struct_tag でも呼ばれる
353 | union_specifier
354 { set_no_type_name true; result = CVoidType.new } # void が宣言されたとする
355 | enum_specifier
356 { set_no_type_name true; result = CVoidType.new } # void が宣言されたとする
357 | TYPE_NAME
358 { set_no_type_name true; result = CDefinedType.new( val[0].val ) }
359
360# mikan K&Rのstruct_or_union_specifierに相当するが、unionは使えない, bit field にも対応しない
361struct_specifier # mikan
362# : STRUCT struct_tag '{'
363 : struct_term struct_tag '{'
364 { StructType.set_define( true ) }
365 struct_declaration_list '}'
366 {
367 StructType.end_of_parse
368 result = val[1]
369 }
370# | STRUCT
371 | struct_term
372 {
373 result = CStructType.new()
374 StructType.set_define( true )
375 }
376 '{' struct_declaration_list '}'
377 {
378 StructType.end_of_parse
379 result = val[1]
380 }
381# | STRUCT struct_tag # mikan struct_tag は namespace 対応が必
382要
383 | struct_term struct_tag # mikan struct_tag は namespace 対応が必
384要
385 {
386 StructType.set_define( false )
387 StructType.end_of_parse
388 result = val[1]
389 }
390
391struct_term
392 : STRUCT { set_no_type_name true }
393
394struct_declaration_list
395 : struct_declaration
396 | struct_declaration_list struct_declaration
397
398struct_tag:
399 IDENTIFIER
400 {
401 result = CStructType.new( val[0].val )
402 set_no_type_name true
403 }
404
405# ポインタ修飾子を追加
406struct_declaration
407 : declaration_specifiers struct_declarator_list ';'
408# : specifier_qualifier_list struct_declarator_list ';'
409 {
410 val[1].each { |i| # i: Decl
411 i.set_type( val[0] )
412 i.set_kind( :MEMBER )
413 i.check
414 CStructType.new_member( i )
415 }
416 result = val[1]
417 }
418 # ビットフィールドを読み飛ばし
419 | declaration_specifiers struct_declarator_list ':' constant_expression ';'
420 {
421 val[1].each { |i| # i: Decl
422 i.set_type( val[0] )
423 i.set_kind( :MEMBER )
424 i.check
425 CStructType.new_member( i )
426 }
427 result = val[1]
428 }
429 | union_specifier ';' # 無名
430 | struct_specifier ';' # 無名
431
432
433
434# K&Rのspecifier_qualifier_listと同じ
435# 名前がまぎらわしかったのでtype_を付けた
436specifier_qualifier_list
437 : type_specifier specifier_qualifier_list
438 {
439 result = val[1].merge val[0]
440 }
441 | type_specifier
442 | type_qualifier specifier_qualifier_list
443 {
444 val[1].set_qualifier val[0]
445 result = val[1]
446 }
447 | type_qualifier
448 {
449 result = CIntType.new( -3 )
450 result.set_qualifier val[0]
451 }
452
453struct_declarator_list
454 : struct_declarator
455 { result = [ val[0] ] }
456 | struct_declarator_list ',' struct_declarator
457 { result << val[2] }
458
459# ビットフィールドは使えない
460struct_declarator
461 : declarator
462# | ':' constant_expression
463# | declarator ':' constant_expression
464
465union_specifier
466# : UNION union_tag '{' union_declaration_list '}'
467# | UNION '{' union_declaration_list '}'
468# | UNION union_tag # mikan struct_tag は namespace 対応が必
469要
470 : union_term union_tag '{' union_declaration_list '}'
471 | union_term '{' union_declaration_list '}'
472 | union_term union_tag # mikan struct_tag は namespace 対応が必
473要
474
475union_term
476 : UNION { set_no_type_name true }
477
478union_declaration_list
479 : union_declaration
480 | union_declaration_list union_declaration
481
482union_tag:
483 IDENTIFIER
484
485union_declaration
486 : declaration_specifiers union_declarator_list ';'
487 | union_specifier ';' # 無名
488 | struct_specifier ';' # 無名
489
490union_declarator_list
491 : union_declarator
492 | union_declarator_list ',' union_declarator
493
494union_declarator
495 : declarator
496 | ':' constant_expression
497 | declarator ':' constant_expression
498
499enum_specifier
500 : ENUM '{' enumerator_list '}'
501 | ENUM IDENTIFIER '{' enumerator_list '}'
502 | ENUM '{' enumerator_list ',' '}'
503 | ENUM IDENTIFIER '{' enumerator_list ',' '}'
504 | ENUM IDENTIFIER
505 | ENUM TYPE_NAME '{' enumerator_list '}'
506 | ENUM TYPE_NAME '{' enumerator_list ',' '}'
507 | ENUM TYPE_NAME
508
509enumerator_list
510 : enumerator
511 | enumerator_list ',' enumerator
512
513enumerator
514 : IDENTIFIER
515 | IDENTIFIER '=' constant_expression
516
517type_qualifier
518 : CONST
519 { result = :CONST }
520 | RESTRICT
521 | VOLATILE
522 { result = :VOLATILE }
523
524function_specifier
525 : __INLINE__
526 | INLINE
527 | __INLINE
528 | CINLINE
529
530declarator
531 : pointer direct_declarator
532 {
533 val[1].set_type( val[0] )
534 result = val[1]
535 }
536 | direct_declarator
537 | pointer TYPE_NAME # 関数ポインタの typedef が二重定義の場合
538 {
539 result = Decl.new( val[1].val )
540 result.set_type( val[0] )
541 }
542
543direct_declarator # mikan
544 : IDENTIFIER
545 { result = Decl.new( val[0].val ) }
546 | '(' declarator ')'
547 { result = val[1] }
548 | direct_declarator '[' constant_expression ']'
549 {
550 val[0].set_type( CArrayType.new( val[2] ) )
551 result = val[0]
552 }
553 | direct_declarator '[' ']'
554 {
555 val[0].set_type( CArrayType.new )
556 result = val[0]
557 }
558 | direct_declarator '(' parameter_type_list ')'
559 {
560 # Generator.warning( "W6001 need 'void' for no parameter" )
561 val[0].set_type( CFuncType.new )
562 result = val[0]
563 }
564 | direct_declarator '(' identifier_list ')' # これは何のために必
565要? 060211
566 | direct_declarator '(' ')'
567 {
568 # Generator.warning( "W6002 need 'void' for no parameter" )
569 val[0].set_type( CFuncType.new )
570 result = val[0]
571 }
572
573pointer
574 : '*'
575 { result = CPtrType.new }
576 | '*' type_qualifier_list
577 {
578 result = CPtrType.new
579 result.set_qualifier( val[1] )
580 }
581 | '*' pointer
582 {
583 val[1].set_type(CPtrType.new)
584 result = val[1]
585 }
586 | '*' type_qualifier_list pointer
587 {
588 ptrtype = CPtrType.new
589 ptrtype.set_qualifier( val[1] )
590 val[2].set_type( ptrtype )
591 result = val[2]
592 }
593
594type_qualifier_list
595 : type_qualifier
596 | type_qualifier_list type_qualifier
597
598parameter_type_list
599 : parameter_list
600 | parameter_list ',' '.' '.' '.'
601 # mikan 可変長パラメータ, ... の間のスペースが許される(手抜き)
602
603parameter_list
604 : parameter_declaration
605# { result = ParamList.new( val[0] ) }
606 | parameter_list ',' parameter_declaration
607# {
608# val[0].add_param( val[2] )
609# # result = val[0] 不要
610# }
611
612
613# パラメータ修飾子を追加
614parameter_declaration
615 : declaration_specifiers declarator
616# {
617# decl = ParamDecl.new( val[1], val[0], [] )
618# val[1].set_kind( :PARAMETER )
619# result = decl
620# }
621
622 # 以下はエラーとする
623# | declaration_specifiers # 仮引数なしは、とりあえず扱わない 060210
624# {
625# unless val[0].kind_of?( VoidType ) then
626# Generator.error( "B1001 need parameter name" )
627# end
628# result = nil
629# }
630 | declaration_specifiers abstract_declarator # 仮引数なし
631 | declaration_specifiers # 仮引数なし
632
633
634identifier_list # 060211 不用になった
635 : IDENTIFIER
636 | identifier_list ',' IDENTIFIER
637
638type_name
639 : specifier_qualifier_list
640 | specifier_qualifier_list abstract_declarator
641
642abstract_declarator # mikan
643 : pointer
644 | direct_abstract_declarator
645 | pointer direct_abstract_declarator
646
647direct_abstract_declarator
648 : '(' abstract_declarator ')'
649 | '[' ']'
650 | '[' assignment_expression ']'
651 | direct_abstract_declarator '[' ']'
652 | direct_abstract_declarator '[' assignment_expression ']'
653 | '(' ')'
654 {
655 Generator.warning( "W6003 need 'void' for no parameter" )
656 }
657 | '(' parameter_type_list ')'
658 | direct_abstract_declarator '(' ')'
659 {
660 Generator.warning( "W6004 need 'void' for no parameter" )
661 }
662 | direct_abstract_declarator '(' parameter_type_list ')'
663
664# assignment_expressionをconstant_expressionに変更
665initializer # mikan
666 : assignment_expression
667 { result = val[0] }
668 | '{' initializer_list '}'
669 { result = val[1] }
670 | '{' initializer_list ',' '}'
671 { result = val[1] }
672 | C_EXP '(' STRING_LITERAL ')'
673 { result = C_EXP.new( val[2] ) }
674
675initializer_list
676 : initializer
677 {
678 result = [ val[0] ]
679 }
680 | initializer_list ',' initializer
681 {
682 val[0] << val[2]
683 result = val[0]
684 }
685
686
687########################## ここからはCDL独自 ##########################
688
689#トップレベルの構文規則
690C_parser
691 :
692 | C_parser extension_statement
693
694extension_statement
695 : cdl_statement
696 | EXTENSION cdl_statement
697
698cdl_statement
699 : typedef
700 | func_def
701 | enum_specifier ';'
702 | struct_specifier ';'
703 | declaration
704 | ';'
705 | error # エラー回復ポイント
706
707typedef
708 : TYPEDEF specifier_qualifier_list declarator_list ';'
709 {
710 val[2].each{ |i|
711 i.set_kind( :TYPEDEF )
712 }
713 Typedef.new_decl_list( val[1], val[2] )
714 # val[1].show_tree 0
715 }
716
717declarator_list
718 : declarator
719 { result = [ val[0] ] }
720 | declarator_list ',' declarator
721 { result << val[2] }
722
723func_def
724 : declaration_specifiers declarator compound_statement
725
726statement
727 : labeled_statement
728 | compound_statement
729 | expression_statement
730 | ifstatement
731 | whilestatement
732 | dowhilestatement
733 | forstatement
734 | switchstatement
735 | jump_statement
736 | asm_statement
737
738labeled_statement
739 : IDENTIFIER ':' statement
740 | CASE constant_expression ':' statement
741 | DEFAULT ':' statement
742
743compound_statement
744 : '{' '}'
745 | '{' block_item_list '}'
746
747block_item_list
748 : block_item
749 | block_item_list block_item
750
751block_item
752 : declaration
753 | statement
754
755expression_statement
756 : ';'
757 | expression ';'
758
759ifstatement
760 : IF '(' expression ')' statement
761 | IF '(' expression ')' statement ELSE statement
762
763switchstatement
764 : SWITCH '(' expression ')' compound_statement
765
766whilestatement
767 : WHILE '(' expression ')' statement
768
769dowhilestatement
770 : DO statement WHILE '(' expression ')' ';'
771
772forstatement
773 : FOR '(' expression_statement expression_statement ')' statement
774 | FOR '(' expression_statement expression_statement expression ')' statement
775 | FOR '(' declaration expression_statement ')' statement
776 | FOR '(' declaration expression_statement expression ')' statement
777
778jump_statement
779 : GOTO IDENTIFIER ';'
780 | CONTINUE ';'
781 | BREAK ';'
782 | RETURN ';'
783 | RETURN expression ';'
784
785namespace_identifier
786 : IDENTIFIER { result = NamespacePath.new( val[0].val, false ) }
787 | '::' IDENTIFIER { result = NamespacePath.new( val[1].val, true ) }
788 | namespace_identifier '::' IDENTIFIER
789 { result = val[0].append!( val[2].val ) }
790
791asm_statement
792 : _ASM {
793 while true
794 # ';' が表れるまで、トークンを読み飛ばす。
795 # gcc の構文拡張に対応すべきだが、単純な実装
796として、';' まで読み飛ばす。
797 # トークン単位で読み飛ばしているので、文字列やコメント内
798の ';' は対象にならない。
799 token = next_token
800 if token[1].val == ";"
801 break
802 end
803 # p "skip: #{token[1].val}"
804 end
805 }
806
807end
808
809---- inner
810
811 RESERVED = {
812 # keyword
813 'typedef' => :TYPEDEF,
814 'struct' => :STRUCT,
815 'union' => :UNION,
816 'sizeof' => :SIZEOF,
817 'throw' => :THROW,
818
819 # specifier
820 # types
821 'void' => :VOID,
822 'char' => :CHAR,
823 'short' => :SHORT,
824
825 'volatile'=> :VOLATILE,
826 'restrict'=> :RESTRICT,
827 'const' => :CONST,
828 'extern' => :EXTERN,
829
830 'long' => :LONG,
831 'float' => :FLOAT,
832 'double' => :DOUBLE,
833 'signed' => :SIGNED,
834 'unsigned'=> :UNSIGNED,
835
836 'int' => :INT,
837 'enum' => :ENUM,
838
839 'if' => :IF,
840 'else' => :ELSE,
841 'while' => :WHILE,
842 'do' => :DO,
843 'for' => :FOR,
844 'switch' => :SWITCH,
845 'case' => :CASE,
846 'default' => :DEFAULT,
847 'goto' => :GOTO,
848 'continue' => :CONTINUE,
849 'break' => :BREAK,
850 'return' => :RETURN,
851 '__inline__' => :__INLINE__,
852 'inline' => :INLINE,
853 '__inline' => :__INLINE,
854 'Inline' => :CINLINE, # inline starting with Capital letter
855 'static' => :STATIC,
856 'register' => :REGISTER,
857 'auto' => :AUTO,
858 '__extension__' => :EXTENSION,
859 '__asm__' => :_ASM,
860 'asm' => :_ASM
861
862 }
863
864 @@generator_nest = -1
865 @@generator_stack = []
866 @@current_locale = []
867
868 def finalize
869
870 # mikan Namespace.pop
871 Celltype.pop
872 Cell.pop
873 CompositeCelltype.pop
874 Region.pop
875
876 end
877
878 def set_plugin( plugin )
879 @plugin = plugin
880 end
881
882 def self.get_plugin
883 @@generator_stack[@@generator_nest].get_plugin
884 end
885
886 def get_plugin
887 @plugin
888 end
889
890 def parse(files)
891
892 # mikan Namespace.push
893 Celltype.push
894 Cell.push
895 CompositeCelltype.push
896 Region.push
897
898 @@generator_nest += 1
899 @@generator_stack[@@generator_nest] = self
900 @b_no_type_name = false
901
902 begin
903
904 @q = []
905 comment = false
906# b_asm = false
907
908 # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
909 TECS_LANG::set_kcode_binary
910
911 # 800U, 0xffLL など (整数リテラルにå…
912±é€šã®ä¿®é£¾å­)
913 integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?"
914
915 files.each {|file|
916 lineno = 1
917 begin
918#2.0 IO.foreach(file) {|line|
919 TECSIO.foreach(file) {|line|
920 col = 1
921 line.rstrip!
922
923 until line.empty?
924
925 if comment
926 case line
927 # コメント終了
928 when /\A\*\//
929 comment = false
930 when /\A./
931 ;
932 end
933 else
934 case line
935 # 空白、プリプロセスディレクティブ
936 when /\A\s+/
937 ;
938 # 識別子
939 when /\A[a-zA-Z_]\w*/
940 word = $&
941 @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)]
942 # 16 進数定数
943 when /\A0x[0-9A-Fa-f]+#{integer_qualifier}/
944 @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)]
945 # 8 進数定数
946 when /\A0[0-7]+#{integer_qualifier}/
947 @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)]
948 # 浮動小数定数
949 when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/
950 @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)]
951 # 整数定数
952 when /\A\d+#{integer_qualifier}/
953 # when /\A\d+/
954 @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)]
955 # 文字
956 when /\A'(?:[^'\\]|\\.)'/
957 @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)]
958 # 文字列
959# "#include #include #include \"../systask/logtask.cfg\" 最後の " 忘れ)で無限ループ
960# when /\A"(?:[^"\\]+|\\.)*"/
961 when /\A"(?:[^"\\]|\\.)*"/ # これはうまく行くようだ
962 @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)]
963 # 行コメント
964 when /\A\/\/.*$/
965 # 読み飛ばすだけ
966 # コメント開始
967 when /\A\/\*/
968 comment = true
969 when /\A>>=/, /\A<<=/, /\A>>/, /\A<</
970 @q << [$&, Token.new($&, file, lineno, col)]
971 when /\A\+=/, /\A\-=/, /\A\*=/, /\A\/=/, /\A%=/, /\A&=/, /\A\|=/, /\A\^=/
972 @q << [$&, Token.new($&, file, lineno, col)]
973 when /\A::/, /\A==/, /\A!=/, /\A>=/, /\A<=/, /\A\->/, /\A\+\+/, /\A\-\-/
974 @q << [$&, Token.new($&, file, lineno, col)]
975 when /\A\|\|/, /\A\&\&/
976 @q << [$&, Token.new($&, file, lineno, col)]
977 when /\A./
978 @q << [$&, Token.new($&, file, lineno, col)]
979 else
980 raise
981 end
982 end
983
984 line = $'
985 col += $&.length
986 end
987
988 lineno += 1
989 }
990
991 rescue => evar
992 Generator.error( "B1002 while open or reading \'$1\'" , file )
993 print_exception( evar )
994 end
995 }
996
997 # 終了の印
998 @q << nil
999
1000 @yydebug = true
1001 do_parse
1002
1003 ensure
1004 @@generator_nest -= 1
1005 TECS_LANG::reset_kcode
1006 end
1007
1008 end
1009
1010
1011 def next_token
1012 token = @q.shift
1013
1014 if token then
1015 @@current_locale[@@generator_nest] = token[1].locale
1016
1017 case token[1].val
1018 when ";", ":", ",", "(", ")", "{", "}"
1019 set_no_type_name false
1020 when ".", "->"
1021 set_no_type_name true
1022 end
1023
1024 # TYPE_NAME トークンへ置き換え
1025 if @b_no_type_name == false
1026 if token[0] == :IDENTIFIER && Namespace.is_typename?( token[1].val ) then
1027 token[0] = :TYPE_NAME
1028 locale = @@current_locale[@@generator_nest]
1029#print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}: type_name'\n" )
1030 end
1031 end
1032
1033 if $debug then # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生)
1034 locale = @@current_locale[@@generator_nest]
1035 if token then
1036 print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" )
1037 else
1038 print( "#{locale[0]}: line #{locale[1]} : EOF\n" )
1039 end
1040 end
1041 end
1042
1043 token
1044 end
1045
1046 def on_error(t, v, vstack)
1047 if v == "$" then
1048 Generator.error( "B1003 Unexpected EOF" )
1049 else
1050 Generator.error( "B1004 syntax error near \'$1\'" , v.val )
1051 end
1052
1053 end
1054
1055 def self.current_locale
1056 @@current_locale[ @@generator_nest ]
1057 end
1058
1059 @@n_error = 0
1060 @@n_warning = 0
1061 @@n_info = 0
1062
1063 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でエラー発生は不適切)
1064 def self.error( msg )
1065 @@n_error += 1
1066 locale = @@current_locale[ @@generator_nest ]
1067
1068 if locale then
1069 Console.puts "#{locale[0]}:#{locale[1]}: error: #{msg}"
1070 else
1071 Console.puts "error: #{msg}"
1072 end
1073 end
1074
1075 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でウォーニング発生は不適切)
1076 def self.warning( msg )
1077 @@n_warning += 1
1078 locale = @@current_locale[ @@generator_nest ]
1079 Console.puts "#{locale[0]}:#{locale[1]}: warning: #{msg}"
1080 end
1081
1082 # このメソッドは構文解析、意味解析からのみ呼出し可
1083 def self.info( msg )
1084 @@n_info += 1
1085 locale = @@current_locale[ @@generator_nest ]
1086 Console.puts "#{locale[0]}:#{locale[1]}: info: #{msg}"
1087 end
1088
1089 def self.get_n_error
1090 @@n_error
1091 end
1092
1093 def self.get_n_warning
1094 @@n_warning
1095 end
1096
1097 def self.get_nest
1098 @@generator_nest
1099 end
1100
1101 def set_no_type_name b_no_type_name
1102 locale = @@current_locale[ @@generator_nest ]
1103#print "b_no_type_name=#{b_no_type_name} #{locale[0]}: line #{locale[1]}\n"
1104 @b_no_type_name = b_no_type_name
1105 end
1106
1107---- footer
1108
Note: See TracBrowser for help on using the repository browser.