source: azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/core/syntaxobj.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: 34.4 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2017 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
55# mikan ruby の symbol と文字列の使い分けがどうしてもうまくいかないことが時々
56あるので name.to_sym をå…
57¥ã‚Œã‚‹ã“とにした
58
59#== Node
60#
61# Node の直接の子クラス: C_EXP, Type, BaseVal, BDNode(ほとんどのものは BDNode の子クラス)
62# Node に (BDNodeにも) å…
63¥ã‚‰ãªã„もの: Token, Import, Import_C, Generate
64#
65# owner を持たないものが Node となる
66# エラーは、cdl_error を通じて報告する (意味解析が構文解析後に行われる場合には、行番号が正しく出力できる
67#
68
69class Node
70#@locale:: [@file, @lineno, @col]
71
72 def initialize
73 @locale = Generator.current_locale
74 end
75
76 #=== エラーを出力する
77 def cdl_error( message, *arg )
78 Generator.error2( @locale, message, *arg )
79 end
80
81 #=== エラーを出力する
82 #locale:: Array(locale info) : 構文解析中は無視される
83 def cdl_error2( locale, message, *arg )
84 Generator.error2( locale, message, *arg )
85 end
86
87 #=== エラーを出力する
88 #locale:: Array(locale info)
89 # 構文解析中 cdl_error2 では locale が無視されるため、別に locale を出力する
90 def cdl_error3( locale, message, *arg )
91 Generator.error( message, *arg )
92 Console.puts "check: #{locale[0]}: line #{locale[1]} for above error"
93 end
94
95 #=== ウォーニング出力する
96 def cdl_warning( message, *arg )
97 Generator.warning2( @locale, message, *arg )
98 end
99
100 #=== ウォーニング出力する
101 def cdl_warning2( locale, message, *arg )
102 Generator.warning2( locale, message, *arg )
103 end
104
105 #=== 情
106報を表示する
107 def cdl_info( message, *arg )
108 Generator.info2( @locale, message, *arg )
109 end
110
111 #=== 情
112報を表示する
113 def cdl_info2( locale, message, *arg )
114 Generator.info2( locale, message, *arg )
115 end
116
117 def get_locale
118 @locale
119 end
120
121 def set_locale locale
122 @locale = locale
123 end
124
125 def locale_str
126 "locale=( #{@locale[0]}, #{@locale[1]} )"
127 end
128end
129
130#== 双方向 Node (Bi Direction Node)
131#
132# Node の子クラス
133# owner Node から参ç…
134§ã•ã‚Œã¦ã„るもの (owner へのリンクも取り出せる)
135#
136# get_owner で得られるもの
137# FuncHead => Signature
138# Decl => Namespace(const), Typedef(typedef),
139# Celltype, CompositeCelltype(attr,var)
140# Struct(member), ParamDecl(parameter), FuncHead(funchead)
141# Signature, Celltype, CompositeCelltype, Typedef => Namespace
142#, Namespace => Namespace, Generator.class (root Namespace の場合)
143# Cell => Region, CompositeCelltype(in_composite)
144# Port => Celltype, Composite
145# Factory => Celltype
146# Join => Cell
147# CompositeCelltypeJoin => CompositeCelltype
148# Region => Region,
149# ParamDecl => ParamList
150# ParamList => FuncHead
151# Expression => Namespace
152# 大半のものは new_* メソッドで owner Node に伝達される
153# そのメソッドが呼び出されたときに owner Node が記録される
154# new_* がないもの:
155# Decl(parameter), ParamDecl, ParamList, FuncHead, Expression
156#
157# Expression は、owner Node となるものが多くあるが、改造が困難であるため
158# Expression が定義されたときの Namespace を owner Node とする
159# StructType は Type の一種なので owner を持たない
160#
161class BDNode < Node
162#@owner::Node
163#@NamespacePath:: NamespacePath
164#@Generator::
165#@import::Import :
166
167 def initialize
168 super
169 @owner = nil
170 @NamespacePath = nil
171 @import = Import.get_current
172
173 end
174
175 #=== owner を設定する
176 def set_owner owner
177 dbgPrint "set_owner: #{owner.class.name}\n"
178 @owner = owner
179 end
180
181 #=== owner を得る
182 # class の説明を参ç…
183§
184 def get_owner
185 if @owner == nil
186 raise "Node have no owner #{self.class.name} #{get_name}"
187 end
188 @owner
189 end
190end
191
192#== Namespace 名を持つ BDNode
193# Namespace(Region), Signature, Celltype, CompositeCelltype, Cell
194class NSBDNode < BDNode
195
196 def initialize
197 super
198 end
199
200 #=== 属する namespace を得る
201 # owner を namespace にたどり着くまで上にたどる
202 def get_namespace
203 if @owner.kind_of? Namespace
204 return @owner
205 elsif @owner != nil then
206 return @owner.get_namespace
207 else
208 # @owner == nil なら "::"
209 if @name != "::" then
210 raise "non-root namespace has no owner #{self.class.name}##{@name} #{self}"
211 end
212 return nil
213 end
214 end
215
216 def set_namespace_path
217 ns = get_namespace
218 if ns then
219 @NamespacePath = ns.get_namespace_path.append( get_name )
220 else
221 raise "get_namespace_path: no namespace found"
222 end
223 end
224
225 #=== NamespacePath を得る
226 def get_namespace_path
227 return @NamespacePath
228 end
229
230 def is_imported?
231 if @import then
232 return @import.is_imported?
233 else
234 return false # mikan: 仮 @import が nil になるケースが追求できていない
235 end
236 end
237end
238
239class NamedList
240# @names:: {} of items
241# @items:: [] of items : item の CLASS は get_name メソッドを持つこと get_name の戻り値は Symbol でなくてはならない
242# NamedList を clone_for_composite する場合は、item にもメソッドが必
243要
244# @type:: string エラーメッセージ
245
246 def initialize( item, type )
247 @names = {}
248 @items = []
249 @type = type
250 add_item( item )
251 end
252
253 #=== 要素を加える
254 # parse した時点で加えること(場所を記憶する)
255 def add_item( item )
256
257 if item then
258 assert_name item
259 name = item.get_name
260 prev = @names[name]
261 if prev then
262 Generator.error( "S2001 \'$1\' duplicate $2" , name, @type )
263 prev_locale = prev.get_locale
264 puts "previous: #{prev_locale[0]}: line #{prev_locale[1]} \'#{name}\' defined here"
265 return self
266 end
267
268 @names[name]=item
269 @items << item
270 end
271
272 return self
273 end
274
275 def change_item( item )
276 assert_name item
277 name = item.get_name
278
279 prev_one = @names[name]
280 @names[name]=item
281
282 @items = @items - [ prev_one ]
283 @items << item
284 end
285
286 def del_item( item )
287 assert_name item
288 name = item.get_name
289 @names.delete name
290
291 @items = @items - [ item ]
292 end
293
294 def get_item( name )
295 if ! name.kind_of? Symbol
296 print "get_item: '#{name}', items are below\n"
297 @names.each{ |nm,item|
298 p nm
299 }
300 raise "get_item: #{name}: not Symbol"
301 end
302 if name then
303 return @names[name.to_sym]
304 else
305 return nil
306 end
307 end
308
309 def get_items
310 return @items
311 end
312
313 #=== composite cell を clone した時に要素(JOIN) の clone する
314 #
315 # mikan このメソッドは Join に特化されているので NamedList から分離すべき
316 def clone_for_composite( ct_name, cell_name, locale )
317 cl = self.clone
318 cl.set_cloned( ct_name, cell_name, locale )
319 return cl
320 end
321
322 #=== clone された NamedList インスタンスの参ç…
323§ã™ã‚‹ã‚‚の(item)を clone
324 #
325 # mikan このメソッドは Join に特化されているので NamedList から分離すべき
326 def set_cloned( ct_name, cell_name, locale )
327 items = []
328 names = {}
329 @items.each { |i|
330 dbgPrint "NamedList clone #{ct_name}, #{cell_name}, #{i.get_name}\n"
331
332 cl = i.clone_for_composite( ct_name, cell_name, locale )
333 names[cl.get_name] = cl
334 items << cl
335 }
336 @items = items
337 @names = names
338 end
339
340 def assert_name item
341 if ! item.get_name.kind_of? Symbol
342 raise "Not symbol for NamedList item"
343 end
344 end
345
346 def show_tree( indent )
347 @items.each { |i|
348 i.show_tree( indent )
349 }
350 end
351
352end
353
354class Typedef < BDNode
355# @declarator:: Decl
356
357 def self.new_decl_list( type_spec_qual_list, decl_list )
358 decl_list.each { |decl|
359 Typedef.new( type_spec_qual_list, decl )
360 }
361 end
362
363 def initialize( type_spec_qual_list, decl )
364 super()
365 decl.set_type( type_spec_qual_list )
366 @declarator = decl
367 decl.set_owner self # Decl(Typedef)
368
369 Namespace.new_typedef( self )
370 end
371
372 def get_name
373 @declarator.get_name
374 end
375
376 def get_declarator
377 @declarator
378 end
379
380 def show_tree( indent )
381 indent.times { print " " }
382 puts "Typedef: #{locale_str}"
383 @declarator.show_tree( indent + 1 )
384 end
385end
386
387#== 関数頭部
388# signature に登録される関数
389class FuncHead <BDNode
390# @declarator:: Decl
391
392 def initialize( declarator, type, b_oneway )
393 super()
394 declarator.set_type( type )
395 @declarator = declarator
396 @declarator.set_owner self # Decl (FuncHead)
397
398 if @declarator.get_type.kind_of?( FuncType ) then
399 if b_oneway then
400 @declarator.get_type.set_oneway( b_oneway )
401 end
402 end
403 @declarator.get_type.check_struct_tag :FUNCHEAD
404
405 # check if return type is pointer
406 if declarator.get_type.kind_of? FuncType then
407 if declarator.get_type.get_type.get_original_type.kind_of?( PtrType ) &&
408 Signature.get_current.is_deviate? == false then
409 cdl_warning( "W3004 $1 pointer type has returned. specify deviate or stop return pointer" , @declarator.get_identifier )
410 end
411 end
412 end
413
414 def get_name
415 @declarator.get_name
416 end
417
418 def get_declarator
419 @declarator
420 end
421
422 def is_oneway?
423 if @declarator.is_function? then
424 return @declarator.get_type.is_oneway?
425 end
426 return false
427 end
428
429 def is_function?
430 @declarator.is_function?
431 end
432
433 #=== FuncHead# 関数の名前を返す
434 def get_name
435 return @declarator.get_name
436 end
437
438 #=== FuncHead# 関数の戻り値の型を返す
439 # types.rb に定義されている型
440 # 関数ヘッダの定義として不完å…
441¨ãªå ´åˆ nil を返す
442 def get_return_type
443 if is_function? then
444 return @declarator.get_type.get_type
445 end
446 end
447
448 #=== FuncHead# 関数の引数のリストを返す
449 # ParamList を返す
450 # 関数ヘッダの定義として不完å…
451¨ãªå ´åˆ nil を返す
452 def get_paramlist
453 if is_function? then
454 return @declarator.get_type.get_paramlist
455 end
456 end
457
458 def show_tree( indent )
459 indent.times { print " " }
460 puts "FuncHead: #{locale_str}"
461 @declarator.show_tree( indent + 1 )
462 end
463end
464
465#=== 宣言
466# @kind で示される各種の宣言
467class Decl < BDNode
468
469# @identifer:: String
470# @global_name:: String | nil : String(@kind=TYPEDEF||:CONSTANT), nil(@kind=その他)
471# set_kind にて設定される
472# @type:: ArrayType, FuncType, PtrType, IntType, StructType
473# VoidType, FloatType, DefinedType, BoolType
474# @initializer:: constant_expression, mikan { initlist }
475# @kind:: :VAR, :ATTRIBUTE, :PARAMETER, :TYPEDEF, :CONSTANT, :MEMBER, :FUNCHEAD(signatureの関数定義)
476# @b_referenced:: bool
477#
478# 以下は、@kind が :VAR, :ATTRIBUTE のときに有効
479# @rw:: bool # 古い文法では attr に指定可能だった(消すには generate の修正も必
480要)
481# @omit:: bool
482# @choice_list:: [String] attr 初期値の選択肢
483# 以下は、@kind が :VAR, :ATTRIBUTE, :MEMBER のときに有効
484# @size_is:: Expression or nil unless specified
485# 以下は、@kind が :MEMBER のときに有効
486# @count_is:: Expression or nil unless specified
487# attr, var の場合、count_is は指定できない
488# @string:: Expression, -1 (length not specified) or nil (not specified)
489#
490# mikan ParamDecl だけ別に設けたが、MemberDecl, AttrDecl なども分けるべきか(?)
491
492 def initialize( identifier )
493 super()
494 @identifier = identifier
495 @rw = false
496 @omit = false
497 @size_is = nil
498 @count_is = nil
499 @string = nil
500 @choice_list = nil
501 @b_referenced = false
502 end
503
504 def set_initializer( initializer )
505 @initializer = initializer
506 end
507
508 def get_initializer
509 @initializer
510 end
511
512 def is_function?
513 if @type.class == FuncType then
514 return true
515 else
516 return false
517 end
518 end
519
520 #== Decl の意味的誤りをチェックする
521 def check
522 # return nil if @type == nil
523
524 # 構造体タグチェック(ポインタ型から構造体が参ç…
525§ã•ã‚Œã¦ã„る場合は、タグの存在をチェックしない)
526 @type.check_struct_tag @kind
527
528 # 型のチェックを行う
529 res = @type.check
530 if res then
531 cdl_error( "S2002 $1: $2" , @identifier, res )
532 end
533
534 # 不要の初期化子をチェックする
535 if @initializer then
536 case @kind
537 when :PARAMETER, :TYPEDEF, :MEMBER, :FUNCHEAD
538 cdl_error( "S2003 $1: $2 cannot have initializer" , @identifier, @kind.to_s.downcase )
539 when :VAR, :ATTRIBUTE, :CONSTANT
540 # p @initializer ここでは代å…
541¥å¯èƒ½ã‹ã©ã†ã‹ã€ãƒã‚§ãƒƒã‚¯ã—ない
542 # :VAR, :ATTRIBUTE, :CONSTANT はそれぞれでチェックする
543 # return @type.check_init( @identifier, @initializer, @kind )
544 else
545 raise "unknown kind in Delc::check"
546 end
547 end
548
549 if( @type.kind_of? ArrayType ) && ( @type.get_subscript == nil ) && ( @omit == false ) then
550 if @kind == :ATTRIBUTE then
551 cdl_error( "S2004 $1: array subscript must be specified or omit" , @identifier )
552 elsif @kind == :VAR || @kind == :MEMBER then
553 cdl_error( "S2005 $1: array subscript must be specified" , @identifier )
554 end
555 end
556
557 return nil
558 end
559
560 #== ポインタレベルを得る
561 # 戻り値:
562 # 非ポインタ変数 = 0
563 # ポインタ変数 = 1
564 # 二重ポインタ変数 = 2
565 def get_ptr_level
566 level = 0
567 type = @type
568 while 1
569 if type.kind_of?( PtrType ) then
570 level += 1
571 type = type.get_referto
572# elsif type.kind_of?( ArrayType ) then # 添数なしé…
573åˆ—はポインタとみなす
574# if type.get_subscript == nil then
575# level += 1
576# type = type.get_type
577# else
578# break
579# end
580 # mikan ポインタの添数ありé…
581åˆ—のポインタレベルは0でよい?
582 elsif type.kind_of?( DefinedType ) then
583 type = type.get_type
584 # p "DefinedType: #{type} #{type.class}"
585 else
586 break
587 end
588 end
589 return level
590 end
591
592 def get_name
593 @identifier
594 end
595
596 def get_global_name
597 @global_name
598 end
599
600 def set_type( type )
601 unless @type then
602 @type = type
603 else
604 @type.set_type( type ) # 葉に設定
605 end
606 end
607
608 def get_type
609 @type
610 end
611
612 def get_identifier
613 @identifier
614 end
615
616 # STAGE: B
617 def set_kind( kind )
618 @kind = kind
619 case kind
620 when :TYPEDEF, :CONSTANT
621 if Namespace.get_global_name.to_s == "" then
622 @global_name = @identifier
623 else
624 @global_name = :"#{Namespace.get_global_name}_#{@identifier}"
625 end
626 else
627 @global_name = nil
628 end
629 end
630
631 def get_kind
632 @kind
633 end
634
635 def set_specifier_list( spec_list )
636 spec_list.each{ |spec|
637 case spec[0]
638 when :RW
639 @rw = true
640 when :OMIT
641 @omit = true
642 when :SIZE_IS
643 @size_is = spec[1]
644 when :COUNT_IS
645 @count_is = spec[1]
646 when :STRING
647 @string = spec[1]
648 when :CHOICE
649 @choice_list = spec[1]
650 else
651 raise "Unknown specifier #{spec[0]}"
652 end
653 }
654
655 if @size_is || @count_is || @string
656 @type.set_scs( @size_is, @count_is, @string, nil, false )
657 end
658 end
659
660 def is_rw?
661 @rw
662 end
663
664 def is_omit?
665 @omit
666 end
667
668 def get_size_is
669 @size_is
670 end
671
672 def get_count_is
673 @count_is
674 end
675
676 def get_string
677 @string
678 end
679
680 def get_choice_list
681 @choice_list
682 end
683
684 def referenced
685 @b_referenced = true
686 end
687
688 def is_referenced?
689 @b_referenced
690 end
691
692 def is_type?( type )
693 t = @type
694 while 1
695 if t.kind_of?( type ) then
696 return true
697 elsif t.kind_of?( DefinedType ) then
698 t = t.get_type
699 else
700 return false
701 end
702 end
703 end
704
705 def is_const?
706 type = @type
707 while 1
708 if type.is_const? then
709 return true
710 elsif type.kind_of?( DefinedType ) then
711 type = type.get_type
712 else
713 return false
714 end
715 end
716 end
717
718 #=== Decl# print_flowinfo
719 def print_flowinfo file
720 if @kind == :VAR then
721 file.write "#{@identifier} "
722 end
723 end
724
725 def show_tree( indent )
726 indent.times { print " " }
727 puts "Declarator: name: #{@identifier} kind: #{@kind} global_name: #{@global_name} #{locale_str}"
728 (indent+1).times { print " " }
729 puts "type:"
730 @type.show_tree( indent + 2 )
731 if @initializer then
732 (indent+1).times { print " " }
733 puts "initializer:"
734 @initializer.show_tree( indent + 2 )
735 else
736 (indent+1).times { print " " }
737 puts "initializer: no"
738 end
739 (indent+1).times { print " " }
740 puts "size_is: #{@size_is.to_s}, count_is: #{@count_is.to_s}, string: #{@string.to_s} referenced: #{@b_referenced} "
741
742 end
743
744end
745
746# 関数パラメータの宣言
747class ParamDecl < BDNode
748
749# @declarator:: Decl: Token, ArrayType, FuncType, PtrType
750# @direction:: :IN, :OUT, :INOUT, :SEND, :RECEIVE
751# @size:: Expr (size_is 引数)
752# @count:: Expr (count_is 引数)
753# @max:: Expr (size_is の第二引数)
754# @b_nullable:: Bool : nullable
755# @string:: Expr or -1(if size not specified) (string 引数)
756# @allocator:: Signature of allocator
757# @b_ref:: bool : size_is, count_is, string_is 引数として参ç…
758§ã•ã‚Œã¦ã„ã‚‹
759#
760# 1. 関数型でないこと
761# 2. 2次å…
762ƒä»¥ä¸Šã®é…
763åˆ—であって最も内
764側以外の添数があること
765# 3. in, out, ..., size_is, count_is, ... の重複指定がないこと
766# 4. ポインタレベルが適切なこと
767
768 def initialize( declarator, specifier, param_specifier )
769 super()
770 @declarator = declarator
771 @declarator.set_owner self # Decl (ParamDecl)
772 @declarator.set_type( specifier )
773 @param_specifier = param_specifier
774 @b_ref = false
775 @b_nullable = false
776
777 if @declarator.is_function? then # (1)
778 cdl_error( "S2006 \'$1\' function" , get_name )
779 return
780 end
781
782 res = @declarator.check
783 if res then # (2)
784 cdl_error( "S2007 \'$1\' $2" , get_name, res )
785 return
786 end
787
788 @param_specifier.each { |i|
789 case i[0] # (3)
790 when :IN, :OUT, :INOUT, :SEND, :RECEIVE
791 if @direction == nil then
792 @direction = i[0]
793 elsif i[0] == @direction then
794 cdl_warning( "W3001 $1: duplicate" , i[0] )
795 next
796 else
797 cdl_error( "S2008 $1: inconsitent with previous one" , i[0] )
798 next
799 end
800
801 case i[0]
802 when :SEND, :RECEIVE
803 @allocator = Namespace.find( i[1] ) #1
804 if ! @allocator.instance_of?( Signature ) then
805 cdl_error( "S2009 $1: not found or not signature" , i[1] )
806 next
807 elsif ! @allocator.is_allocator? then
808 # cdl_error( "S2010 $1: not allocator signature" , i[1] )
809 end
810 end
811
812 when :SIZE_IS
813 if @size then
814 cdl_error( "S2011 size_is duplicate" )
815 else
816 @size = i[1]
817 end
818 when :COUNT_IS
819 if @count then
820 cdl_error( "S2012 count_is duplicate" )
821 else
822 @count = i[1]
823 end
824 when :STRING
825 if @string then
826 cdl_error( "S2013 string duplicate" )
827 elsif i[1] then
828 @string = i[1]
829 else
830 @string = -1
831 end
832 when :MAX_IS
833 # max_is は、内
834部的なもの bnf.y.rb 参ç…
835§
836 # size_is で重複チェックされる
837 @max = i[1]
838 when :NULLABLE
839 # if ! @declarator.get_type.kind_of?( PtrType ) then
840 # cdl_error( "S2026 '$1' nullable specified for non-pointer type", @declarator.get_name )
841 # else
842 @b_nullable = true
843 # end
844 end
845
846 }
847
848 if @direction == nil then
849 cdl_error( "S2014 No direction specified. [in/out/inout/send/receive]" )
850 end
851
852 if ( @direction == :OUT || @direction == :INOUT ) && @string == -1 then
853 cdl_warning( "W3002 $1: this string might cause buffer over run" , get_name )
854 end
855
856 # mikan ポインタのé…
857åˆ—(添数有)のレベルが0
858 ptr_level = @declarator.get_ptr_level
859
860 # p "ptr_level: #{@declarator.get_identifier} #{ptr_level}"
861 # p @declarator
862
863 #---- set req_level, min_level & max_level ----#
864 if !(@size||@count||@string) then # (4)
865 req_level = 1
866 elsif (@size||@count)&&@string then
867 req_level = 2
868 else
869 req_level = 1
870 end
871
872 if @direction == :RECEIVE then
873 req_level += 1
874 end
875 min_level = req_level
876 max_level = req_level
877
878 # IN without pointer specifier can be non-pointer type
879 if @direction == :IN && !(@size||@count||@string) then
880 min_level = 0
881 end
882
883 # if size_is specified and pointer refer to struct, max_level increase
884 if @size then
885 type = @declarator.get_type.get_original_type
886 while type.kind_of? PtrType
887 type = type.get_referto.get_original_type
888 end
889 if type.kind_of? StructType then
890 max_level += 1
891 end
892 end
893 #---- end req_level & max_level ----#
894
895 # p "req_level: #{req_level} ptr_level: #{ptr_level}"
896 #if ptr_level < req_level && ! ( @direction == :IN && req_level == 1 && ptr_level == 0) then
897 if ptr_level < min_level then
898 cdl_error( "S2014 $1 need pointer or more pointer" , @declarator.get_identifier )
899 elsif ptr_level > max_level then
900 # note: 構文解析段階で実行のため get_current 可
901 if Signature.get_current == nil || Signature.get_current.is_deviate? == false then
902 cdl_warning( "W3003 $1 pointer level mismatch" , @declarator.get_identifier )
903 end
904 end
905
906 type = @declarator.get_type
907 while type.kind_of?( DefinedType )
908 type = type.get_original_type
909 end
910
911 if ptr_level > 0 then
912 # size_is, count_is, string をセット
913 if @direction == :RECEIVE && ptr_level > 1 then
914 type.get_type.set_scs( @size, @count, @string, @max, @b_nullable )
915 else
916 type.set_scs( @size, @count, @string, @max, @b_nullable )
917 end
918
919#p ptr_level
920#type.show_tree 1
921
922 # ポインタが指しているå…
923ˆã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’å¾—ã‚‹
924 i = 0
925 t2 = type
926 while i < ptr_level
927 t2 = t2.get_referto
928 while t2.kind_of?( DefinedType )
929 t2 = t2.get_original_type
930 end
931 i += 1
932 end
933
934# p @declarator.get_name
935# t2.show_tree 1
936# p t2.is_const?
937
938 # const 修飾が適切かチェック
939 if @direction == :IN then
940 if ! t2.is_const? then
941 cdl_error( "S2015 '$1' must be const for \'in\' parameter $2" , get_name, type.class )
942 end
943 else
944 if t2.is_const? then
945 cdl_error( "S2016 '$1' can not be const for $2 parameter" , get_name, @direction )
946 end
947 end
948 else
949 # 非ポインタタイプ
950 if @size != nil || @count != nil || @string != nil || @max != nil || @b_nullable then
951 type.set_scs( @size, @count, @string, @max, @b_nullable )
952 end
953 end
954
955# if ptr_level > 0 && @direction == :IN then
956# if type.is_const != :CONST
957# end
958
959 # p self
960
961 end
962
963 def check_struct_tag kind
964 @declarator.get_type.check_struct_tag :PARAMETER
965 end
966
967 def get_name
968 @declarator.get_name
969 end
970
971 def get_size
972 @size
973 end
974
975 def get_count
976 @count
977 end
978
979 def get_string
980 @string
981 end
982
983 def get_max
984 @max
985 end
986
987 def clear_max
988 # p "clear_max: #{@declarator.get_name} #{@max.to_s}"
989 @max = nil
990 @declarator.get_type.clear_max
991 end
992
993 def is_nullable?
994 @b_nullable
995 end
996
997 def get_type
998 @declarator.get_type
999 end
1000
1001 def get_direction
1002 @direction
1003 end
1004
1005 def get_declarator
1006 @declarator
1007 end
1008
1009 def get_allocator
1010 @allocator
1011 end
1012
1013 def referenced
1014 @b_ref = true
1015 end
1016
1017 def is_referenced?
1018 @b_ref
1019 end
1020
1021 #=== PPAllocator が必
1022要か
1023 # Transparent RPC の場合 in で size_is, count_is, string のいずれかが指定されている場合 oneway では PPAllocator が必
1024要
1025 # Transparent PC で oneway かどうかは、ここでは判断しないので別途判断が必
1026要
1027 # Opaque RPC の場合 size_is, count_is, string のいずれかが指定されている場合、PPAllocator が必
1028要
1029 def need_PPAllocator?( b_opaque = false )
1030 if ! b_opaque then
1031# if @direction == :IN && ( @size || @count || @string ) then
1032 if @direction == :IN && @declarator.get_type.get_original_type.kind_of?( PtrType ) then
1033 return true
1034 end
1035 else
1036 if (@direction == :IN || @direction == :OUT || @direction == :INOUT ) &&
1037 @declarator.get_type.get_original_type.kind_of?( PtrType ) then
1038 return true
1039 end
1040 end
1041 return false
1042 end
1043
1044 def show_tree( indent )
1045 indent.times { print " " }
1046 puts "ParamDecl: direction: #{@direction} #{locale_str}"
1047 @declarator.show_tree( indent + 1 )
1048 if @size then
1049 (indent+1).times { print " " }
1050 puts "size:"
1051 @size.show_tree( indent + 2 )
1052 end
1053 if @count then
1054 (indent+1).times { print " " }
1055 puts "count:"
1056 @count.show_tree( indent + 2 )
1057 end
1058 if @string then
1059 (indent+1).times { print " " }
1060 puts "string:"
1061 if @string == -1 then
1062 (indent+2).times { print " " }
1063 puts "size is not specified"
1064 else
1065 @string.show_tree( indent + 2 )
1066 end
1067 end
1068 if @allocator then
1069 (indent+1).times { print " " }
1070 puts "allocator: signature: #{@allocator.get_name}"
1071 end
1072 end
1073end
1074
1075# 関数パラメータリスト
1076class ParamList < BDNode
1077# @param_list:: NamedList : item: ParamDecl
1078
1079 def initialize( paramdecl )
1080 super()
1081 @param_list = NamedList.new( paramdecl, "parameter" )
1082 @param_list.get_items.each { |paramdecl|
1083 paramdecl.set_owner self # ParamDecl
1084 }
1085 end
1086
1087 def add_param( paramdecl )
1088 return if paramdecl == nil # 既にエラー
1089
1090 @param_list.add_item( paramdecl )
1091 paramdecl.set_owner self # ParamDecl
1092 end
1093
1094 def get_items
1095 @param_list.get_items
1096 end
1097
1098 #=== size_is, count_is, string の引数の式をチェック
1099 # 変数は前方参ç…
1100§å¯èƒ½ãªãŸã‚ã€é–¢æ•°é ­éƒ¨ã®æ§‹æ–‡è§£é‡ˆãŒçµ‚わった後にチェックする
1101 def check_param
1102 @param_list.get_items.each { |i|
1103 next if i == nil # i == nil : エラー時
1104
1105 if i.get_type.class == VoidType then
1106 # 単一の void 型はここにはこない
1107 cdl_error( "S2027 '$1' parameter cannot be void type", i.get_name )
1108 end
1109
1110 size = i.get_size # Expression
1111 if size then
1112 val = size.eval_const( @param_list )
1113 if val == nil then # 定数式でないか?
1114 # mikan 変数を含む式:単一の変数のみ OK
1115 type = size.get_type( @param_list )
1116 unless type.kind_of?( IntType ) then
1117 cdl_error( "S2017 size_is argument is not integer type" )
1118 else
1119 size.check_dir_for_param( @param_list, i.get_direction, "size_is" )
1120 end
1121 else
1122 if val != Integer( val ) then
1123 cdl_error( "S2018 \'$1\' size_is parameter not integer" , i.get_declarator.get_identifier )
1124 elsif val <= 0 then
1125 cdl_error( "S2019 \'$1\' size_is parameter negative or zero" , i.get_declarator.get_identifier )
1126 end
1127 end
1128 end
1129
1130 max = i.get_max
1131 if max then
1132 val2 = max.eval_const( @param_list )
1133 if val2 == nil then
1134 cdl_error( "S2028 '$1' max (size_is 2nd parameter) not constant", i.get_name )
1135 elsif val2 != Integer( val2 ) || val2 <= 0 then
1136 cdl_error( "S2029 '$1' max (size_is 2nd parameter) negative or zero, or not integer", i.get_name )
1137 end
1138 end
1139
1140 if val != nil && val2 != nil then
1141 if val < val2 then
1142 cdl_warning( "W3005 '$1' size_is always lower than max. max is ignored", i.get_name )
1143 i.clear_max
1144 else
1145 cdl_error( "S2030 '$1' both size_is and max are const. size_is larger than max", i.get_name )
1146 end
1147 end
1148
1149 count = i.get_count # Expression
1150 if count then
1151 val = count.eval_const( @param_list )
1152 if val == nil then # 定数式でないか?
1153 # mikan 変数を含む式:単一の変数のみ OK
1154 type = count.get_type( @param_list )
1155 unless type.kind_of?( IntType ) then
1156 cdl_error( "S2020 count_is argument is not integer type" )
1157 else
1158 count.check_dir_for_param( @param_list, i.get_direction, "count_is" )
1159 end
1160 else
1161 if val != Integer( val ) then
1162 cdl_error( "S2021 \'$1\' count_is parameter not integer" , i.get_declarator.get_identifier )
1163 elsif val <= 0 then
1164 cdl_error( "S2022 \'$1\' count_is parameter negative or zero" , i.get_declarator.get_identifier )
1165 end
1166 end
1167 end
1168
1169 string = i.get_string # Expression
1170 if string != -1 && string then
1171 val = string.eval_const( @param_list )
1172 if val == nil then # 定数式でないか?
1173 # mikan 変数を含む式:単一の変数のみ OK
1174 type = string.get_type( @param_list )
1175 unless type.kind_of?( IntType ) then
1176 cdl_error( "S2023 string argument is not integer type" )
1177 else
1178 string.check_dir_for_param( @param_list, i.get_direction, "string" )
1179 end
1180 else
1181 if val != Integer( val ) then
1182 cdl_error( "S2024 \'$1\' string parameter not integer" , i.get_declarator.get_identifier )
1183 elsif val <= 0 then
1184 cdl_error( "S2025 \'$1\' string parameter negative or zero" , i.get_declarator.get_identifier )
1185 end
1186 end
1187 end
1188 }
1189 end
1190
1191 def check_struct_tag kind
1192 @param_list.get_items.each{ |p|
1193 p.check_struct_tag kind
1194 }
1195 end
1196
1197 #=== Push Pop Allocator が必
1198要か?
1199 # Transparent RPC の場合 (oneway かつ) in のé…
1200åˆ—(size_is, count_is, string のいずれかで修飾)がある
1201 def need_PPAllocator?( b_opaque = false )
1202 @param_list.get_items.each { |i|
1203 if i.need_PPAllocator?( b_opaque ) then
1204 return true
1205 end
1206 }
1207 false
1208 end
1209
1210 def find( name )
1211 @param_list.get_item( name )
1212 end
1213
1214 #== ParamList# 文字列化
1215 #b_name:: Bool: パラメータ名を含める
1216 def to_str( b_name )
1217 str = "("
1218 delim = ""
1219 @param_list.get_items.each{ |paramdecl|
1220 decl = paramdecl.get_declarator
1221 str += delim + decl.get_type
1222 if b_name then
1223 str += " " + decl.get_name
1224 end
1225 str += decl.get_type_post
1226 delim = ", "
1227 }
1228 str += ")"
1229 end
1230
1231 def show_tree( indent )
1232 indent.times { print " " }
1233 puts "ParamList: #{locale_str}"
1234 @param_list.show_tree( indent + 1 )
1235 end
1236end
1237
1238#== CDL の文字列リテラルを扱うためのクラス
1239# CDL の文字列リテラルそのものではない
1240class CDLString
1241 # エスケープ文字を変換
1242 def self.escape str
1243 str = str.dup
1244 str.gsub!( /\\a/, "\x07" )
1245 str.gsub!( /\\b/, "\x08" )
1246 str.gsub!( /\\f/, "\x0c" )
1247 str.gsub!( /\\n/, "\x0a" )
1248 str.gsub!( /\\r/, "\x0d" )
1249 str.gsub!( /\\t/, "\x08" )
1250 str.gsub!( /\\v/, "\x0b" )
1251 str.gsub!( /(\\[Xx][0-9A-Fa-f]{1,2})/, '{printf \"\\1\"}' )
1252 str.gsub!( /(\\[0-7]{1,3})/, '{printf \"\\1\"}' )
1253 str.gsub!( /\\(.)/, "\\1" ) # mikan 未定義のエスケープシーケンスを変換してしまう (gcc V3.4.4 では警告が出される)
1254 return str
1255 end
1256
1257 #=== CDLString#前後の " を取り除く
1258 def self.remove_dquote str
1259 s = str.sub( /\A"/, "" )
1260 s.sub!( /"\z/, "" )
1261 return s
1262 end
1263end
1264
1265#== CDL の初期化子を扱うためのクラス
1266# CDL の初期化子そのものではない
1267class CDLInitializer
1268 #=== 初期化子のクローン
1269 # 初期化子は Expression, C_EXP, Array のいずれか
1270 def self.clone_for_composite( rhs, ct_name, cell_name, locale )
1271 if rhs.instance_of? C_EXP then
1272 # C_EXP の clone を作るとともに置換
1273 rhs = rhs.clone_for_composite( ct_name, cell_name, locale )
1274 elsif rhs.instance_of? Expression then
1275 rhs = rhs.clone_for_composite
1276 elsif rhs.instance_of? Array then
1277 rhs = clone_for_compoiste_array( rhs, ct_name, cell_name, locale )
1278 else
1279 raise "unknown rhs for join"
1280 end
1281 return rhs
1282 end
1283
1284 #=== 初期化子(é…
1285åˆ—)のクローン
1286 # 要素は clone_for_composite を持つものだけ
1287 def self.clone_for_compoiste_array( array, ct_name, cell_name, locale )
1288 # "compoiste.identifier" の場合 (CDL としては誤り)
1289 if array[0] == :COMPOSITE then
1290 return array.clone
1291 end
1292
1293 new_array = array.map{ |m|
1294 clone_for_composite( m, ct_name, cell_name, locale )
1295 }
1296 return new_array
1297 end
1298end
Note: See TracBrowser for help on using the repository browser.