source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb@ 352

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 28.4 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 : struct_term struct_tag '{'
303 { StructType.set_define( true ) }
304 struct_declaration_list '}'
305 {
306 StructType.end_of_parse
307 result = val[1]
308 }
309# | STRUCT
310 | struct_term
311 {
312 result = CStructType.new()
313 StructType.set_define( true )
314 }
315 '{' struct_declaration_list '}'
316 {
317 StructType.end_of_parse
318 result = val[1]
319 }
320# | STRUCT struct_tag # mikan struct_tag は namespace 対応が必要
321 | struct_term struct_tag # mikan struct_tag は namespace 対応が必要
322 {
323 StructType.set_define( false )
324 StructType.end_of_parse
325 result = val[1]
326 }
327
328struct_term
329 : STRUCT { set_no_type_name true }
330
331struct_declaration_list
332 : struct_declaration
333 | struct_declaration_list struct_declaration
334
335struct_tag:
336 IDENTIFIER
337 {
338 result = CStructType.new( val[0].val )
339 set_no_type_name true
340 }
341
342# ポインタ修飾子を追加
343struct_declaration
344 : declaration_specifiers struct_declarator_list ';'
345# : type_specifier_qualifier_list struct_declarator_list ';'
346 {
347 val[1].each { |i| # i: Decl
348 i.set_type( val[0] )
349 i.set_kind( :MEMBER )
350 i.check
351 CStructType.new_member( i )
352 }
353 result = val[1]
354 }
355 | union_specifier ';' # 無名
356 | struct_specifier ';' # 無名
357
358
359
360# K&Rのspecifier_qualifier_listと同じ
361# 名前がまぎらわしかったのでtype_を付けた
362type_specifier_qualifier_list
363 : type_specifier
364 | type_specifier type_specifier_qualifier_list
365 {
366 result = val[1].merge val[0]
367 }
368 | type_qualifier
369 {
370 result = CIntType.new( -3 )
371 result.set_qualifier val[0]
372 }
373 | type_qualifier type_specifier_qualifier_list
374 {
375 val[1].set_qualifier val[0]
376 result = val[1]
377 }
378
379struct_declarator_list
380 : struct_declarator
381 { result = [ val[0] ] }
382 | struct_declarator_list ',' struct_declarator
383 { result << val[2] }
384
385# ビットフィールドは使えない
386struct_declarator
387 : declarator
388
389
390
391union_specifier
392# : UNION union_tag '{' union_declaration_list '}'
393# | UNION '{' union_declaration_list '}'
394# | UNION union_tag # mikan struct_tag は namespace 対応が必要
395 : union_term union_tag '{' union_declaration_list '}'
396 | union_term '{' union_declaration_list '}'
397 | union_term union_tag # mikan struct_tag は namespace 対応が必要
398
399union_term
400 : UNION { set_no_type_name true }
401
402union_declaration_list
403 : union_declaration
404 | union_declaration_list union_declaration
405
406union_tag:
407 IDENTIFIER
408
409union_declaration
410 : declaration_specifiers union_declarator_list ';'
411 | union_specifier ';' # 無名
412 | struct_specifier ';' # 無名
413
414union_declarator_list
415 : union_declarator
416 | union_declarator_list ',' union_declarator
417
418# ビットフィールドは使えない
419union_declarator
420 : declarator
421
422
423
424# enumの種類を追加
425enum_specifier # mikan
426 : enum_type '{' enumerator_list '}'
427 | enum_type IDENTIFIER '{' enumerator_list '}'
428 | enum_type IDENTIFIER
429
430enum_type
431 : ENUM { result = CEnumType.new( -1 ) }
432# | ENUM8 { result = CEnumType.new( 8 ) }
433# | ENUM16 { result = CEnumType.new( 16 ) }
434# | ENUM32 { result = CEnumType.new( 32 ) }
435# | ENUM64 { result = CEnumType.new( 64 ) }
436# | ENUM128 { result = CEnumType.new( 128 ) }
437
438enumerator_list
439 : enumerator
440 | enumerator_list ',' enumerator
441
442enumerator
443 : IDENTIFIER
444 | IDENTIFIER '=' constant_expression
445
446type_qualifier
447 : CONST { result = :CONST }
448 | VOLATILE { result = :VOLATILE }
449
450declarator
451 : pointer direct_declarator
452 {
453 val[1].set_type( val[0] )
454 result = val[1]
455 }
456 | direct_declarator
457 | pointer TYPE_NAME # 関数ポインタの typedef が二重定義の場合
458 {
459 result = Decl.new( val[1].val )
460 result.set_type( val[0] )
461 }
462
463direct_declarator # mikan
464 : IDENTIFIER
465 { result = Decl.new( val[0].val ) }
466 | '(' declarator ')'
467 { result = val[1] }
468 | direct_declarator '[' constant_expression ']'
469 {
470 val[0].set_type( CArrayType.new( val[2] ) )
471 result = val[0]
472 }
473 | direct_declarator '[' ']'
474 {
475 val[0].set_type( CArrayType.new )
476 result = val[0]
477 }
478 | direct_declarator '(' parameter_type_list ')'
479 {
480 # Generator.warning( "W6001 need 'void' for no parameter" )
481 val[0].set_type( CFuncType.new )
482 result = val[0]
483 }
484
485# | direct_declarator '(' identifier_list ')' # これは何のために必要? 060211
486 | direct_declarator '(' ')'
487 {
488 # Generator.warning( "W6002 need 'void' for no parameter" )
489 val[0].set_type( CFuncType.new )
490 result = val[0]
491 }
492
493pointer
494 : '*'
495 { result = CPtrType.new }
496 | '*' type_qualifier
497 {
498 result = CPtrType.new
499 result.set_qualifier( val[1] )
500 }
501 | '*' pointer
502 {
503 val[1].set_type(CPtrType.new)
504 result = val[1]
505 }
506 | '*' type_qualifier pointer
507 {
508 ptrtype = CPtrType.new
509 ptrtype.set_qualifier( val[1] )
510 val[2].set_type( ptrtype )
511 result = val[2]
512 }
513
514
515parameter_type_list
516 : parameter_list
517 | parameter_list ',' '.' '.' '.'
518 # mikan 可変長パラメータ, ... の間のスペースが許される(手抜き)
519
520parameter_list
521 : parameter_declaration
522# { result = ParamList.new( val[0] ) }
523 | parameter_list ',' parameter_declaration
524# {
525# val[0].add_param( val[2] )
526# # result = val[0] 不要
527# }
528
529
530# パラメータ修飾子を追加
531parameter_declaration
532 : declaration_specifiers declarator
533# {
534# decl = ParamDecl.new( val[1], val[0], [] )
535# val[1].set_kind( :PARAMETER )
536# result = decl
537# }
538
539 # 以下はエラーとする
540# | declaration_specifiers # 仮引数なしは、とりあえず扱わない 060210
541# {
542# unless val[0].kind_of?( VoidType ) then
543# Generator.error( "B1001 need parameter name" )
544# end
545# result = nil
546# }
547 | declaration_specifiers abstract_declarator # 仮引数なし
548 | declaration_specifiers # 仮引数なし
549
550
551#identifier_list # 060211 不用になった
552# : IDENTIFIER
553# | identifier_list ',' IDENTIFIER
554
555type_name
556 : type_specifier_qualifier_list
557 | type_specifier_qualifier_list abstract_declarator
558
559abstract_declarator # mikan
560 : pointer
561 | direct_abstract_declarator
562 | pointer direct_abstract_declarator
563
564direct_abstract_declarator
565 : '(' abstract_declarator ')'
566 | '[' ']'
567 | '[' constant_expression ']'
568 | direct_abstract_declarator '[' ']'
569 | direct_abstract_declarator '[' constant_expression ']'
570 | '(' ')'
571 {
572 Generator.warning( "W6003 need 'void' for no parameter" )
573 }
574 | '(' parameter_type_list ')'
575 | direct_abstract_declarator '(' ')'
576 {
577 Generator.warning( "W6004 need 'void' for no parameter" )
578 }
579 | direct_abstract_declarator '(' parameter_type_list ')'
580
581# assignment_expressionをconstant_expressionに変更
582initializer # mikan
583 : constant_expression
584 { result = val[0] }
585 | '{' initializer_list '}'
586 { result = val[1] }
587 | '{' initializer_list ',' '}'
588 { result = val[1] }
589 | C_EXP '(' STRING_LITERAL ')'
590 { result = C_EXP.new( val[2] ) }
591
592initializer_list
593 : initializer
594 {
595 result = [ val[0] ]
596 }
597 | initializer_list ',' initializer
598 {
599 val[0] << val[2]
600 result = val[0]
601 }
602
603
604########################## ここからはCDL独自 ##########################
605
606#トップレベルの構文規則
607C_parser
608 :
609 | C_parser extension_statement
610
611extension_statement
612 : statement
613 | EXTENSION statement
614
615statement
616 : typedef
617 | func_def
618 | enum_specifier ';'
619 | struct_specifier ';'
620 | declaration
621 | ';'
622 | error # エラー回復ポイント
623
624typedef
625 : TYPEDEF type_specifier_qualifier_list declarator_list ';'
626 {
627 val[2].each{ |i|
628 i.set_kind( :TYPEDEF )
629 }
630 Typedef.new_decl_list( val[1], val[2] )
631 # val[1].show_tree 0
632 }
633
634declarator_list
635 : declarator
636 { result = [ val[0] ] }
637 | declarator_list ',' declarator
638 { result << val[2] }
639
640func_def
641 : declaration_specifiers declarator compoundstatement
642
643infunc_statement_list
644 :
645 | infunc_statement_list infunc_statement
646
647infunc_statement
648 : declaration
649 | ifstatement
650 | whilestatement
651 | dowhilestatement
652 | forstatement
653 | switchstatement
654 | labelstatement
655 | compoundstatement
656 | gotostatement
657 | expressionstatement
658 | ';'
659
660ifstatement
661 : IF '(' expression ')' infunc_statement
662 | IF '(' expression ')' infunc_statement ELSE infunc_statement
663
664whilestatement
665 : WHILE '(' expression ')' infunc_statement
666
667dowhilestatement
668 : DO infunc_statement WHILE '(' expression ')' ';'
669
670forstatement
671 : FOR '(' expression ';' expression ';' expression ')' infunc_statement
672
673switchstatement
674 : SWITCH '(' expression ')' infunc_statment
675
676labelstatement
677 : IDENTIFIER ':' infunc_statement
678 | CASE constant_expression ':' infunc_statement
679 | DEFAULT ':' infunc_statement
680
681compoundstatement
682 : '{' infunc_statement_list '}'
683
684gotostatement
685 : GOTO IDENTIFIER ';'
686 | CONTINUE ';'
687 | BREAK ';'
688 | RETURN expression ';'
689 | RETURN ';'
690
691expressionstatement
692 : expression ';'
693 | unary_expression assignment_operator expression ';'
694
695assignment_operator
696 : '='
697 | '+='
698 | '-='
699 | '*='
700 | '/='
701 | '%='
702 | '<<='
703 | '>>='
704 | '&='
705 | '|='
706 | '^='
707
708storage_class
709 : __INLINE__
710 | INLINE
711 | __INLINE
712 | CINLINE
713 | EXTERN
714 | STATIC
715 | AUTO
716 | REGISTER
717
718namespace_identifier
719 : IDENTIFIER { result = NamespacePath.new( val[0].val, false ) }
720 | '::' IDENTIFIER { result = NamespacePath.new( val[1].val, true ) }
721 | namespace_identifier '::' IDENTIFIER
722 { result = val[0].append!( val[2].val ) }
723
724end
725
726---- inner
727
728 RESERVED = {
729 # keyword
730 'typedef' => :TYPEDEF,
731 'struct' => :STRUCT,
732 'union' => :UNION,
733 'sizeof' => :SIZEOF,
734 'throw' => :THROW,
735
736 # specifier
737 # types
738 'void' => :VOID,
739 'char' => :CHAR,
740 'short' => :SHORT,
741
742 'volatile'=> :VOLATILE,
743 'const' => :CONST,
744 'extern' => :EXTERN,
745
746 'long' => :LONG,
747 'float' => :FLOAT,
748 'double' => :DOUBLE,
749 'signed' => :SIGNED,
750 'unsigned'=> :UNSIGNED,
751
752 'int' => :INT,
753 'enum' => :ENUM,
754
755 'if' => :IF,
756 'else' => :ELSE,
757 'while' => :WHILE,
758 'do' => :DO,
759 'for' => :FOR,
760 'case' => :CASE,
761 'default' => :DEFAULT,
762 'goto' => :GOTO,
763 'continue' => :CONTINUE,
764 'break' => :BREAK,
765 'return' => :RETURN,
766 '__inline__' => :__INLINE__,
767 'inline' => :INLINE,
768 '__inline' => :__INLINE,
769 'Inline' => :CINLINE, # inline starting with Capital letter
770 'static' => :STATIC,
771 'register' => :REGISTER,
772 'auto' => :AUTO,
773 '__extension__' => :EXTENSION,
774
775 }
776
777 @@generator_nest = -1
778 @@generator_stack = []
779 @@current_locale = []
780
781 def finalize
782
783 # mikan Namespace.pop
784 Celltype.pop
785 Cell.pop
786 CompositeCelltype.pop
787 Region.pop
788
789 end
790
791 def set_plugin( plugin )
792 @plugin = plugin
793 end
794
795 def self.get_plugin
796 @@generator_stack[@@generator_nest].get_plugin
797 end
798
799 def get_plugin
800 @plugin
801 end
802
803 def parse(files)
804
805 # mikan Namespace.push
806 Celltype.push
807 Cell.push
808 CompositeCelltype.push
809 Region.push
810
811 @@generator_nest += 1
812 @@generator_stack[@@generator_nest] = self
813 @b_no_type_name = false
814
815 begin
816
817 @q = []
818 comment = false
819
820 # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
821 TECS_LANG::set_kcode_binary
822
823 # 800U, 0xffLL など (整数リテラルに共通の修飾子)
824 integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?"
825
826 files.each {|file|
827 lineno = 1
828 begin
829#2.0 IO.foreach(file) {|line|
830 TECSIO.foreach(file) {|line|
831 col = 1
832 line.rstrip!
833
834 until line.empty?
835
836 if comment
837 case line
838 # コメント終了
839 when /\A\*\//
840 comment = false
841 when /\A./
842 ;
843 end
844 else
845 case line
846 # 空白、プリプロセスディレクティブ
847 when /\A\s+/
848 ;
849 # 識別子
850 when /\A[a-zA-Z_]\w*/
851 word = $&
852 @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)]
853 # 16 進数定数
854 when /\A0x[0-9A-Fa-f]+#{integer_qualifier}/
855 @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)]
856 # 8 進数定数
857 when /\A0[0-7]+#{integer_qualifier}/
858 @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)]
859 # 浮動小数定数
860 when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/
861 @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)]
862 # 整数定数
863 when /\A\d+#{integer_qualifier}/
864 # when /\A\d+/
865 @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)]
866 # 文字
867 when /\A'(?:[^'\\]|\\.)'/
868 @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)]
869 # 文字列
870# "#include #include #include \"../systask/logtask.cfg\" 最後の " 忘れ)で無限ループ
871# when /\A"(?:[^"\\]+|\\.)*"/
872 when /\A"(?:[^"\\]|\\.)*"/ # これはうまく行くようだ
873 @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)]
874 # 行コメント
875 when /\A\/\/.*$/
876 # 読み飛ばすだけ
877 # コメント開始
878 when /\A\/\*/
879 comment = true
880 when /\A>>=/, /\A<<=/, /\A>>/, /\A<</
881 @q << [$&, Token.new($&, file, lineno, col)]
882 when /\A\+=/, /\A\-=/, /\A\*=/, /\A\/=/, /\A%=/, /\A&=/, /\A\|=/, /\A\^=/
883 @q << [$&, Token.new($&, file, lineno, col)]
884 when /\A::/, /\A==/, /\A!=/, /\A>=/, /\A<=/, /\A\->/, /\A\+\+/, /\A\-\-/
885 @q << [$&, Token.new($&, file, lineno, col)]
886 when /\A./
887 @q << [$&, Token.new($&, file, lineno, col)]
888 else
889 raise
890 end
891 end
892
893 line = $'
894 col += $&.length
895 end
896
897 lineno += 1
898 }
899
900 rescue => evar
901 Generator.error( "B1002 while open or reading \'$1\'" , file )
902 print_exception( evar )
903 end
904 }
905
906 # 終了の印
907 @q << nil
908
909 @yydebug = true
910 do_parse
911
912 ensure
913 @@generator_nest -= 1
914 TECS_LANG::reset_kcode
915 end
916
917 end
918
919
920 def next_token
921 token = @q.shift
922
923 if token then
924 @@current_locale[@@generator_nest] = token[1].locale
925
926 case token[1].val
927 when ";", ":", ",", "(", ")", "{", "}"
928 set_no_type_name false
929 when ".", "->"
930 set_no_type_name true
931 end
932
933 # TYPE_NAME トークンへ置き換え
934 if @b_no_type_name == false
935 if token[0] == :IDENTIFIER && Namespace.is_typename?( token[1].val ) then
936 token[0] = :TYPE_NAME
937 locale = @@current_locale[@@generator_nest]
938#print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}: type_name'\n" )
939 end
940 end
941
942 if $debug then # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生)
943 locale = @@current_locale[@@generator_nest]
944 if token then
945 print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" )
946 else
947 print( "#{locale[0]}: line #{locale[1]} : EOF\n" )
948 end
949 end
950 end
951
952 token
953 end
954
955 def on_error(t, v, vstack)
956 if v == "$" then
957 Generator.error( "B1003 Unexpected EOF" )
958 else
959 Generator.error( "B1004 syntax error near \'$1\'" , v.val )
960 end
961
962 end
963
964 def self.current_locale
965 @@current_locale[ @@generator_nest ]
966 end
967
968 @@n_error = 0
969 @@n_warning = 0
970 @@n_info = 0
971
972 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でエラー発生は不適切)
973 def self.error( msg )
974 @@n_error += 1
975 locale = @@current_locale[ @@generator_nest ]
976
977 if locale then
978 Console.puts "error: #{locale[0]}: line #{locale[1]} #{msg}"
979 else
980 Console.puts "error: #{msg}"
981 end
982 end
983
984 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でウォーニング発生は不適切)
985 def self.warning( msg )
986 @@n_warning += 1
987 locale = @@current_locale[ @@generator_nest ]
988 Console.puts "warning: #{locale[0]}: line #{locale[1]} #{msg}"
989 end
990
991 # このメソッドは構文解析、意味解析からのみ呼出し可
992 def self.info( msg )
993 @@n_info += 1
994 locale = @@current_locale[ @@generator_nest ]
995 Console.puts "info: #{locale[0]}: line #{locale[1]} #{msg}"
996 end
997
998 def self.get_n_error
999 @@n_error
1000 end
1001
1002 def self.get_n_warning
1003 @@n_warning
1004 end
1005
1006 def self.get_nest
1007 @@generator_nest
1008 end
1009
1010 def set_no_type_name b_no_type_name
1011 locale = @@current_locale[ @@generator_nest ]
1012#print "b_no_type_name=#{b_no_type_name} #{locale[0]}: line #{locale[1]}\n"
1013 @b_no_type_name = b_no_type_name
1014 end
1015
1016---- footer
1017
Note: See TracBrowser for help on using the repository browser.