source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

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