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

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

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

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 65.4 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2018 by TOPPERS Project
7#--
8# 上記著作権者
9は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11# 変・再é…
12å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
13# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15# スコード中に含まれていること.
16# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17# 用できる形で再é…
18å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
19å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
20# 者
21マニュアルなど)に,上記の著作権表示,この利用条件および下記
22# の無保証規定を掲載すること.
23# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24# 用できない形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
26# と.
27# (a) 再é…
28å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
29マニュアルなど)に,上記の著
30# 作権表示,この利用条件および下記の無保証規定を掲載すること.
31# (b) 再é…
32å¸ƒã®å½¢æ…
33‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
34# 報告すること.
35# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36# 害からも,上記著作権者
37およびTOPPERSプロジェクトをå…
38è²¬ã™ã‚‹ã“と.
39# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
40# 由に基づく請求からも,上記著作権者
41およびTOPPERSプロジェクトを
42# å…
43è²¬ã™ã‚‹ã“と.
44#
45# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
46お
47# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
48# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
49# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
50# の責任を負わない.
51#
52# $Id$
53#++
54
55class Generator
56rule
57# トップレベルの構文要素はcomponent_description
58all: component_description
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 | TRUE
72 { result = [ :BOOL_CONSTANT, true ] }
73 | FALSE
74 { result = [ :BOOL_CONSTANT, false ] }
75 | INTEGER_CONSTANT
76 { result = [ :INTEGER_CONSTANT, val[0] ] }
77 | FLOATING_CONSTANT
78 { result = [ :FLOATING_CONSTANT, val[0] ] }
79 | OCTAL_CONSTANT
80 { result = [ :OCTAL_CONSTANT, val[0] ] }
81 | HEX_CONSTANT
82 { result = [ :HEX_CONSTANT, val[0] ] }
83 | CHARACTER_LITERAL
84 { result = [ :CHARACTER_LITERAL, val[0] ] }
85 | string_literal_list
86 { result = [ :STRING_LITERAL_LIST, val[0] ] }
87 | '(' expression ')'
88 { result = [ :PARENTHESES, val[1].get_elements ] }
89
90string_literal_list
91 : STRING_LITERAL
92 | string_literal_list STRING_LITERAL
93 {
94 # 連接した文字列を1つの文字列にまとめる
95 str = "\"" + val[0].val.gsub( /\"(.*)\"/, "\\1" ) + val[1].val.gsub( /\"(.*)\"/, "\\1" ) + "\""
96 result = Token.new( str, val[0].file, val[0].lineno, val[0].col )
97 }
98
99# 関数呼び出しと後置インクリメント、デクリメント演算子がない
100postfix_expression
101 : primary_expression
102 | postfix_expression '[' expression ']'
103 { result = [ :OP_SUBSC, val[0], val[2] ] }
104 | postfix_expression '.' IDENTIFIER
105 { result = [ :OP_DOT, val[0], val[2] ] }
106 | postfix_expression '->' IDENTIFIER
107 { result = [ :OP_REF, val[0], val[2] ] }
108
109# 前置インクリメント、デクリメント演算子がない
110unary_expression
111 : postfix_expression
112 | unary_operator cast_expression
113 { result = [ val[0], val[1] ] }
114 | SIZEOF unary_expression
115 { result = [ :OP_SIZEOF_EXPR, val[1] ] }
116 | SIZEOF '(' type_name ')'
117 { result = [ :OP_SIZEOF_TYPE, val[1] ] }
118
119unary_operator
120 : '&' { result = :OP_U_AMP }
121 | '*' { result = :OP_U_ASTER }
122 | '+' { result = :OP_U_PLUS }
123 | '-' { result = :OP_U_MINUS }
124 | '~' { result = :OP_U_TILDE }
125 | '!' { result = :OP_U_EXCLAM }
126
127cast_expression
128 : unary_expression
129 | '(' type_name ')' cast_expression
130 { result = [ :CAST, val[1], val[3] ] }
131
132multiplicative_expression
133 : cast_expression
134 | multiplicative_expression '*' cast_expression
135 { result = [ :OP_MULT, val[0], val[2] ] }
136 | multiplicative_expression '/' cast_expression
137 { result = [ :OP_DIV, val[0], val[2] ] }
138 | multiplicative_expression '%' cast_expression
139 { result = [ :OP_REMAIN, val[0], val[2] ] }
140
141additive_expression
142 : multiplicative_expression
143 | additive_expression '+' multiplicative_expression
144 { result = [ :OP_ADD, val[0], val[2] ] }
145 | additive_expression '-' multiplicative_expression
146 { result = [ :OP_SUB, val[0], val[2] ] }
147
148shift_expression
149 : additive_expression
150 | shift_expression '<<' additive_expression
151 { result = [ :OP_LSFT, val[0], val[2] ] }
152 | shift_expression '>>' additive_expression
153 { result = [ :OP_RSFT, val[0], val[2] ] }
154
155relational_expression
156 : shift_expression
157 | relational_expression '<' shift_expression
158 { result = [ :OP_LT, val[0], val[2] ] }
159 | relational_expression '>' shift_expression
160 { result = [ :OP_GT, val[0], val[2] ] }
161 | relational_expression '<=' shift_expression
162 { result = [ :OP_LE, val[0], val[2] ] }
163 | relational_expression '>=' shift_expression
164 { result = [ :OP_GE, val[0], val[2] ] }
165
166equality_expression
167 : relational_expression
168 | equality_expression '==' relational_expression
169 { result = [ :OP_EQ, val[0], val[2] ] }
170 | equality_expression '!=' relational_expression
171 { result = [ :OP_NE, val[0], val[2] ] }
172
173and_expression
174 : equality_expression
175 | and_expression '&' equality_expression
176 { result = [ :OP_AND, val[0], val[2] ] }
177
178exclusive_or_expression
179 : and_expression
180 | exclusive_or_expression '^' and_expression
181 { result = [ :OP_EOR, val[0], val[2] ] }
182
183inclusive_or_expression
184 : exclusive_or_expression
185 | inclusive_or_expression '|' exclusive_or_expression
186 { result = [ :OP_OR, val[0], val[2] ] }
187
188logical_and_expression
189 : inclusive_or_expression
190 | logical_and_expression '&&' inclusive_or_expression
191 { result = [ :OP_LAND, val[0], val[2] ] }
192
193logical_or_expression
194 : logical_and_expression
195 | logical_or_expression '||' logical_and_expression
196 { result = [ :OP_LOR, val[0], val[2] ] }
197
198conditional_expression
199 : logical_or_expression
200 | logical_or_expression '?' expression ':' conditional_expression
201 { result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ] }
202
203
204# コンマ演算子が使えない
205expression
206 : conditional_expression
207 {
208 result = Expression.new( val[0] )
209 # result.print
210 }
211
212constant_expression
213 : conditional_expression
214 {
215 result = Expression.new( val[0] )
216 # result.print
217
218 # res = result.eval_const( nil )
219 # if res then
220 # puts "val: #{res}"
221 # else
222 # puts "val: nil"
223 # end
224 }
225
226
227
228# Types
229########################## 宣言 ##########################
230# 宣言もK&Rと一部異なる
231
232# declarationはセルの属性で使われる
233# K&Rとの違い: storage classが指定できない、型が省略できない
234declaration
235 : type_specifier_qualifier_list init_declarator_list ';'
236 {
237 val[1].each { |i| # i: Decl
238 i.set_type( val[0] )
239 }
240 result = val[1]
241 }
242
243# declaration_specifiersは関数のパラメータで使われるが、
244# type_specifier_qualifier_listで十分かもしれない
245# Oyama
246# const, volatile は単独で型にならないので変形
247# const と volatile が同居
248することはないので、繰返し指定できないようにした
249# type_specifier も繰返し指定できる必
250要はない (singed など単独で型にはならない)
251declaration_specifiers
252 : type_specifier
253 | type_qualifier type_specifier
254 {
255 val[1].set_qualifier( val[0] )
256 result = val[1]
257 }
258
259init_declarator_list
260 : init_declarator
261 { result = [val[0]] }
262 | init_declarator_list ',' init_declarator
263 { result << val[2] }
264
265init_declarator
266 : declarator
267 | declarator '=' initializer
268 { val[0].set_initializer( val[2] ) }
269
270# INT8から下はK&Rにない
271# Oyama
272# signed, unsigned は単独で型にならないので、構文要素として分離
273type_specifier
274 : VOID { result = VoidType.new }
275 | FLOAT32_T { result = FloatType.new(32) }
276 | DOUBLE64_T { result = FloatType.new(64) }
277 | struct_specifier
278 | enum_specifier
279 | TYPE_NAME { result = DefinedType.new( val[0].val ) }
280# | IDENTIFIER { result = DefinedType.new( val[0].val ) } # reduce/reduce conflict が起こってしまう
281 | sign_int_type
282 | char_type
283 | BOOL_T { result = BoolType.new }
284# | BOOL {
285# Generator.warning( "W5001 bool: obsolete type. use bool_t" )
286# result = BoolType.new
287# }
288 | FLOAT {
289 Generator.warning( "W5002 float: obsolete type. use float32_t" )
290 result = FloatType.new(32)
291 }
292 | DOUBLE {
293 Generator.warning( "W5003 double: obsolete type. use double64_t" )
294 result = FloatType.new(64)
295 }
296 | DESCRIPTOR '(' namespace_identifier ')' { # namespace_identifier: signature name
297 result = DescriptorType.new( val[2] )
298 }
299
300char_type
301 : CHAR_T { result = IntType.new( -1 ) }
302 | SCHAR_T
303 {
304 result = IntType.new( -1 )
305 result.set_sign( :SIGNED, true )
306 }
307 | UCHAR_T
308 {
309 result = IntType.new( -1 )
310 result.set_sign( :UNSIGNED, true )
311 }
312
313int_type
314 : CHAR {
315 # Generator.warning( "W5004 char: obsolete type. use char_t" )
316 result = IntType.new( -11 )
317 }
318 | SHORT { result = IntType.new( -2 ) }
319 | INT { result = IntType.new( -3 ) }
320 | LONG { result = IntType.new( -4 ) }
321# | INTPTR { result = IntType.new( -5 ) }
322# | INT8 {
323# Generator.warning( "W5005 int8: obsolete. use int8_t" )
324# result = IntType.new( 8 )
325# }
326# | INT16 {
327# Generator.warning( "W5006 int16: obsolete. use int16_t" )
328# result = IntType.new( 16 )
329# }
330# | INT32 {
331# Generator.warning( "W5007 int32: obsolete. use int32_t" )
332# result = IntType.new( 32 )
333# }
334# | INT64
335# {
336# Generator.warning( "W5008 int64: obsolete. use int64_t" )
337# result = IntType.new( 64 )
338# }
339# | INT128
340# {
341# Generator.warning( "W5009 int64: obsolete. use int64_t" )
342# result = IntType.new( 128 )
343# }
344 | INT8_T { result = IntType.new( 8 ) }
345 | INT16_T { result = IntType.new( 16 ) }
346 | INT32_T { result = IntType.new( 32 ) }
347 | INT64_T { result = IntType.new( 64 ) }
348 | INT128_T { result = IntType.new( 128 ) }
349 | UINT8_T
350 {
351 result = IntType.new( 8 )
352 result.set_sign( :UNSIGNED, true )
353 }
354 | UINT16_T
355 {
356 result = IntType.new( 16 )
357 result.set_sign( :UNSIGNED, true )
358 }
359 | UINT32_T
360 {
361 result = IntType.new( 32 )
362 result.set_sign( :UNSIGNED, true )
363 }
364 | UINT64_T
365 {
366 result = IntType.new( 64 )
367 result.set_sign( :UNSIGNED, true )
368 }
369 | UINT128_T
370 {
371 result = IntType.new( 128 )
372 result.set_sign( :UNSIGNED, true )
373 }
374
375sign # TECS では signed, unsigned 単独では型にできない
376 : SIGNED { result = :SIGNED }
377 | UNSIGNED { result = :UNSIGNED }
378
379# result[0] :CHAR などのトークン、result[1] :CONST, :VOLATILE など
380sign_int_type
381 : sign int_type
382 {
383 val[1].set_sign( val[0] )
384 result = val[1]
385 }
386 | int_type
387
388# K&Rのstruct_or_union_specifierに相当するが、unionは使えない
389struct_specifier # mikan
390 : STRUCT struct_tag '{'
391 { StructType.set_define( true ) }
392 struct_declaration_list '}'
393 {
394 StructType.end_of_parse
395 result = val[1]
396 }
397 | STRUCT
398 {
399 # tag が無い場合、内
400部名を与える
401 result = StructType.new( :"TAG__#{@@no_struct_tag_num}__" )
402 @@no_struct_tag_num += 1
403 StructType.set_define( true )
404 }
405 '{' struct_declaration_list '}'
406 {
407 StructType.end_of_parse
408 result = val[1]
409 }
410 | STRUCT struct_tag # mikan struct_tag は namespace 対応が必
411要
412 {
413 StructType.set_define( false )
414 StructType.end_of_parse
415 result = val[1]
416 }
417
418struct_declaration_list
419 : struct_declaration
420 | struct_declaration_list struct_declaration
421
422struct_tag:
423 IDENTIFIER
424 { result = StructType.new( val[0].val ) }
425
426# ポインタ修飾子を追加
427struct_declaration
428 : type_specifier_qualifier_list struct_declarator_list ';'
429 {
430 val[1].each { |i| # i: Decl
431 i.set_type( val[0] )
432 i.set_kind( :MEMBER )
433 i.check
434 StructType.new_member( i )
435 }
436 result = val[1]
437 }
438 | spec_L pointer_specifier_list spec_R type_specifier_qualifier_list struct_declarator_list ';'
439 {
440 val[4].each { |i| # i: Decl
441 i.set_type( val[3] )
442 i.set_kind( :MEMBER )
443 i.set_specifier_list val[1]
444 i.check
445 StructType.new_member( i )
446 }
447 result = val[4]
448 }
449
450pointer_specifier_list
451 : pointer_specifier { result = [ val[0] ] }
452 | pointer_specifier_list ',' pointer_specifier { result << val[2] }
453
454pointer_specifier
455 : STRING { result = [:STRING,-1] }
456 | STRING '(' expression ')' { result = [:STRING,val[2]] }
457 | SIZE_IS '(' expression ')' { result = [:SIZE_IS,val[2]] }
458 | COUNT_IS '(' expression ')' { result = [:COUNT_IS,val[2]] }
459
460
461# K&Rのspecifier_qualifier_listと同じ
462# 名前がまぎらわしかったのでtype_を付けた
463type_specifier_qualifier_list
464# Oyama type_specifier を繰り返して指定することはなくなった (sign_int_type としたため)
465# : type_specifier type_specifier_qualifier_list
466 : type_specifier
467 | type_qualifier type_specifier_qualifier_list
468 {
469 val[1].set_qualifier( val[0] )
470 result = val[1]
471 }
472# mikan Oyama type_qualifier だけでは型指定にならない : 構文エラーとするより、意味エラーとした方が親切
473# | type_qualifier
474
475
476struct_declarator_list
477 : struct_declarator
478 { result = [ val[0] ] }
479 | struct_declarator_list ',' struct_declarator
480 { result << val[2] }
481
482# ビットフィールドは使えない
483struct_declarator
484 : declarator
485
486# enumの種類を追加
487enum_specifier # mikan
488 : enum_type '{' enumerator_list '}'
489 | enum_type IDENTIFIER '{' enumerator_list '}'
490 | enum_type IDENTIFIER
491
492enum_type
493 : ENUM { result = EnumType.new( -1 ) }
494 | ENUM8 { result = EnumType.new( 8 ) }
495 | ENUM16 { result = EnumType.new( 16 ) }
496 | ENUM32 { result = EnumType.new( 32 ) }
497 | ENUM64 { result = EnumType.new( 64 ) }
498 | ENUM128 { result = EnumType.new( 128 ) }
499
500enumerator_list
501 : enumerator
502 | enumerator_list ',' enumerator
503
504enumerator
505 : IDENTIFIER
506 | IDENTIFIER '=' constant_expression
507
508type_qualifier
509 : CONST { result = :CONST }
510 | VOLATILE { result = :VOLATILE }
511
512declarator
513 : pointer direct_declarator
514 {
515 val[1].set_type( val[0] )
516 result = val[1]
517 }
518 | direct_declarator
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( ArrayType.new( val[2] ) )
528 result = val[0]
529 }
530 | direct_declarator '[' ']'
531 {
532 val[0].set_type( ArrayType.new )
533 result = val[0]
534 }
535 | direct_declarator '(' parameter_type_list ')'
536 {
537 val[0].set_type( FuncType.new( val[2] ) )
538 result = val[0]
539 }
540# | direct_declarator '(' identifier_list ')' # これは何のために必
541要? 060211
542 | direct_declarator '(' ')'
543 {
544 Generator.warning( "W5010 need 'void' for no parameter" )
545 val[0].set_type( FuncType.new )
546 result = val[0]
547 }
548
549pointer
550 : '*'
551 { result = PtrType.new }
552 | '*' type_qualifier
553 {
554 result = PtrType.new
555 result.set_qualifier( val[1] )
556 }
557 | '*' pointer
558 {
559 val[1].set_type(PtrType.new)
560 result = val[1]
561 }
562 | '*' type_qualifier pointer
563 {
564 ptrtype = PtrType.new
565 ptrtype.set_qualifier( val[1] )
566 val[2].set_type( ptrtype )
567 result = val[2]
568 }
569
570
571parameter_type_list
572 : parameter_list
573 | parameter_list ',' '...'
574 # mikan 可変長パラメータ
575
576parameter_list
577 : parameter_declaration
578 { result = ParamList.new( val[0] ) }
579 | parameter_list ',' parameter_declaration
580 {
581 val[0].add_param( val[2] )
582 # result = val[0] 不要
583 }
584
585
586# パラメータ修飾子を追加
587parameter_declaration
588# : spec_L parameter_specifier_list spec_R declaration_specifiers declarator
589 : parameter_specifier_list_bracket declaration_specifiers declarator
590 {
591 val[2].set_kind( :PARAMETER )
592 paramdecl = ParamDecl.new( val[2], val[1], val[0] )
593 val[2].check
594 result = paramdecl
595 }
596
597 # 以下はエラーとする
598 | declaration_specifiers declarator # parameter_specifier なしは扱わない
599 {
600 Generator.error( "G1001 need specifier for \'$1\'" , val[1].get_name )
601 result = nil
602 }
603 | declaration_specifiers # 仮引数なしは、とりあえず扱わない 060210
604 {
605 unless val[0].instance_of?( VoidType ) then
606 Generator.error( "G1002 need parameter name" )
607 end
608 result = nil
609 }
610# | '[' parameter_specifier_list ']' declaration_specifiers # 同 060210
611 | parameter_specifier_list_bracket declaration_specifiers # 同 060210
612 {
613 unless val[1].instance_of?( VoidType ) then
614 Generator.error( "G1003 need parameter name" )
615 end
616 result = nil
617 }
618
619parameter_specifier_list_bracket
620 : spec_L parameter_specifier_list spec_R { result = val[1] }
621# : '[' parameter_specifier_list ']' { result = val[1] }
622
623parameter_specifier_list
624 : parameter_specifier { result = val[0] }
625 | parameter_specifier_list ',' parameter_specifier
626 { result = result + val[2] }
627
628parameter_specifier
629 : IN { result = [ [:IN] ] }
630 | OUT { result = [ [:OUT] ] }
631 | INOUT { result = [ [:INOUT] ] }
632 | SEND '(' namespace_identifier ')' { result = [ [:SEND, val[2]] ] } #1ok allocator
633 | RECEIVE '(' namespace_identifier ')' { result = [ [:RECEIVE,val[2]] ] } #1ok allocator
634 | STRING { result = [ [:STRING,nil] ] }
635 | STRING '(' expression ')' { result = [ [:STRING, val[2]] ] }
636 | SIZE_IS '(' expression ')' { result = [ [:SIZE_IS, val[2]] ] }
637 | SIZE_IS '(' expression ',' constant_expression ')'
638 {
639 result = [ [:SIZE_IS,val[2]], [:MAX_IS, val[4]] ]
640 }
641 | COUNT_IS '(' expression ')' { result = [ [:COUNT_IS,val[2]] ] }
642 | NULLABLE { result = [ [:NULLABLE] ] }
643
644type_name
645 : type_specifier_qualifier_list
646 | type_specifier_qualifier_list abstract_declarator
647 {
648 if val[1] then
649 val[1].set_type( val[0] )
650 result = val[1]
651 else
652 # エラー:仮で val[0] を返す
653 result = val[0]
654 end
655 }
656 # mikan abstract_declarator が pointer 以外ではうまく動かない、とりあえず '*' CAST のみ救った
657
658abstract_declarator # mikan
659 : pointer
660 | direct_abstract_declarator
661 | pointer direct_abstract_declarator
662
663direct_abstract_declarator
664 : '(' abstract_declarator ')'
665 { result = val[1] } # 関数ポインタ型を救う
666 | '[' ']'
667 {
668 Generator.error( "G1004 impossible array type" )
669 result = nil
670 }
671 | '[' constant_expression ']'
672 {
673 Generator.error( "G1005 impossible array type" )
674 result = nil
675 }
676 | direct_abstract_declarator '[' ']'
677 {
678 Generator.error( "G1006 impossible array type" )
679 result = nil
680 }
681 | direct_abstract_declarator '[' constant_expression ']'
682 {
683 Generator.error( "G1007 impossible array type" )
684 result = nil
685 }
686 | '(' ')'
687 {
688 Generator.error( "G1008 impossible function type" )
689 result = nil
690 }
691 | '(' parameter_type_list ')'
692 | direct_abstract_declarator '(' ')'
693 {
694 Generator.warning( "W5011 need 'void' for no parameter" )
695 val[0].set_type( FuncType.new )
696 result = val[0]
697 }
698 | direct_abstract_declarator '(' parameter_type_list ')'
699 {
700 val[0].set_type( FuncType.new( val[2] ) )
701 result = val[0]
702 }
703
704# assignment_expressionをconstant_expressionに変更
705initializer # mikan
706 : constant_expression
707 { result = val[0] }
708 | '{' initializer_list '}'
709 { result = val[1] }
710 | '{' initializer_list ',' '}'
711 { result = val[1] }
712# | C_EXP '(' STRING_LITERAL ')'
713 | C_EXP '(' string_literal_list ')'
714 { result = C_EXP.new( val[2] ) }
715
716initializer_list
717 : initializer
718 {
719 result = [ val[0] ]
720 }
721 | initializer_list ',' initializer
722 {
723 val[0] << val[2]
724 result = val[0]
725 }
726
727
728########################## ここからはCDL独自 ##########################
729
730#トップレベルの構文規則
731#コンポーネント記述
732component_description
733 : component_description specified_statement
734 | component_description location_information
735 | component_description tool_info
736 |
737
738specified_statement
739 : statement
740 | spec_L statement_specifier_list spec_R statement
741 {
742 obj = val[3]
743 if obj.kind_of?( Cell ) || obj.kind_of?( Signature ) || obj.kind_of?( Celltype ) || obj.kind_of?( CompositeCelltype )then
744 # cell, signature 以外は、指定子を置けない
745 else
746 Generator.get_statement_specifier # クリア
747 Generator.error( "G1009 unexpected specifier" )
748 end
749 }
750 # これと同じ記述が composite_celltype にもある
751
752statement
753 : typedef
754 | const_statement
755 | namespace
756 | signature
757 | celltype
758 | cell
759 | composite_celltype
760 | enum_specifier ';'
761 | struct_specifier ';'
762 | region
763 | import
764 | import_C
765 | generate_statement
766 | error # エラー回復ポイント
767
768
769statement_specifier_list
770 : statement_specifier
771 { Generator.add_statement_specifier val[0] }
772 | statement_specifier_list ',' statement_specifier
773 { Generator.add_statement_specifier val[2] }
774
775statement_specifier
776 : ALLOCATOR '(' alloc_list ')' # cell
777 { result = [ :ALLOCATOR, val[2] ] }
778 | CALLBACK # signature
779 { result = [ :CALLBACK ] }
780 | CONTEXT '(' string_literal_list ')' # signature
781 { result = [ :CONTEXT, val[2].val ] }
782 | DEVIATE # signature
783 { result = [ :DEVIATE ] }
784 | ID '(' constant_expression ')' # cell
785 { result = [ :ID, val[2] ] }
786 | PROTOTYPE # cell
787 { result = [ :PROTOTYPE ] }
788 | RESTRICT '(' restrict_list ')' # cell
789 { result = [ :RESTRICT, val[2] ] }
790 | SINGLETON { result = [:SINGLETON] } # celltype, composite
791 | IDX_IS_ID { result = [:IDX_IS_ID] } # celltype, composite (composite: no-effective)
792 | ACTIVE { result = [:ACTIVE] } # celltype, composite
793 | GENERATE '(' plugin_name ',' plugin_arg ')' # celltype, cell
794 { result = [:GENERATE, val[2].val, val[4].val] }
795
796alloc_list
797 : alloc { result = [ val[0] ] }
798 | alloc_list ',' alloc { result << val[2] }
799
800alloc
801 : IDENTIFIER '.' IDENTIFIER '.' IDENTIFIER '=' initializer
802 { result = [ :NORMAL_ALLOC, val[0], nil, val[2], val[4], val[6] ] }
803 | IDENTIFIER '[' constant_expression ']' '.' IDENTIFIER '.' IDENTIFIER '=' initializer
804 { result = [ :NORMAL_ALLOC, val[0], val[2], val[5], val[7], val[9] ] }
805# mikan 将来的な拡張 ('*' でまとめて指定可能とする)
806# | IDENTIFIER '.' IDENTIFIER '.' '*' '=' initializer
807# { result = [ val[0], val[ ], val[ ], val[ ] ] }
808# | IDENTIFIER '.' '*' '.' '*' '=' initializer
809# { result = [ val[0], val[ ], val[ ], val[ ] ] }
810
811restrict_list
812 : restrict
813 { result = [val[0]] }
814 | restrict_list ',' restrict
815 { result << val[2] }
816
817restrict
818 : port_name '=' '{' region_name_list '}'
819 { result = [ val[0].val, nil, val[3] ] }
820 | port_name '.' IDENTIFIER '=' '{' region_name_list '}'
821 { result = [ val[0].val, val[2].val, val[5] ] }
822
823region_name_list
824 : namespace_identifier
825 { result = [val[0]] }
826 | region_name_list ',' namespace_identifier
827 { result << val[2] }
828
829const_statement
830 : declaration # 定数定義
831 {
832 val[0].each { |decl|
833 decl.set_kind( :CONSTANT )
834 Namespace.new_const_decl( decl )
835 decl.check
836 }
837 }
838
839import_C
840 : IMPORT_C '(' STRING_LITERAL ')' ';'
841 {
842 @@import_C = true
843 Import_C.new( val[2] )
844 @@import_C = false
845 }
846 | IMPORT_C '(' STRING_LITERAL ',' STRING_LITERAL ')' ';'
847 {
848 @@import_C = true
849 Import_C.new( val[2], val[4] )
850 @@import_C = false
851 }
852
853import
854 : IMPORT '(' STRING_LITERAL ')' ';'
855 { Import.new( val[2] ) }
856 | IMPORT '(' AB_STRING_LITERAL ')' ';'
857 { Import.new( val[2], true ) }
858
859generate_statement
860# : GENERATE '(' plugin_name ',' namespace_identifier ',' STRING_LITERAL ')' ';' #1ok signature plugin
861 : GENERATE '(' plugin_name ',' namespace_identifier ',' plugin_arg ')' ';' #1ok signature plugin
862 { Generate.new( val[2].val, val[4], val[6] ) }
863
864typedef
865 : TYPEDEF type_specifier_qualifier_list declarator_list ';'
866 {
867 val[2].each{ |i| # i:Decl
868 i.set_kind( :TYPEDEF )
869 }
870 Typedef.new_decl_list( val[1], val[2] )
871 val[2].each{ |i| # i:Decl
872 i.check
873 }
874 }
875 | TYPEDEF '[' typedef_specifier ']' type_specifier_qualifier_list declarator_list ';'
876 {
877 val[5].each{ |i| # i:Decl
878 i.set_kind( :TYPEDEF )
879 }
880 Typedef.new_decl_list( val[4], val[5] )
881 val[5].each{ |i| # i:Decl
882 i.check
883 }
884 }
885 # mikan typedef_specifier 未処置
886
887
888typedef_specifier
889 : STRING
890 | STRING '(' expression ')'
891
892declarator_list
893 : declarator
894 { result = [ val[0] ] }
895 | declarator_list ',' declarator
896 { result << val[2] }
897
898namespace
899 : NAMESPACE namespace_name '{' statement_list '}' ';'
900 {val[1].end_of_parse}
901
902namespace_name
903 : IDENTIFIER
904 {result = Namespace.new(val[0].val)}
905 # namespace インスタンスに statement を記憶させるためここで生成
906
907statement_list
908 : specified_statement
909 | statement_list specified_statement
910
911namespace_identifier
912 : IDENTIFIER { result = NamespacePath.new( val[0].val, false ) }
913 | '::' IDENTIFIER { result = NamespacePath.new( val[1].val, true ) }
914 | namespace_identifier '::' IDENTIFIER
915 { result = val[0].append!( val[2].val ) }
916
917#シグニチャ
918signature
919 : SIGNATURE signature_name '{' function_head_list '}' ';'
920 { result = val[1].end_of_parse( val[3] ) }
921
922signature_name
923 : IDENTIFIER
924 {result = Signature.new( val[0].val ) }
925
926function_head_list # result: function_head のé…
927åˆ—
928# : function_head
929# { result = NamedList.new( val[0], "function" ) }
930 :
931 { result = NamedList.new( nil, "function" ) }
932 | function_head_list function_head
933 { result = val[0].add_item( val[1] ) }
934
935function_head
936 : type_specifier_qualifier_list declarator ';'
937 {
938 # val[1]: Decl
939 if val[1].is_function? then
940 result = FuncHead.new( val[1], val[0], false )
941 val[1].set_kind :FUNCHEAD
942 val[1].check
943 else
944 # mikan 関数のé…
945åˆ—も以下のメッセージになる
946 Generator.error( "G1010 Not function" )
947 result = nil
948 end
949 }
950 | spec_L ONEWAY spec_R type_specifier_qualifier_list declarator ';'
951 {
952 if val[4].is_function? then
953 result = FuncHead.new( val[4], val[3], true )
954 else
955 Generator.error( "G1011 Not function" )
956 result = nil
957 end
958 }
959
960
961#セルタイプ
962celltype
963 : CELLTYPE celltype_name '{' celltype_statement_list '}' ';'
964 {
965 val[1].end_of_parse
966 result = val[1]
967 }
968
969celltype_name
970 : IDENTIFIER
971 { result = Celltype.new(val[0].val) }
972
973celltype_statement_list
974 : specified_celltype_statement
975 | celltype_statement_list specified_celltype_statement
976
977specified_celltype_statement
978 : celltype_statement
979 {
980 if val[0].kind_of? Port then
981 Celltype.new_port( val[0] )
982 end
983 }
984 | spec_L celltype_statement_specifier_list spec_R celltype_statement
985 {
986 if val[3].kind_of? Port then
987 val[3].set_specifier val[1] # 設定順序あり
988 Celltype.new_port( val[3] )
989 else
990 # Port 以外では指定子はエラー
991 Generator.error( "G1012 $1 : cannot put specifier here" , val[1] )
992 end
993 }
994
995celltype_statement
996 : port
997 | attribute
998 | var
999 | require
1000 | factory
1001# | error # エラー回復ポイント (#513 無限ループに陥るケースがあるので、ここでのエラー回復は取りやめ)
1002
1003celltype_statement_specifier_list
1004 : celltype_statement_specifier
1005 { result = [ val[0] ] }
1006 | celltype_statement_specifier_list ',' celltype_statement_specifier
1007 { result << val[2] }
1008
1009celltype_statement_specifier
1010 : INLINE { result = [ :INLINE ] }
1011 | ALLOCATOR '(' alloc_list2 ')' { result = [ :ALLOCATOR, val[2] ] }
1012 | OPTIONAL { result = [ :OPTIONAL ] }
1013 | REF_DESC { result = [ :REF_DESC ] }
1014 | DYNAMIC { result = [ :DYNAMIC ] }
1015 | OMIT { result = [ :OMIT ] }
1016
1017alloc_list2
1018 : alloc2 { result = [ val[0] ] } # 受け口のアロケータ指定
1019 | alloc { result = [ val[0] ] } # 内
1020部セルのアロケータ指定
1021 | alloc_list2 ',' alloc2 { result << val[2] }
1022 | alloc_list2 ',' alloc { result << val[2] }
1023
1024alloc2
1025 : IDENTIFIER '.' IDENTIFIER '=' initializer # 内
1026部アロケータ (デバドラ向きアロケータ)指定
1027 { result = [ :INTERNAL_ALLOC, val[0].val, val[2].val, val[4] ] }
1028 | IDENTIFIER '.' IDENTIFIER '<=' initializer # 多段リレーモデル向きアロケータ指定
1029 { result = [ :RELAY_ALLOC, val[0].val, val[2].val, val[4] ] }
1030
1031
1032#呼び口、受け口
1033port
1034 : port_type namespace_signature_name port_name ';'
1035 { result = Port.new( val[2].val, val[1], val[0] ) }
1036 | port_type namespace_signature_name port_name '[' ']' ';'
1037 { result = Port.new( val[2].val, val[1], val[0], "[]" ) }
1038 | port_type namespace_signature_name port_name '[' array_size ']' ';'
1039 { result = Port.new(val[2].val, val[1], val[0], val[4]) }
1040 | port_type namespace_signature_name port_name '<=' namespace_identifier '.' IDENTIFIER ';' #1ok reverse require
1041 { result = Port.new( val[2].val, val[1], val[0], nil, val[4], val[ 6 ].val ) }
1042
1043port_type
1044 : CALL { result = :CALL }
1045 | ENTRY { result = :ENTRY }
1046
1047namespace_signature_name
1048 : namespace_identifier #1ok
1049 { result = val[0] }
1050
1051port_name
1052 : IDENTIFIER
1053
1054array_size
1055 : constant_expression
1056
1057
1058#属性
1059attribute
1060 : ATTRIBUTE '{' attribute_declaration_list '}' ';'
1061 { result = nil }
1062
1063attribute_declaration_list
1064 : attribute_declaration
1065 { Celltype.new_attribute( val[0] ) }
1066 | attribute_declaration_list attribute_declaration
1067 { Celltype.new_attribute( val[1] ) }
1068
1069
1070attribute_declaration
1071 : declaration
1072 {
1073 val[0].each{ |i| # i:Decl
1074 i.set_kind( :ATTRIBUTE )
1075 i.check
1076 }
1077 result = val[0]
1078 }
1079 | spec_L attribute_specifier spec_R declaration
1080 {
1081 val[3].each{ |i| # i:Decl
1082 i.set_kind( :ATTRIBUTE ) # 設定順序あり
1083 i.set_specifier_list( [val[1]] )
1084 i.check
1085 }
1086 result = val[3]
1087 }
1088
1089attribute_specifier
1090 : OMIT { result = [:OMIT] }
1091 | SIZE_IS '(' expression ')' { result = [:SIZE_IS,val[2]] }
1092 | CHOICE '=' '{' choice_list '}' { result = [:CHOICE,val[3]] }
1093
1094choice_list
1095 : choice_list ',' choice_element { result << val[2] }
1096 | choice_element { result = [ val[0] ] }
1097
1098choice_element
1099 : STRING_LITERAL
1100
1101#内
1102部変数
1103var
1104 : VAR '{' var_declaration_list '}' ';'
1105 { result = nil }
1106
1107var_declaration_list
1108 : var_declaration
1109 { Celltype.new_var( val[0] ) }
1110 | var_declaration_list var_declaration
1111 { Celltype.new_var( val[1] ) }
1112
1113var_declaration
1114 : declaration
1115 {
1116 val[0].each{ |i| # i:Decl
1117 i.set_kind( :VAR )
1118 i.check
1119 }
1120 }
1121 | spec_L var_specifier spec_R declaration
1122 {
1123 val[3].each{ |i| # i:Decl
1124 i.set_kind( :VAR ) # 設定順序あり
1125 i.set_specifier_list( [val[1]] )
1126 i.check
1127 }
1128 result = val[3]
1129 }
1130
1131var_specifier
1132 : SIZE_IS '(' expression ')' { result = [:SIZE_IS,val[2]] }
1133
1134# リクワイア
1135require
1136 : REQUIRE namespace_identifier '.' IDENTIFIER';' # mikan namespace #1
1137 {
1138 Celltype.new_require( val[1], val[3] )
1139 }
1140 | REQUIRE IDENTIFIER '=' namespace_identifier '.' IDENTIFIER';' #1
1141 {
1142 Celltype.new_require( val[3], val[5], val[1].val )
1143 }
1144
1145#ファクトリ
1146factory
1147 : factory_head '{' factory_function_list '}' ';'
1148
1149factory_head
1150 : FACTORY { Factory.set_f_celltype( false ) }
1151 | CTFACTORY { Factory.set_f_celltype( true ) }
1152
1153factory_function_list
1154 : # 空
1155 | factory_function_list factory_function
1156
1157factory_function
1158 : factory_function_name '(' constant_expression ',' constant_expression ')' ';'
1159 { Factory.new( val[0].val, val[2], val[4], nil ) }
1160 | factory_function_name '(' constant_expression ',' constant_expression ',' arg_list ')' ';'
1161 { Factory.new( val[0].val, val[2], val[4], val[6] ) }
1162
1163factory_function_name
1164 : IDENTIFIER
1165
1166arg_list # factory の write 関数の第三引数以降
1167 : IDENTIFIER
1168 { result = [ [ :IDENTIFIER, val[0].val ] ] }
1169 | arg_list ',' IDENTIFIER
1170 { result << [ :IDENTIFIER, val[2].val ] }
1171 | STRING_LITERAL
1172 { result = [ [ :STRING_LITERAL, val[0].val ] ] }
1173 | arg_list ',' STRING_LITERAL
1174 { result << [ :STRING_LITERAL, val[2].val ] }
1175
1176#セル生成
1177cell
1178 : CELL namespace_celltype_name cell_name '{'
1179 { Cell.new_def }
1180 join_list '}' ';'
1181 { result = Cell.end_of_parse true }
1182 | CELL namespace_celltype_name cell_name ';' # oyama プロトタイプ宣言
1183 { result = Cell.end_of_parse false }
1184
1185namespace_celltype_name
1186 : namespace_identifier
1187 { result = Cell.new(val[0]) }
1188
1189cell_name
1190 : IDENTIFIER
1191 { result = Cell.set_name(val[0].val) }
1192
1193join_list
1194 : # 空行 061007
1195 | join_list specified_join
1196 | join_list reverse_join
1197
1198specified_join
1199 : spec_L join_specifier_list spec_R join
1200 { val[3].set_specifier_list( val[1] ) }
1201 | join
1202 { val[0].set_specifier_list( [] ) }
1203
1204join_specifier_list
1205 : join_specifier_list ',' join_specifier
1206 { result << val[2] }
1207 | join_specifier
1208 { result = [val[0]] }
1209
1210join_specifier
1211 : THROUGH '(' plugin_name ',' plugin_arg ')'
1212 { result = [ :THROUGH, val[2], val[4] ] }
1213
1214plugin_name
1215 : IDENTIFIER { result = val[0] }
1216
1217plugin_arg
1218 : string_literal_list
1219
1220join
1221# : cae_name '=' expression ';'
1222# {
1223# result = Join.new( val[0].val, nil, val[2] )
1224# Cell.new_join( result, true )
1225# }
1226# | cae_name '[' ']' '=' expression ';'
1227 : cae_name '[' ']' '=' expression ';'
1228 {
1229 result = Join.new( val[0].val, -1, val[4] )
1230 Cell.new_join( result, true )
1231 }
1232 | cae_name '[' array_index ']' '=' expression ';'
1233 {
1234 result = Join.new( val[0].val, val[2], val[5] )
1235 Cell.new_join( result, true )
1236 }
1237 | cae_name '=' initializer ';' # 初期化子: '{', '}' も可
1238 {
1239 result = Join.new( val[0].val, nil, val[2] )
1240 Cell.new_join( result, true )
1241 }
1242 | cae_name '=' COMPOSITE '.' IDENTIFIER ';'
1243 {
1244 result = Join.new( val[0].val, nil, [ :COMPOSITE, val[4] ] )
1245 Cell.new_join( result, true )
1246 }
1247
1248cae_name # cae: callport, attribute, entryport
1249 : IDENTIFIER
1250
1251reverse_join
1252 # non-array <= non-array
1253 : cae_name '<=' namespace_identifier '.' IDENTIFIER ';'
1254 {
1255 rj = ReverseJoin.new( val[0].val, nil, val[2], val[4].val )
1256 Cell.new_reverse_join( rj )
1257 }
1258 # non-array <= array
1259 | cae_name '<=' namespace_identifier '.' IDENTIFIER '[' expression ']' ';'
1260 {
1261 rj = ReverseJoin.new( val[0].val, nil, val[2], val[4].val, val[6] )
1262 Cell.new_reverse_join( rj )
1263 }
1264 # array <= non-array
1265 | cae_name '[' array_index ']' '<=' namespace_identifier '.' IDENTIFIER ';'
1266 {
1267 rj = ReverseJoin.new( val[0].val, val[2], val[5], val[7].val )
1268 Cell.new_reverse_join( rj )
1269 }
1270 # array <= array
1271 | cae_name '[' array_index ']' '<=' namespace_identifier '.' IDENTIFIER '[' expression ']' ';'
1272 {
1273 rj = ReverseJoin.new( val[0].val, val[2], val[5], val[7].val, val[9] )
1274 Cell.new_reverse_join( rj )
1275 }
1276
1277
1278array_index
1279 : constant_expression
1280
1281#複合種
1282composite_celltype
1283 : COMPOSITE composite_celltype_name '{' composite_celltype_statement_list '}' ';'
1284 {
1285 CompositeCelltype.end_of_parse
1286 result = val[1]
1287 }
1288
1289composite_celltype_name
1290 : IDENTIFIER
1291 { result = CompositeCelltype.new(val[0].val) }
1292
1293composite_celltype_statement_list
1294 : specified_composite_celltype_statement
1295 | composite_celltype_statement_list specified_composite_celltype_statement
1296
1297specified_composite_celltype_statement
1298 : composite_celltype_statement
1299 {
1300 if val[0].kind_of?( Port ) then
1301 CompositeCelltype.new_port( val[0] ) # 遅
1302延して登録
1303 end
1304 }
1305 | spec_L composite_celltype_statement_specifier_list spec_R composite_celltype_statement
1306 {
1307 if val[3].kind_of?( Port ) then
1308 # port 以外 val[3] に有効な値がå…
1309¥ã£ã¦ã„ないので、以下のメソッドを適用できない
1310 # 現状 port, cell 以外は指定子を受け付けない
1311 # (しかし将来他の文も指定子を受け付ける可能性があるので、この位置に記述する)
1312 val[3].set_specifier( Generator.get_statement_specifier )
1313 CompositeCelltype.new_port( val[3] ) # 遅
1314延して登録 (set_specifier 後)
1315 elsif val[3].kind_of?( Cell ) then
1316 # Cell.end_of_parse にて設定
1317 else
1318 Generator.get_statement_specifier # クリア
1319 Generator.error( "G1013 unexpected specifier" )
1320 end
1321 }
1322
1323composite_celltype_statement
1324 : composite_port
1325 | composite_attribute
1326 | internal_cell
1327 | export_join
1328# | error # エラー回復ポイント (#513 無限ループに陥るケースがあるので、ここでのエラー回復は取りやめ)
1329
1330composite_celltype_statement_specifier_list
1331 : composite_celltype_statement_specifier
1332 {
1333 Generator.add_statement_specifier val[0]
1334 result = [ val[0] ]
1335 }
1336 | composite_celltype_statement_specifier_list ',' composite_celltype_statement_specifier
1337 {
1338 Generator.add_statement_specifier val[2]
1339 result = val[0] << val[2]
1340 }
1341
1342composite_celltype_statement_specifier
1343 : ALLOCATOR '(' alloc_list2 ')' { result = [ :ALLOCATOR, val[2] ] }
1344 | OMIT { result = [ :OMIT ] }
1345 | OPTIONAL { result = [ :OPTIONAL ] }
1346 | REF_DESC { result = [ :REF_DESC ] }
1347 | DYNAMIC { result = [ :DYNAMIC ] }
1348
1349composite_port
1350 : port
1351 {
1352 # CompositeCelltype.new_port( val[0] )
1353 result = val[0]
1354 }
1355
1356#属性
1357composite_attribute
1358 : ATTRIBUTE '{' composite_attribute_declaration_list '}' ';'
1359 { result = nil }
1360
1361composite_attribute_declaration_list
1362 : attribute_declaration
1363 { CompositeCelltype.new_attribute( val[0] ) }
1364 | composite_attribute_declaration_list attribute_declaration
1365 { CompositeCelltype.new_attribute( val[1] ) }
1366
1367internal_cell
1368 : CELL internal_namespace_celltype_name
1369 internal_cell_name '{'
1370 { Cell.new_def }
1371 internal_join_list '}' ';'
1372 { result = Cell.end_of_parse true }
1373 | CELL internal_namespace_celltype_name internal_cell_name ';'
1374 { result = Cell.end_of_parse false }
1375
1376
1377internal_namespace_celltype_name
1378 : namespace_identifier
1379 { Cell.new(val[0],true) }
1380
1381internal_cell_name
1382 : IDENTIFIER
1383 { Cell.set_name(val[0].val) }
1384
1385
1386internal_join_list
1387 : # 空行 061007
1388 | internal_join_list specified_join
1389 | internal_join_list external_join
1390 | internal_join_list reverse_join
1391
1392external_join # cell 内
1393に記述する呼び口の外部結合
1394 : internal_cell_elem_name '=>' COMPOSITE '.' export_name ';'
1395 { Cell.external_join( val[0].val, val[4].val, true ) }
1396 | internal_cell_elem_name '=>' export_name ';'
1397 { Cell.external_join( val[0].val, val[2].val, false ) }
1398 # 以前の文法では、呼び口側も cell の外に記述していた
1399 # その時の実装
1400を
1401
1402export_join # cell 外に記述する受け口の外部結合
1403 : export_name '=>' internal_ref_cell_name '.' internal_cell_elem_name ';'
1404 {
1405 CompositeCelltype.new_join( val[0].val,
1406 val[2].val, val[4].val, :ENTRY )
1407 }
1408 | COMPOSITE '.' export_name '=>' internal_ref_cell_name '.' internal_cell_elem_name ';'
1409 {
1410 CompositeCelltype.new_join( val[2].val,
1411 val[4].val, val[6].val, :ENTRY )
1412 }
1413
1414export_name
1415 : IDENTIFIER
1416
1417internal_ref_cell_name
1418 : IDENTIFIER
1419
1420internal_cell_elem_name
1421 : IDENTIFIER
1422
1423# リージョン
1424region
1425 : spec_L region_specifier_list spec_R REGION region_name '{' region_statement '}' ';'
1426 { Region.end_of_parse }
1427 | REGION region_name '{' region_statement '}' ';'
1428 { Region.end_of_parse }
1429
1430
1431region_specifier_list
1432 : region_specifier
1433 | region_specifier_list ',' region_specifier
1434
1435region_specifier
1436 : IN_THROUGH '(' plugin_name ',' plugin_arg ')'
1437 { Region.new_in_through( val[2].val, val[4].val ) }
1438 | IN_THROUGH '(' ')' # in 許可
1439 { Region.new_in_through }
1440 | OUT_THROUGH '(' plugin_name ',' plugin_arg ')'
1441 { Region.new_out_through( val[2].val, val[4].val ) }
1442 | OUT_THROUGH '(' ')' # out 許可
1443 { Region.new_out_through() }
1444 | TO_THROUGH '(' namespace_region_name ',' plugin_name ',' plugin_arg ')'
1445 { Region.new_to_through( val[2], val[4].val, val[6].val ) }
1446 | TO_THROUGH '('namespace_region_name ')' # to 許可
1447 { Region.new_to_through( val[2], nil, nil ) }
1448 | NODE
1449 { Region.set_type( :NODE ) }
1450 | LINKUNIT
1451 { Region.set_type( :LINKUNIT ) }
1452 | DOMAIN '(' IDENTIFIER ',' STRING_LITERAL ')'
1453 { Region.set_domain( val[2].val, val[4] ) }
1454 | CLASS '(' IDENTIFIER ')'
1455 { Region.set_type( :CLASS, val[2].val ) }
1456
1457region_name
1458 : IDENTIFIER
1459 { result = Region.new( val[0].val ) }
1460
1461region_statement
1462 :
1463 | region_statement region_cell
1464 | region_statement region
1465
1466region_cell
1467 : cell
1468 | spec_L statement_specifier_list spec_R cell
1469 {
1470 obj = val[3]
1471 if obj.kind_of?( Cell ) then
1472 else
1473 Generator.get_statement_specifier # クリア
1474 Generator.error( "G9999 unexpected specifier" )
1475 end
1476 }
1477# | spec_L region_cell_specifier_list spec_R cell
1478
1479# region_cell_specifier_list
1480# : region_cell_specifier
1481# { Generator.add_statement_specifier val[0] }
1482# | region_cell_specifier_list region_cell_specifier
1483# { Generator.add_statement_specifier val[2] }
1484
1485# region_cell_specifier
1486# : ALLOCATOR '(' alloc_list ')'
1487# { result = [ :ALLOCATOR, val[2] ] }
1488
1489
1490namespace_region_name
1491 : :IDENTIFIER
1492 { result = [ val[0].val ] } # mikan é…
1493åˆ—である必
1494要はない
1495# : namespace_identifier
1496
1497# 指定子の括弧 (in, out などのキーワード切り替えのため分離)
1498spec_L
1499 : '[' { set_in_specifier }
1500spec_R
1501 : ']' { unset_in_specifier }
1502
1503# location information
1504location_information
1505 : __LOCATION_INFORMATION__ '{' cell_location_join_location_list '}'
1506
1507cell_location_join_location_list
1508 : cell_location_join_location_list cell_location
1509 | cell_location_join_location_list join_location
1510 |
1511
1512cell_location
1513 : __CELL__ namespace_identifier '(' constant_expression ',' constant_expression ',' constant_expression ',' constant_expression ')' '{' port_location_list '}'
1514 {
1515 TECSGEN::Cell_location.new( val[1], val[3], val[5], val[7], val[9], val[12] )
1516 }
1517
1518port_location_list
1519 : port_location_list port_location
1520 {
1521 result = val[0] << val[1]
1522 }
1523 |
1524 { result = [] }
1525
1526port_location
1527 : IDENTIFIER '(' IDENTIFIER ',' constant_expression ')'
1528 { result = [ val[0], val[2], val[3] ] }
1529
1530join_location # mikan port array
1531 : __JOIN__ '(' namespace_identifier '.' IDENTIFIER '=>' namespace_identifier '.' IDENTIFIER ')' '{' bar_list '}'
1532 {
1533 TECSGEN::Join_location.new( val[2], val[4], val[6], val[8], val[11] )
1534 }
1535
1536bar_list
1537 : bar_list IDENTIFIER '(' constant_expression ')'
1538 {
1539 result = val[0] << [ val[1], val[3] ]
1540 }
1541 | { result = [] }
1542
1543
1544# JSON object
1545tool_info : TOOL_INFO '(' JSON_string ')' JSON_object { TOOL_INFO.new( val[2].to_sym, val[4] ) }
1546JSON_object : '{' JSON_property_list '}' { result = val[1] }
1547JSON_property_list : JSON_string ':' JSON_value { result = { val[0].to_sym => val[2] } }
1548 | JSON_property_list ',' JSON_string ':' JSON_value
1549 { val[0][ val[2].to_sym ] = val[4] }
1550JSON_value : JSON_string | JSON_number | JSON_object | JSON_array
1551 | TRUE { result=val[0].val } | FALSE { result=val[0].val } # JSON_NULL # null not suppoted
1552JSON_array : '[' JSON_array_list ']' { result = val[1] }
1553 | '[' ']' { result = [] }
1554JSON_array_list : JSON_value { result = [ val[0] ] }
1555 | JSON_array_list ',' JSON_value { val[0] << val[2] }
1556JSON_string : STRING_LITERAL { result = val[0].val.gsub!( /\"(.*)\"/, "\\1" ) }
1557JSON_number : INTEGER_CONSTANT { result = val[0].val.to_i }
1558 | FLOATING_CONSTANT { result = val[0].val.to_f }
1559 | '-' INTEGER_CONSTANT { result = - val[0].val.to_i }
1560 | '-' FLOATING_CONSTANT { result = - val[0].val.to_f }
1561 | '+' INTEGER_CONSTANT { result = val[0].val.to_i }
1562 | '+' FLOATING_CONSTANT { result = val[0].val.to_f }
1563
1564
1565end
1566
1567---- inner
1568
1569 RESERVED = {
1570 # keyword
1571 'namespace' => :NAMESPACE,
1572 'signature' => :SIGNATURE,
1573 'celltype' => :CELLTYPE,
1574 'cell' => :CELL,
1575 'attr' => :ATTRIBUTE,
1576 'var' => :VAR,
1577 'call' => :CALL,
1578 'entry' => :ENTRY,
1579 'composite' => :COMPOSITE,
1580 'require' => :REQUIRE,
1581 'factory' => :FACTORY,
1582 'FACTORY' => :CTFACTORY,
1583 'typedef' => :TYPEDEF,
1584 'struct' => :STRUCT,
1585 'region' => :REGION,
1586 'import' => :IMPORT,
1587 'import_C' => :IMPORT_C,
1588 'generate' => :GENERATE,
1589 '__tool_info__' => :TOOL_INFO,
1590
1591 # types
1592 'void' => :VOID,
1593
1594 'volatile'=> :VOLATILE,
1595 'const' => :CONST,
1596
1597 'signed' => :SIGNED,
1598 'unsigned'=> :UNSIGNED,
1599
1600 'int8_t' => :INT8_T,
1601 'int16_t' => :INT16_T,
1602 'int32_t' => :INT32_T,
1603 'int64_t' => :INT64_T,
1604 'int128_t' => :INT128_T,
1605 'uint8_t' => :UINT8_T,
1606 'uint16_t' => :UINT16_T,
1607 'uint32_t' => :UINT32_T,
1608 'uint64_t' => :UINT64_T,
1609 'uint128_t' => :UINT128_T,
1610
1611 'float32_t' => :FLOAT32_T,
1612 'double64_t' => :DOUBLE64_T,
1613 'bool_t' => :BOOL_T,
1614 'char_t' => :CHAR_T,
1615 'schar_t' => :SCHAR_T,
1616 'uchar_t' => :UCHAR_T,
1617
1618 # unrecommened types
1619 'int' => :INT,
1620# 'intptr' => :INTPTR,
1621 'short' => :SHORT,
1622 'long' => :LONG,
1623
1624 # obsolete types
1625 'char' => :CHAR,
1626# 'int8' => :INT8,
1627# 'int16' => :INT16,
1628# 'int32' => :INT32,
1629# 'int64' => :INT64,
1630# 'int128' => :INT128,
1631# 'float' => :FLOAT,
1632# 'double' => :DOUBLE,
1633# 'bool' => :BOOL,
1634
1635 'enum' => :ENUM,
1636 'enum8' => :ENUM8,
1637 'enum16' => :ENUM16,
1638 'enum32' => :ENUM32,
1639 'enum64' => :ENUM64,
1640
1641 'true' => :TRUE,
1642 'false' => :FALSE,
1643
1644 'C_EXP' => :C_EXP,
1645
1646 'Descriptor' => :DESCRIPTOR,
1647
1648 # location information for TECSCDE
1649 '__location_information__' => :__LOCATION_INFORMATION__,
1650 '__cell__' => :__CELL__,
1651 '__join__' => :__JOIN__,
1652 }
1653
1654 # 指定子 '[]' 内
1655でのみ使用できるキーワード
1656 RESERVED2 = {
1657 # specifier
1658 'id' => :ID,
1659
1660 # signature
1661 'callback' => :CALLBACK,
1662 'context' => :CONTEXT,
1663 'deviate' => :DEVIATE,
1664
1665 # celltype
1666 'singleton' => :SINGLETON,
1667 'idx_is_id' => :IDX_IS_ID,
1668 'active' => :ACTIVE,
1669
1670 # port (entry)
1671 'inline' => :INLINE,
1672 'ref_desc' => :REF_DESC, # call も可
1673
1674 # port (call)
1675 'optional' => :OPTIONAL,
1676 'dynamic' => :DYNAMIC,
1677
1678 # port (call), attribute
1679 'omit' => :OMIT,
1680
1681 # attribute
1682 'choice' => :CHOICE,
1683
1684 # cell
1685 'allocator' => :ALLOCATOR,
1686 'prototype' => :PROTOTYPE,
1687 'restrict' => :RESTRICT,
1688
1689 # FuncType
1690 'oneway' => :ONEWAY,
1691
1692 # parameter (basic)
1693 'in' => :IN,
1694 'out' => :OUT,
1695 'inout' => :INOUT,
1696 'send' => :SEND,
1697 'receive' => :RECEIVE,
1698
1699 # parameter
1700 'size_is' => :SIZE_IS,
1701 'count_is' => :COUNT_IS,
1702 'string' => :STRING,
1703 'nullable' => :NULLABLE,
1704
1705 'through' => :THROUGH,
1706 'in_through' => :IN_THROUGH,
1707 'out_through' => :OUT_THROUGH,
1708 'to_through' => :TO_THROUGH,
1709
1710 'node' => :NODE,
1711 'linkunit' => :LINKUNIT ,
1712 'domain' => :DOMAIN,
1713 'class' => :CLASS,
1714 }
1715
1716 # 再帰的なパーサのためのスタック
1717 @@generator_nest = -1
1718 @@generator_stack = []
1719 @@current_locale = []
1720
1721 # import_C 中である
1722 @@import_C = false
1723
1724 # すべての構文解析が完了した
1725 @@b_end_all_parse = false
1726
1727 # tag なし struct
1728 @@no_struct_tag_num = 0
1729
1730 def self.parse( file_name, plugin = nil, b_reuse = false )
1731 # パーサインスタンスを生成(別パーサで読み込む)
1732 parser = Generator.new
1733
1734 # plugin から import されている場合の plugin 設定
1735 parser.set_plugin plugin
1736
1737 # reuse フラグを設定
1738 parser.set_reuse b_reuse
1739
1740 # cdl をパース
1741 parser.parse( [file_name] )
1742
1743 # 終期化 パーサスタックを戻す
1744 parser.finalize
1745 end
1746
1747 def finalize
1748
1749 # mikan Namespace.pop
1750 Namespace.pop
1751 Signature.pop
1752 Celltype.pop
1753 Cell.pop
1754 CompositeCelltype.pop
1755 end
1756
1757 def set_plugin( plugin )
1758 @plugin = plugin
1759 end
1760
1761 def self.get_plugin
1762 if @@generator_stack[@@generator_nest] then
1763 # tecsgen 引数の cdl が import される場合は nil
1764 return @@generator_stack[@@generator_nest].get_plugin
1765 else
1766 return nil
1767 end
1768 end
1769
1770 def get_plugin
1771 @plugin
1772 end
1773
1774 def set_reuse( b_reuse )
1775 @b_reuse = b_reuse
1776 end
1777
1778 def self.is_reuse?
1779 if @@generator_stack[@@generator_nest] then
1780 # tecsgen 引数の cdl が import される場合は nil
1781 return @@generator_stack[@@generator_nest].is_reuse?
1782 else
1783 return false
1784 end
1785 end
1786
1787 def is_reuse?
1788 @b_reuse
1789 end
1790
1791 def parse(files)
1792
1793 # mikan Namespace.push
1794 Namespace.push
1795 Signature.push
1796 Celltype.push
1797 Cell.push
1798 CompositeCelltype.push
1799
1800 @@generator_nest += 1
1801 @@generator_stack[@@generator_nest] = self
1802 @in_specifier = false
1803
1804 begin
1805
1806 @q = []
1807 b_in_comment = false
1808 b_in_string = false
1809
1810 # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
1811 TECS_LANG::set_kcode_binary
1812
1813 files.each {|file|
1814 lineno = 1
1815 begin
1816 string = ""
1817#2.0 IO.foreach(file) {|line|
1818 TECSIO.foreach(file) {|line|
1819 col = 1
1820# line.rstrip! 改行含む文字列を扱うようになったので、ここで空白を取り除けなくなった
1821
1822 until line.empty?
1823
1824 if b_in_comment
1825 case line
1826 # コメント終了
1827 when /\A\*\//
1828 b_in_comment = false
1829 when /\A./
1830 ;
1831 when /\s+/ # line.rstrip! を止めたため \n などの空白文字とまっちするルールが必
1832要になった
1833 ;
1834 end
1835 elsif b_in_string
1836 if line =~ /\A(?:[^"\\]|\\.)*"/
1837 string = "#{string}#{$&}"
1838 @q << [:STRING_LITERAL, Token.new(string, file, lineno, col)]
1839 b_in_string = false
1840 elsif line =~ /\A.*\\\n/ # 改行 \n は '.' にマッチしない
1841 string += $&
1842 elsif line =~ /\A.*\n/ # 改行 \n は '.' にマッチしない
1843 string += line
1844 # この位置では error メソッドは使えない (token 読出し前)
1845 puts "#{file}:#{lineno}:#{col}: error: string literal has newline without escape"
1846 @@n_error += 1
1847 end
1848 else
1849 case line
1850 # 空白、プリプロセスディレクティブ
1851 when /\A\s+/
1852 ;
1853 # 識別子
1854 when /\A[a-zA-Z_]\w*/
1855 word = $&
1856 @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)]
1857 # 16 進数定数
1858 when /\A0x[0-9A-Fa-f]+/
1859 @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)]
1860 # 8 進数定数
1861 when /\A0[0-7]+/
1862 @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)]
1863 # 浮動小数定数
1864 when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/
1865 @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)]
1866 # 整数定数
1867 when /\A\d+/
1868 @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)]
1869 # 文字定数
1870 when /\A'(?:[^'\\]|\\.)'/
1871 @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)]
1872 # 文字列
1873# "#include #include #include \"../systask/logtask.cfg\" 最後の " 忘れ)で無限ループ
1874# when /\A"(?:[^"\\]+|\\.)*"/
1875 when /\A"(?:[^"\\]|\\.)*"/ # これはうまく行くようだ
1876 @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)]
1877 # 文字列 (改行あり)
1878 when /\A"(?:[^"\\]|\\.)*\\\n$/
1879 string = $&
1880 b_in_string = true
1881 # 文字列 (改行あり, escape なし)
1882 when /\A("(?:[^"\\]|\e\.)*)\n$/
1883 string = $1 + "\\\n"
1884 b_in_string = true
1885 # この位置では error メソッドは使えない (token 読出し前) # mikan cdl_error ではない
1886 puts "#{file}:#{lineno}:#{col}: error: string literal has newline without escape"
1887 @@n_error += 1
1888 # 山括弧で囲まれた文字列
1889 # when /\A<[0-9A-Za-z_\. \/]+>/ # AB: angle bracke
1890 when /\A<(?:[^>\\]|\\.)*>/ # これはうまく行くようだ
1891 @q << [:AB_STRING_LITERAL, Token.new($&, file, lineno, col)]
1892 # 行コメント
1893 when /\A\/\/.*$/
1894 # 読み飛ばすだけ
1895 # コメント開始
1896 when /\A\/\*/
1897 b_in_comment = true
1898 # '>>', '<<' など
1899 when /\A>>/, /\A<</, /\A==/, /\A!=/, /\A\&\&/, /\A\|\|/
1900 @q << [$&, Token.new($&, file, lineno, col)]
1901 when /\A::/, /\A=>/, /\A<=/, /\A>=/
1902 @q << [$&, Token.new($&, file, lineno, col)]
1903 # '(', ')' など一文字の記号、または未知の記号
1904 when /\A./
1905 @q << [$&, Token.new($&, file, lineno, col)]
1906 else
1907 raise
1908 end
1909 end
1910
1911 line = $'
1912 col += $&.length
1913 end
1914
1915 lineno += 1
1916 }
1917
1918 rescue => evar
1919 Generator.error( "G1014 while open or reading \'$1\'" , file )
1920 if $debug then
1921 p puts( evar )
1922 pp $@
1923 end
1924 end
1925 }
1926
1927 # 終了の印
1928 @q << nil
1929
1930 @yydebug = true
1931 do_parse
1932
1933 ensure
1934 @@generator_nest -= 1
1935 TECS_LANG::reset_kcode
1936 end
1937
1938 end
1939
1940 def next_token
1941 token = @q.shift
1942
1943 if token then
1944 @@current_locale[@@generator_nest] = token[1].locale
1945
1946 if token[0] == :IDENTIFIER then
1947 # TYPE_NAME トークンへ置換え
1948 if Namespace.is_typename?( token[1].val ) then
1949 token[0] = :TYPE_NAME
1950 elsif @in_specifier && RESERVED2[ token[1].val.to_s ] then
1951 # 指定子キーワード( '[', ']' 内
1952でのみ有効)
1953 token[0] = RESERVED2[ token[1].val.to_s ]
1954 end
1955 end
1956
1957 if $debug then # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生)
1958 locale = @@current_locale[@@generator_nest]
1959 if token then
1960 print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" )
1961 else
1962 print( "#{locale[0]}: line #{locale[1]} : EOF\n" )
1963 end
1964 end
1965 else
1966 token = [ false, false ]
1967 end
1968
1969 token
1970 end
1971
1972 def on_error(t, v, vstack)
1973 # p t, token_to_str(t), vstack
1974 if token_to_str(t) == "$end" then
1975 Generator.error( "G1015 Unexpected EOF" )
1976 else
1977 Generator.error( "G1016 syntax error near \'$1\'" , v.val )
1978 end
1979 end
1980
1981 def self.current_locale
1982 @@current_locale[ @@generator_nest ]
1983 end
1984
1985 @@n_error = 0
1986 @@n_warning = 0
1987 @@n_info = 0
1988
1989 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でエラー発生は不適切)
1990 def self.error( msg, *arg )
1991 locale = nil
1992 self.error2( locale, msg, *arg )
1993 end
1994
1995 def self.error2( locale, msg, *arg )
1996 @@n_error += 1
1997
1998 msg = TECSMsg.get_error_message( msg )
1999 # $1, $2, ... を arg で置換
2000 count = 1
2001 arg.each{ |a|
2002 str = TECSIO.str_code_convert( msg, a.to_s )
2003 msg.sub!( /\$#{count}/, str )
2004 count += 1
2005 }
2006
2007 # import_C の中でのエラー?
2008 if @@import_C then
2009 C_parser.error( msg )
2010 else
2011
2012 # Node の記憶する 位置 (locale) を使用した場合、変更以前に比べ、
2013 # 問題発生箇所と異なる位置にエラーが出るため、構文解析中のエラー
2014 # は、解析中の位置を出力する.(new_XXX で owner が子要素のチェッ
2015 # クをすると owner の行番号が出てしまう点で、ずれが生じている)
2016
2017 if @@b_end_all_parse == false || locale == nil then
2018 locale = @@current_locale[ @@generator_nest ]
2019 end
2020 if locale then
2021 Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: error: #{msg}"
2022 else
2023 Console.puts "error: #{msg}"
2024 end
2025 end
2026 end
2027
2028 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でウォーニング発生は不適切)
2029 def self.warning( msg, *arg )
2030 locale = nil
2031 self.warning2( locale, msg, *arg )
2032 end
2033
2034 def self.warning2( locale, msg, *arg )
2035 @@n_warning += 1
2036
2037 msg = TECSMsg.get_warning_message( msg )
2038 # $1, $2, ... を arg で置換
2039 count = 1
2040 arg.each{ |a|
2041 str = TECSIO.str_code_convert( msg, a.to_s )
2042 msg.sub!( /\$#{count}/, str )
2043 count += 1
2044 }
2045
2046 # import_C の中でのウォーニング?
2047 if @@import_C then
2048 C_parser.warning( msg )
2049 else
2050 if @@b_end_all_parse == false || locale == nil then
2051 locale = @@current_locale[ @@generator_nest ]
2052 end
2053 if locale then
2054 Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: warning: #{msg}"
2055 else
2056 Console.puts "warning: #{msg}"
2057 end
2058 end
2059 end
2060
2061 # このメソッドは構文解析、意味解析からのみ呼出し可
2062 def self.info( msg, *arg )
2063 locale = nil
2064 self.info2( locale, msg, *arg )
2065 end
2066
2067 def self.info2( locale, msg, *arg )
2068 @@n_info += 1
2069
2070 msg = TECSMsg.get_info_message( msg )
2071 # $1, $2, ... を arg で置換
2072 count = 1
2073 arg.each{ |a|
2074 str = TECSIO.str_code_convert( msg, a.to_s )
2075 msg.sub!( /\$#{count}/, str )
2076 count += 1
2077 }
2078
2079 # import_C の中でのウォーニング?
2080 if @@import_C then
2081 C_parser.info( msg )
2082 else
2083 if @@b_end_all_parse == false || locale == nil then
2084 locale = @@current_locale[ @@generator_nest ]
2085 end
2086 if locale then
2087 Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: info: #{msg}"
2088 else
2089 Console.puts "info: #{msg}"
2090 end
2091 end
2092 end
2093
2094 def self.get_n_error
2095 @@n_error
2096 end
2097
2098 def self.get_n_warning
2099 @@n_warning
2100 end
2101
2102 def self.get_n_info
2103 @@n_info
2104 end
2105
2106 def self.get_nest
2107 @@generator_nest
2108 end
2109
2110 def self.parsing_C?
2111 @@import_C
2112 end
2113
2114 #=== '[' specifier 始め
2115 def set_in_specifier
2116 # p "set_in_specifier"
2117 @in_specifier = true
2118 end
2119
2120 #=== ']' specifier 終わり
2121 def unset_in_specifier
2122 # p "unset_in_specifier"
2123 @in_specifier = false
2124 end
2125
2126 # statement_specifier は構文解釈途中で参ç…
2127§ã—たいため
2128 @@statement_specifier_stack = []
2129 def self.add_statement_specifier( ss )
2130 if( @@statement_specifier_stack[ @@generator_nest ] == nil )then
2131 @@statement_specifier_stack[ @@generator_nest ] = [ ss ]
2132 else
2133 @@statement_specifier_stack[ @@generator_nest ] << ss
2134 end
2135 end
2136
2137
2138 def self.get_statement_specifier
2139 spec_list = @@statement_specifier_stack[ @@generator_nest ]
2140 @@statement_specifier_stack[ @@generator_nest ] = nil
2141 return spec_list
2142 end
2143
2144 #=== すべての構文解析が完了したことを報告
2145 def self.end_all_parse
2146 @@b_end_all_parse = true
2147 end
2148
2149---- footer
2150
2151
2152# ファイル => INCLUDE("header")のé…
2153åˆ—
2154Include = Hash.new {|hash, key| hash[key] = []}
2155
2156
2157class Token
2158
2159 attr_accessor :val, :file, :lineno, :col
2160
2161 def initialize(val, file, lineno, col)
2162 @val = val
2163 @file = file
2164 @lineno = lineno
2165 @col = col
2166
2167 end
2168
2169 def to_s
2170 @val.to_s
2171 end
2172
2173 def to_sym
2174 @val.to_sym
2175 end
2176
2177 def get_name
2178 @val
2179 end
2180
2181 def locale
2182 [@file, @lineno, @col]
2183 end
2184
2185 def eql?(other)
2186 if other.is_a? Symbol
2187 @val == other
2188 elsif other.is_a? Token
2189 @val == other.val
2190 elsif other.is_a? String
2191 @val.to_s == other
2192 else
2193 raise ArgumentError
2194 end
2195 end
2196
2197 alias == eql?
2198
2199 def show_tree( indent )
2200 indent.times { print " " }
2201 print "#{@val}\n"
2202 end
2203
2204end
2205
2206#= TECSIO
2207# Ruby2.0(1.9) 対応に伴い導å…
2208¥ã—たクラス
2209# SJIS 以外では、ASCII-8BIT としてå…
2210¥åŠ›ã™ã‚‹
2211class TECSIO
2212 def self.foreach(file) # ブロック引数 { |line| }
2213 pr = Proc.new # このメソッドのブロック引数を pr に代å…
2214¥
2215 if $b_no_kcode then
2216 msg = "E".encode $Ruby19_File_Encode
2217 if( $Ruby19_File_Encode == "Shift_JIS" )
2218
2219 # Shift JIS は、いったん Windows-31J として読み込ませ、Shift_JIS に変換させる.
2220 # コメント等に含まれる SJIS に不適切な文字コードは '?' または REPLACEMENT CHARACTER に変換される.
2221 # EUC や UTF-8 で記述された CDL が混在していても、Ruby 例外が発生することなく処理を進めることができる.
2222 # 文字コード指定が SJIS であって、文字列リテラルの中に、文字コードがSJIS 以外の非 ASCII が含まれている場合、
2223 # Ruby 1.8 の tecsgen では文字コード指定に影響なく処理されたものが、Ruby 1.9 以降では '?' に置き換わる可能性がある.
2224
2225 mode = "r:Windows-31J"
2226 else
2227 mode = "r:#{$Ruby19_File_Encode}"
2228 end
2229 # mode = "r"
2230 else
2231 msg = "E"
2232 mode = "r"
2233 end
2234
2235 f = File.open( file, mode )
2236 begin
2237 f.each{ |line|
2238 # dbgPrint line
2239 line = str_code_convert( msg, line )
2240 pr.call( line )
2241 }
2242 ensure
2243 f.close
2244 end
2245 end
2246
2247 #=== 文字コードが相違する場合一致させる
2248 # msg と str の文字コードが相違する場合、str を msg の文字コードに変換する
2249 # 変換不可の文字コードは '?' (utf-8 の場合 U+FFFD (REPLACEMENT CHARACTER )) に変換
2250 #
2251 # このメソッドは、エラーメッセージ出力でも使用されていることに注意.
2252 #
2253 #msg_enc::Encode | String
2254 def self.str_code_convert( msg, str )
2255 if $b_no_kcode == false then
2256 return str # Ruby V1.8 まで
2257 end
2258 if msg.encoding != str.encoding then
2259 option = { :invalid => :replace, :undef => :replace } # 例外を発生させず、'?' に変換する(utf-8 は 0xfffd)
2260 # return str.encode( msg.encoding, option )
2261 str = str.encode( "utf-8", option )
2262 return str.encode( msg.encoding, option )
2263 else
2264 return str
2265 end
2266 end
2267end
Note: See TracBrowser for help on using the repository browser.