• 検索結果がありません。

{printf("BRANCH Block");bak;} defauIt: 

printf("OhrBlock");  } 

実行給果(部分)

{} Blockー>BlocklD 6291457  BASICBlock‑> BlocklD 6291458  BASICBlock‑> BlocklD 6291459

ベ D

BASIC Block‑> BlocklD 6291460

ベ 9

{} Block司>BI:klD 6291461  ‑‑(4)  FORBlock‑> BlocklD 6291462 ‑(3)  IFBloc主ー>Block lD 6291463  {j)  BASICBlock‑> BlocklD 6291464  {} Block ‑> Block lD 6291465 

ifblock 6291463 (l)  if(i<=10) 

k=add(i++k);basic block 6291459 (2)  else for b10ck 6291462 (3) 

3 プログラムの構造を解析する 47 

forU= 1; j<= 10; j++){compound block 6291461 (4) 

basic block 6291460 (5)  dec(&i); 

3 . 2   ブロック構造の解析

48  Sapidによるソフトウェア解析技法

サンプルプログラム

3‑4

ーブロック構造の解析

アルゴリズム:

1.各関数宣言オブジェクト(optionaldecl)を順番に選以以下の手続きを繰り返す 2.その関数宣言のトップブロックを求める

3 .

そのブロックと直接関連を持つブロックの

I d

を取得

4 . 3 .

で求めたブロックの情報を出力

#incIude <stdio.h> 

#incIude <Sapid/Sapid.h> 

LJu Ju

︐/ 

I f  

M

h }  

O川悦d

UHH'1dU

H H

p b I

b . 

S

bO0

h u

D副創刊い

d m

J円・叩閣由

m m

四灯油尚

PL MM m

ιu EU Ru au

X

LY tt tt  

mv mV

r

mv nE JU JU AU AQ  

OμμHH

LU Lu

L υ LU l 

nu nv nu nu   u M

uv qu eu qu cu  

?t mMint町 , 伽 骨 岬 日 〕 SpdObjld  top̲block̲id, bllUd;  int  i; 

SpdObjldArray opCaπay; 

S凶Cursorlk̲csr; SpdDBld  dbld;  dbld = spdOpenSDBO; 

openModel(dbld); 

1.各関数宣言オブジヱクト (optionaldecI)を同薦書に選び以下の手続きを繰り返す opCaπ~r ~p~GetO均ldArray("optionaldecI",NULL, NULL); 

for (i = 0; i < opcarray.size; i++) 

if(spdGetAttfValInt(opt̲array[i]"sort")==OPT ]UNCDEF){  getFuncName(opCarray.id[i]); 

/ / 2

その関数宣言のトップブロックを求める

top̲block̲id = spdGetARelObj(opCarray.id[i]"func̲bodyγany");  μ 3そ の ブ ロ ッ ク と 直f鵬 を 持 つ ブ ロ ッ

p

Idを 開 lilkr=spdGetRel0lrii:t

( t o " . J > 1

k̲id"blk̲blk", "p‑id");  whITe ((blk~id = spdGetRelObjt csr))!=SAPID̲NON̲ID) { 

ぶ i i d 宇・都民需品摘。説立田仇凶,

spdFreeCursor(blk一 回r);

:

主 f : 臨す必蹴叫);

関数

getBlockTrace オブジェクトblock

の基本情報を求める

