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

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

文字コードを設定

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