c a s e EXPR̲SORT̲FUNCCALL:
目
tum" FUNCCALL " ; b r e a k ;
回 目
E X P R ̲ S O R T ̲ I N I T U S T :
四
tum"I N I T I A U Z E " ; b
刊誌;回 目
EXPR̲RETURN:
r
可e t u r n" RETURN " ; b r e a k ; d e f a u l
t:r e t u r n "OTHER E X P R E S S I O N " ;
関数 ge
tExpressionSort 一 式 の 種 類 を 求 め る 73400754
ー(吋)734 ∞ 355 r e t u m i + j
734 ∞ 3913 i = O
734 ∞ 4214 k < 100
734 ∞ 4515
I<=10
734005216 k=add
(i++,k ) 7340055 1 8 j = 1 734 ∞ 58 1 8 j
く=10
734 ∞ 6018 j + +
734 ∞ 64 1 9 d e c ( &
i)734 ∞ 6922 p r i n t f ( " i = % d k=%d¥n
ぺi , k )
734 ∞ 7124 r e t u m 0
2 . 2
オブジェクトexpression
の構文解析ARITHMETIC RETURN ARITHMETIC ARITHMETIC ARITHMETIC ARITHMETIC ARITHMETIC ARITHMETIC ARITHMETIC FUNCCALL FUNCCALL RETURN
C 言 語 を は じ め と す る 手 続 き 型 言 語 で は 、 変 数 に 対 し て 値 と 記 憶 領 域 が 割 り 当 て ら れ る 。 変 数 が 代 入 式 の 左 辺 に 現 れ る 場 合 は 変 数 の 記 憶 領 域 を 指 し 、 右 辺 に 現 れ る 場 合 は 変 数 の 値 を 指 す 。 そ れ ぞ れ 左 辺 値 (EXPR̲L̲VALUE)
,右 辺 値 (EXPR̲R̲ VALUE) と呼ぶ。 c 言 語 で は a++ の よ う に 値 と 記 憶 領 域 を 同 時 に 参 照 す る 式 も 存 在 し 、 こ れ を 左 右 辺 値(EXPR̲LR̲ VALUE) と呼ぶ。
EXPR L VALUE 左辺値 EXPR R VALUE 右辺値
EXPR PL V ALUE ポインタ付き左辺値 EXPR PR V ALUE ポインタ付き右辺値 EXPR P REF
アドレス参照EXPR LR VALUE 左辺値かつ右辺値 EXPR PLR VALUE ポインタ付き左右辺値
l e x p r e s s i o n
の属性l r t y p e
のマクロ定義]42 Sapidによるソフトウェア解析技法
*stmtは 基 本 文 を 表 すexpression 図
6.
式 の 構 造基本文である
e x p r e s s i o n
オブジェクト (図6
) を 対 象 と し て 構 文 を 解 析 す る 。e x p r
田s i o n (
式)がi d e n t i f i e r
と関連i d e n t ̲ r e f
を 持 つ 場 合 は 変 数 の み の 式 と な り 、
c o n s t a n t
と関連c o n s t ̲ r e f
を持っときは定 数 の み の 式 と な る 。 下 位 に 式 を 持 つ 場 合 は、関連expr̲op
を用いて演算子の存在 を調べ、再帰的に下位の式を構文解析す る。サ ン プ ル プ ロ グ ラ ム
3‑2
ー オ ブ ジ ェ ク トe x p r e s s i o n
の 構 文 解 析#函己亘面三証函瓦五〉
#include <Sapid/Sapid.h>
void olll!nModel(SpdDBld); S
P 4
0tjI(! get政pressionlnfo(SpdObjld); SpdObjld geUdenUnfo(SpdObjld));cn8r
・
geCOperator̲Info(SpdObjld);/ / 2章3.4参 照 Tt main(mt珂c,伽f岬[])S同DBld dbld; S凶ObjldArray expr̲array; SpdObjld exprーid; iot i; dbld = s凶OpenSDBO;
openModel(dbld);
expr̲array = spdGetObjldArray("expression", NULL, NULL);
for (i = 0; i < expr̲array.size; i++) { expr̲id=expr̲3rray.id[i];
/ / st匂at蛤eme町叩n凶B吐tと な るe回xpr目官s田洛剖l回o町叩nオプジエクトを選び情報を出力 E
臨s凶 白 仏 叫R副
d 嗣 l 旧 O 壇 橋 ; 恋 一 4
凶司'但U
宮r r r
ピ 巾 .s制凶
h ω E 慌 毘 坑 刈 ( 叩 削
;g朕酬edtE炉岱凶i叫onI曲{加回P戸r一̲̲iiのdd);オ} sodFreeObiIdArraYI eXDr aπav):同tum
( E X I T ̲ s u e e
ilSs :
工 一関数
g e t E x p r e s s i o n l n f o
式の情報を求める刊,idgetExpressionlnfo(SpdO均Ide叩Ud){
SpdObjld idenUd, cons北.̲id,expr l̲id, op̲id; SpdCursor骨expr由民・op田 町
/ / ↓ 融 行 の み の 式 の 場 合
if((idenUd= spdGetARelO均(expr)~九dent refγany"))!=SAPID̲NON̲ID) {geUdentJnfo{idenUd); retum;}
/ / ↓ 定 数 の み の 式 の 場 合
else if((consUd = spdGetAReIObj(expr̲id,"∞nsCref',"any"))!=SAPID̲NON̲ID)
第
3
章 プ ロ グ ラ ム の 構 造 を 解 析 す る 43 面 而 成 可 函t克 己
s函GetAttrValString(∞nsCid."value"));return;}1 1
↓式の持つ演算子を!帳番に出力op~白r=spdGetReIObjlnit(expr̲id. "expr̲opぺ"any"); wbile ((op~Jd = spdGetRelObj{op白r))!=SAPID̲NON̲ID)
printf(" up ¥"%s¥" ".geCOperator̲info(op̲id));
1 1
↓下位式を求めるexpr即 =spdGetRelObjlnit(expr̲id. "expr̲expr". "p‑ーid"); while ((expr l̲id = spdl白tRelO句(expr一四))!= SAPID̲NON̲ID) {
printf(ヘn¥t¥tSub‑expo(96d:%s ".expr̲id. spd
G e
tObjTexi(expr Ud));getExpressionlnfo(expr l̲id);}
関数 g e t ̲ i d e n t ̲ i n f o ‑ i d e n t i f i e r の情報を出力
void geUdenUnfo(SpdObjld idenUd)if(spdGetAttrValInt(idencid. "so目")== ID3ARlABLE) prinぜ''Var:%s". spdGetName(idenCid));
else if(spdGetAttrValInt(idenCid. "sort") == ID̲FUNCTION) pnnぜ'C'Func:%s". spdGetName(idenCid));
関数 g e t ̲ O p e r a t o r ̲ i n f o ‑i d e n t i f i e r の情報を出力
char・
geCOperator̲info(SpdO切Idoperator̲id){switch(spdGetAttrValInt(operator̲id. "sort")){
曲 目OP INC:
}
return "++";b陀ak;
回 目OPーDEC:
return ")";b同ak; 途 中 省 略 case τYFE DOTS:
return ".";break; default:
return "OTHEROPERATOR";
実行結果(一部)
4:ー(吋)(7340075) OP:"‑‑"Sub‑exp of 7340075:(吋)(7340074)OP:")" OP:"("
Sub‑exp of 7340074;吋(7340073)OP・町"
Sub‑expof 7340073:i (7340072)Var:i 11 :i=O (7340039) OP:"="
Sub‑exp of 734003虫0(7340038)Const:O Sub‑exp of 734003宮i(7340037) Var:i 14 :k< 100 (7340042) OP阿<"
Sub‑exp of 734004ZJOO (7340041) Const: 100 Sub‑exp of 7340042:k (7340040) Var:k 17 :i<= 1 0 (7340045) OP:"<="
Sub‑expof 7340045:10(7340044) Const: 10 Sub‑exp of 734004Si (7340043) Var:i 24 :k=add(i++.k) (7340052) OP:"="
Sub‑exp of 734005zadd(け+.k)(734005)) Sub‑exi> of 7340051:add (7340047) Func:add Sub‑exp of 7.340051:k (7340050) Var:k Sub‑exi> of 7340051:i++ (7340049) OP:"++
Sub‑exp of 7 34004g:i (7340048) Var:i Sub‑exp of 7340052:k (7340046) Var:k
4 4 S a p i d
によるソフトウエア解析技法ident4VAR)
/ k /↓7340052
↓7340049↓7340050
5 日 「 τ 寸
i d e n t ( V
‑AliL一 / k図
7 . k
ェadd(
i++,k J
の構文解析E クラス blαk
クラス
block
は、変数を宣言する宣言部と手続きを記述する実行部から構成 される。宣言部を持つブロックは、関数宣言の本体や、ブロック内でのみ有効 な局所変数を宣言するブロックなどである。ブロックは内部にサブ(下位)ブ ロックを持つ。最底辺のblock
オブジエクトはクラスexpression
オブジエクト と関連blk̲expr
を持つ。このようなblock
オブジェクトをbasicblock
と呼ぶ。i n t k= O ;
宣 言 部 実行部(サブブロック)f o r ( j = 1 ; j < 4 ; j + + ) { i n c ( k ) ;
p r i n t f ( i=%dj=%dk=%d¥n" , i j , , k ) ;
}図
8 .
ブロックの構造
↓
b a s i c block
式1・・・式nサブブロック
図
9.
第3章
プログラムの構造を解析する
45 blockを、中括弧 " { t ' と γ' で囲まれたブロック、制御構造による分岐ブロック、
分 岐 の な い 連 続 す る 文 の 列 の 3 種類に分ける。"{"と"}"で固まれた部分を
compound blockと呼ぶ。
if、
for、
whileと い っ た の 制 御 文 の 「 長 さ 」 は 、 キ ー ワ ー ド の 先 頭 か ら 分 岐 の 終 点 ま で で あ る 。 文 の 最 大 の 列 を
basicblockと呼 ぶ 。
basicblockの 前 後 に は 別 の
basicblockは 現 わ れ な い 。 分 岐 の 終 点 は 、 合 流 す る 次 の 文 の 直 前 で あ る 。 空 白 や 改 行 、 セ ミ コ ロ ン は 無 視 す る 。 分 岐 先 の 手 続き部もサブブロックである。
↓IF
ブロック
if(i(=10)
←分岐先のサブブロック
k=add(i++.k);↑分岐の終点
図10.BLOCK BASIC Ba8ic block BLOCK COMP Compound block BLOCK IF IF
文の
block BLOCK SWITCH SWITCH文の
block BLOCK FOR FOR文の
block BLOCK WHILE WHILE文の
block BLOCK DO DO文の
block BLOCK BRANCH分岐
blockBLOCK HIERACHICAL
他の
blockを含む
block [blockの属性
80rtのマクロ定義]
↓ifblock
始まり
14 if(i< = 10)
←
basic block始まり
15 k=add(i++,k);
←
basic block終わり
16 else ↓forblock始まり
↓compound block始まり
17 for( j =
1; j<= 1匂j++){←
basicblock始まり
18 dec(&i);←
basic block終わり
19 } ←
compound block終わり
↑forblock
終わり
&ifblock終わり
[サンプルプログラム
1のブロック構造(部分 ) J
46
S a p i d
によるソフトウェア解析技法3 . 1
クラスblock
の情報の取得program name :maln
↓file ded declaration sort:DECL FUNCDEF
↓ded decl プロック
↓blk blk declarator
sort:DECL FUNCDEF
↓decl oot optional̲decl sort:OPY FUNCDEF
↓func̲body block
sort:BLOCK COMP 図
1 1 .
b l o c k
オブジェクトの基本情報を取得す るプログラムを作成する。最上位のブロ ッ ク は 、 関 数 宣 言 の オ プ シ ョ ナ ル 部 分 (クラスo p t i o n a l d e c l
)と関連func̲body
を 持 つ 。 最 底 辺 の ブ ロ ッ ク は ク ラ ス白 戸 田
s i o n
のオブジェクトと関連blk3xpr
を持つ。関数の中で出現するブロック情 報を求める。#include <stdio.h>
#include <SapidfSapid.h>
サンプルプログラム
3‑3
ブロック情報を求めるvoid openModel(SpdDBld);
SpdObjI(J getBlocklnfo(SpdO巴dld); int main(int argc, char骨argv[]){
SpdObjldArray blk̲a町'ay; iot 1;
SpdDBld dbld; dbld = s凶OpenSDBO;
openMo(Jel(dbld);
︑ ︾
[ ) ︐
' A U
︑
B I‑
‑ a 冒L U J
L a
U町
N a
‑ L i K
1 D b
J・
2 P 1
N M W
J九
日明 間前
肱
H a一
m
r r H K K
可回 一 OLM
︑ 削 M M Fぱ J m 国' 即ぃ 出し い一 明 bi
一 日H
の此到M E巴 ゆ回
開 制
仰 V .
向町
‑
S01CTι
=
= I I サ ト 叫 田
町 w n 町 バ 川
a ‑ h
↑
r
町晶 一 凶 山
・R u e o n
‑
void get
I l
locl厄iif玩可証oo}ia‑WocUd){関数
g e t B l o c k I n f o
オブジエクトb l o c k
の基本情報を求めるint attr̲ val;
attr val
=
s凶GetA伽'ValInt(bl田k̲id,"sort");switch(attr̲ val){
回 目BLOCK BASIC:
{printf("BASIC Block")かeak;}
曲 目B1ρCK IF:
{printf("IF Block");break;}
田 町B1βCK FOR:
{printf("FOR Block");break;}
団 関BLOCKWHlLE:
{printf("WHILE Block");break;}
曲 目BLOCK COMP:
{printf("{} Block");br回k;}
回seBLOCK BRANCH:
{printf("BRANCH Block");b四ak;} defauIt:
printf("O唯h氾rBlock"); }
実行給果(部分)
{} 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);