source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb@ 374

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

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

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