void getBlockTrace(SpdObjld block̲id){ 

SpdObjld  blk̲id;  ghcumf

龍一国

r'

getBlockInfo(block̲id);  prinげ("%d "block̲id);  /  ブロックを下イ方向へたどる

blk3sr = spdGetRelObjlnit(blocLid"blk̲blk""p‑id");  while((blk"::id = spdGetRelObj(blk3Sr))!=SAPID:"'NON̲ID){ 

pnn(">"); getBlockTrace(blk̲id);  spdFreeCursor(blk一 回r);

3 プログラムの構造を解析する 49 

実行結果

(main

関数のみ)

Funcation main 

rop‑> BASIC Block 6291467 

rop‑> WHILE Block 6291466‑>{} Block 6291465 ‑>BASIC Block 6291464 ‑>IF Block 6291463 

‑>FOR Block 6291462 ‑>{} Block 6291461‑>BASIC Block 6291460‑>BASIC Block 6291459  Trop‑> BASIC Block 6291458 

while block 6291466compoundblock 6291465  while (k< 100)  {←basic blocK 6291464 

ifblock 6291463  if(i<=10) 

basic block 6291459k=add(i++k);  else 

for block 6291462 compound block 6291461  forU= 1; j<= 10; j++){basic block 6291460 

dec(&i); 

printf("i=%d k=%d¥n"ik); 

[実行結果のブロック構造]

W  変 数 の ト レ ー ス と 制 御 構 造

プログラムの検証やデバッグプロセスでは、変数の値が、制御構造中でどの ように変化するかを分析する。条件式や繰り返し文と、制御ブロックとの関係 も分析する。

クラス

e x p r e s s i o n

b l o c k

のオブジヱクトを用いて変数の値のトレースを 行うプログラムを作成する。ターゲットとする変数を含む文の所属するブロッ クの種類や構造を調べる。変数の値が変化させられる可能性についても検査す る(左辺値、右左辺値など)。

解析対象プログラム

3 ‑ 2

intmainO{ 

int i=Oj, k= 0;  while (k< 100){ 

{int k;  if(i<= 10) 

k=i++ + k;  else { 

i10;  k=k‑10; 

50  Sapidによるソフトウェア解析技法

K=i; 

i>r(j=1; j<= 1 0; j++){  k=k+j;  k; 

printf("i=%d k=%d¥n"ik);  retum 0; 

4 . 1  

変数のトレースとブロック情報(1)

ターゲット変数をk とし、当該変数が左辺値として出現する式を順番に取得 し、 どの種類のブロックに属するかを調べる。 式が制御ブロックの条件部等に 属していれば、制御ブロックと直接関連をもっ。

サンプルプログラム

3

5

変数のトレースとブロック情報(1 

)  アルゴリズム:

1 .  

id

intiferオブジェクトの中で変数のものを選び以下の手続きを繰り返す 2.  その変数を左辺値として含む文のオブジェクトIdを取得

3 .  

ブロックと直接関連を持つ式(文statement)のIdを取得getStatement 4.  当該ブロックの情報を出力

#面面瓦de<stdio:h:;: 

#include <SapidjSapid.h> 

void  OlltmModel(SpdDBld);  SpdObjId getBlockIrifo(SpdO巴~Id);

SpdOIdgetStatement(SpdOlijld); irit  spd..lleUine(SpdObjld); 

??t Emmnma副州inn1

ο

((

(

(inn2

s凶DBId dbId SpdObjldArray id̲array;  SjxlObjld  ei'lJr̲id

, 

siatemenUd; 

SpdCursor  *ident.田町

mt  IJ;  dbld = spdOpenSDBO; 

openMooel(dbld); 

id̲array = spdGetObjldArray("identer"

NULL

, 

NULL); 

j j 1. ideintiferオブジエクトの中で変数のものを選び以下の手続きを繰り返す for (i  =匂i< id̲array.size; i++ ) 

if( spdGetAt廿.ValIrit(id̲array.id[i]"sort")==ID̲VARIABLE){ 

printf("¥nη%d‑objectof identifier¥"%s¥"¥n"j+ lspdGetName(id̲array.id[i]));  2.その変数を左辺値として含む文のオブジヱクトIdを耳切尋

identr= spdGetRelObjlnit(id̲aπay.id[i]"idencrefγany"); 

while((expr̲ld = spdGetRelObj(hlent一 回r))!=SAPID̲NON̲ID) if (spdGetAttrValInt(expcid"lrtype") ==EXPR̲L̲ VALUE){ 

//3.当該の文と直俊関連を持つブロックを耐尋 statemenUd = getStatement (expr̲id); 

3

プログラムの構造を解析する 51 

//4. 当 ü~'ブロックの情報を出力

getBlockInfo(spdGetARelObj(statement̲id"blk̲expr""any")); 

prin("¥n");

spdFreeCu

問 。

r(idenCr); spdFreeObjldArray(id̲array);  spdCloseSDB(dbld);  retum (EXIT̲SUCCESS); 

関数

getStatement 一式の情報を求める

SpdOIdgetStatement(SpdOIdepUd){

SpdObjld  expr̲tmp̲id;  SpdCursor  *exprr; SpdRel  expi̲rel; 

expr̲r= spdGetRelObjlnit(expr̲i札、xpr̲expr""cid"); wliile((expr"':tmp̲id = spdGetRelObj(expr̲csr))!=SAPID̲NON̲ID){ 

if((s凶pd.dωeOb.j(exPr̲tmp̲id"blf<

e

xp

fii

ex勾pr~~叫'el= spdGωetAReel(expr

凶 一

ι"blkepr"nly""')

pnn("¥¥nexpr戸 % 治sa剖1#%制d

、 て

sp.dcCωωb.jText(exprtmp̲id) spdllecline(expr̲tmp̲id));  spdFreeCursor( expr ̲csr); 

}return expr‑tmpJd

, 

else 

getStatement(expr̲tmp̲id); 

実行結果(変数

k

の結果のみ)

Tbe l‑th object of identifier "k" 

expr = k=k+j at # 17 BASIC Block  expr = k = i at # 15 BASIC Block  The 2‑th object 0identifier"k" 

pr=k=k‑10at#7 BASICBlock <ー(A)basblock内の式の左辺値での出現 expr = k=i++ + k at # 10 BASIC Block <ー(B)

while (k< 100){  if(i<= 10) 

(B) basic block内の式の左辺値での出現 k=i++ + k; 

else{ 

1‑10; 

(A) basic block内の式の左辺値での出現 k=k‑10; 

[変数 kの出現とブロック構造 IThe2‑th object of identifier "k") 

52  Sapidによるソフトウェア解析技法 4.2  変数のトレースとブロック情報(2)

あ る 文 を 含 む 最 上 位 の ブ ロ ッ ク を 求 め る 。 タ ー ゲ ッ 卜 の 変 数 ( ク ラ ス

IBASIC I

K

2

日 孟 + 団 コ

k

14.

identifier) が属する式と関連blk̲expr

を持つ最内ブロックを、外側へたどり、

得られるブロック情報を取得する。

3 . 2

の関数getBlockTraceの解析方向を上向 きに変える (p‑id

c‑id)

サンプルプログラム

3‑6

変数のトレースとブロック情報(

2 ) アルゴリズム:

l  変数を左辺値として含む文のオブジェクトIdを取得

2 .  

1.で求めた文と直接関連を持つブロックを取得

3.  2.で求めた文のブロック情報を最内から順番に出力get

B l

ockTrace、get

B l

ocklnfo 自説副示扇面五〉

#include <SapidfSapid.h> 

void  openModel(SpdDBld);  SpdObjld getStatement(SpdOId); SpdObjld getBlocklnfo(SpdObjld);  SpdOb]Id getBlockTrace(SpdObjld);  int  spd.....geUine(SpdOlljld);  int main(int argc, char *argv[]) 

SpdObjldArray id̲array; 

SPdOb]Id  expr̲id, sfatemenUd, block̲id;  SpdCursor 

ident田 町

int  i;  SpdDBld  dbld;  dbld = spdOpenSDBO; 

openModel(dbld); 

id̲array = spdGetOldArray("identifier"NULL, NULL); 

for (i = 0; i id̲array.size; i++) 

if(s凶Ge凶町ValInt(id_町r!,y.id[})九。六,:'L=~~!?~V品lAB日){

p巾 げt"¥n¥nThe%d‑th object (VAR ¥"%s¥")"i+ 1spdGetName(id̲array.id[i])); 

f f  

1.変数を左辺値として含む文のオブジェクトIdを耐専

identr= sp~GetR:elOl?jI!'lt,Ci(:I~array.id[~lパdent refany"); while((expr̲id = spdGetRelObj(iden

t . . : 白

r))!=SAPID̲NON̲ID) if (spdGetAttrVallnt(expr̲id

"lrtype") ==EXPR̲L̲ VALUE){ 

f  f 

2.  1.で求めた文と直接関連を持つブロックを取得 statementid= getExpression(expr̲id); 

if((blk̲id=spdGetARelO(statemen

t . . :

id

"blk̲expr"

、 ,

id"))!=SAPID̲NON̲ID)

f f  

3. 2.で求めた文のプロック情報を最内から順番に取得

getBlockTrace(block̲id);  return (EXIT̲SUCCESS); 

3 プログラムの構造を解析する 53 

関数 g e t B l o c k T r a c e オブジェクト b l o c k の 基 本 情 報 を 求 め る

void getBlockT回 目SpdObjldblock̲id){  pdObjld  blk~id;

int  attr̲ val;  SpdCursor  lk田 町

getBlockInf口(block̲id);printf(" %d "block̲id); 

L(ZtiA& 椅

1 Z 6 a ‑ i"blk̲b町 トid"

while((blk

‑=id= spdGetRelO~削~(blkk csr))!=SAPID

NON̲ID){

prin(">"); getBlockTrace(blk̲id);  spdFrCursor(blk一 回r);

実行結果(部分)

甘 児 島thobject of identifier "k" 

expr= k~k-10at 町ベA)

BASIC Block 6291457>{}Block 6291458>IFBlock6291459‑>{} Block 6291460

WHILE  Block 6291461‑>{} Block 6291469 

expr = k=i++ + k at 1 0 

BASIC Block 6291456

IF Block 6291459 ‑>{} Block 6291460‑>WHlLE Block 6291461 ‑>{}  Block 6291469‑(B) 

変数 k の出現とブロック構造('T he2 ‑ t h  o b j e c t  o f  i d e n t i f i e r  " k " )  

int mainO{' compound block 6291469  int i=Oj, k=O; 

while block 6291461 

while (k<1 OO){compoundblock 6291460 

ifblock 6291459  if(i<= 10) 

basic block 6291456  k=i++ + k;  +‑(B) 

else{compoundblock 6291458 

basic block 6291457   α1

k‑10;

A)

ドキュメント内 Sapidによるソフトウェア解析技法 (ページ 53-59)