【 事例演習 6】  数式インタプリタ 解 説...

24
事事事事 6 事事事事事事事事 解 解 解 解 “解解解解解解解解解解解解解解 “解解解解解解解解解解解解解解

Upload: nasnan

Post on 18-Mar-2016

50 views

Category:

Documents


3 download

DESCRIPTION

【 事例演習 6】  数式インタプリタ 解 説     “インタプリタの基本的な仕組み ”.  特殊問題向き言語. 高水準言語. コンパイラ. インタプリタ. 構文解析&    コード生成. 構文解析&  コード生成.    疑似コード     ( P-Code ).    疑似コード ( P-Code または Byte-Code ). コードの最適化  機械語コード生成. 仮想マシン P-Code | Byte-Code の評価 & 実行. インタプリタとコンパイラの相違. アセンブラ言語.   アセンブラ  機械語コードへ - PowerPoint PPT Presentation

TRANSCRIPT

  【事例演習 6 】  数式インタプリタ

     解 説解 説      

    “インタプリタの基本的な仕組み    “インタプリタの基本的な仕組み””

    機械語  (Intel 用 ,Motorola 用 ,PowerPC 用…)

アセンブラ言語

  ファームウェア方式機械語の命令をマクロ命令と考え, CPU 内に格納されたさらに基本的なマイクロコードプログラムによって評価・実行する方式

    ハードウェア方式機械語の命令を CPUの論理回路によって解釈・実行する方式

コンパイラ

高水準言語

 コードの最適化 機械語コード生成

   疑似コード    ( P-Code )

 構文解析&  コード生成

インタプリタとコンパイラの相違

実行 実行

  アセンブラ  機械語コードへ 直接変換

    インタプリタ

 特殊問題向き言語

  仮想マシン P-Code | Byte-Code の評価 &実行

   構文解析&   コード生成

   疑似コード( P-Code ま た は Byte-Code )

 機能1:コンパイル(構文解析と疑似コードの生成) 入力された文や式が構文規則(シンタックス)にしたがっているかチェックし, 疑似コードを生成する

        疑似コード P(Pseudo)-Code   アプリケーション プログラムを疑似的なコードや基本的な関数の呼出しに形式に変換したもの・ 

疑似コード生成

疑似コードの評価・実行

  機能2:仮想マシン (Virtual Machine)   疑似コードや基本的な関数呼出しをプログラム的に評価・実行する

インタプリタ言語(例えば BASIC,Java 等)で組んだ     アプリケーション・プログラム

C コンパイラ  ( Intel用)

C コンパイラ ( Motorola用)

C コンパイラ ( PowerPC用)

仮想マシンの機能を記述した Cプログラムを翻訳した機械語コード            (Intel 用 ,Motorola 用 ,PowerPC 用…)

実行

この範囲は CPU に依存しない

インタプリタ

    サーバ

     Web ブラウザ   Java 仮想マシン

( Virtual   Machine)

Java  コンパイラ

コンパイルが生成したByte_code( 疑似コード)

Java プログラム Byte-code (疑似コード)

Java における Byte-code の転送と評価・実行

インタプリタの基本的な機能構造図

  インタプリタ    本体

 

 構文規則にしたがっているか 文 / 式をチェックし, 同時に疑似コードを生成する

  get_syllable 一語の切出し

  regist_variable  変数の登録

   Parser

構文規則にしたがっているか解析し疑似コードを生成するモジュール群

疑似コードを格納したテーブル p_code_tbl

   

疑似コードを解釈し実行する

スタック操作  演算操作  命令アドレス 制御操作

   Evaluator (仮想マシンとしての機能)

p_code_tbl

    Parser (構文チェックと    疑似コード生成の機能)

擬似コードの生成方法とスタック上での操作との対応

スタック上でのこのような擬似命令を順に実行すると・・・

< a >  

< b >

Evaluator

   a + b 

   a b +

①逆ポーランド表記に置換する

計算式

Parser②対応する順序で疑似コードを生成

[ a ]   [ b ]   ADD

[ a ] A で示される番地から値をスタックの先頭に積む命令ADD   スタック上の2つのオペランドに対して加算演算を     行い,その結果をスタック先頭に積む命令

ADD 演 算 の 実行

計算式で記述した計算が実行された

< a > + < b > <a> a で示される番地からもってきた値

スタック上でのこのような擬似命令を順に実行すると・・・

   a + b   - c 

対応する順序で疑似コードを生成

[ a ]   [ b ] ADD [ c ] SUBT

< a > + < b >

Evaluator

Parser

< c >

SUBT 演算の実行

<a>+<b> - <c>

計算式で記述した計算が実行された

  a   + b * c     

[ a ]     

疑似コードを生成

Evaluator

Parser

計算式

< a >  

計算式で記述した計算が実行された

計算の優先度の高いものを一つのまとまりとして扱うと・・・

MULT 演算

< b >  

< c >  

< b > * < c >

ADD 演算

<a> + <b>*<c>

    ? ADD      

[ b ]   [ c ]   MULT     

スタック上でのこのような擬似命令を順に実行すると・・・

(  a + b )* c     

Parser

計算式

< a >  

計算式で記述した計算が実行された

計算の優先度の高いものを一つのまとまりとして扱うと・・・

< b >  

疑似コードを生成

ADD 演算 Evaluator

< a > + < b > 

< c > 

MULT 演算

(<a>+<b>)*<c>

[ c ]   MULT     

    ?    

[ a ]   [ b ]   ADD     

スタック上でのこのような擬似命令を順に実行すると・・・

構文規則にしたがっているかの構文チェック,     および擬似コードを生成するプログラムの考え方

  

  計算の優先度が高いものは,一つの“まとまり”として扱い

     その処理は“まとまり”に任せる

構文チェックと擬似コードの生成 

  方針

数式とは ・・・+

-

+

- 項

+,- より優先度の高い演算を含むものは「項」として一つに

まとめて扱い,その構文チェックと擬似コード生成は「項」に任せる

 項

因子*

/

*

/ 因子 ・・・ 項とは 

* , / より優先度の高い演算を含むものは「因子」として一つに

まとめて扱い,その構文チェックと擬似コード生成は「因子」に任せる

例えば...

因子とは 数字 

変数名

(  数式  )

式 (expression)::=  項 (term)

+

-

以下の構文図式( syntax Diagram) で示すように記述されているかチェックすればよい

構文チェックの方法

項 (term)::=  因子 (factor)

*

/

 

 因子( factor ) :: =                  変数名( variable name ) 

                定数 (constant)

               (   式 (expression)    )

実は,構文図式は関数呼出しの手順に対応している

                +                  -

 関数 expression ( )   ::=         term ( )                                   *                /

 関数 term   ( ) ::=         factor ( )

 関数 factor   ( )::=         variable_name ( )              constant ( )

       (    expression ( )    )

再帰呼出し

疑似コード生成の方法

                +                  -

 関数 expression ( )   ::=         term ( )                                   *                /

 関数 term   ( ) ::=         factor ( )

 関数 factor   ( )::=         variable_name ( )              constant ( )

       (    expression ( )    )

ADD SUBT 

2つ term() が呼出された後に生成

MULT DIVD2つ factor() が呼出された後に生成

VALC:  変数のアドレス CNST:  定数のアドレス

                +                  -

 関数 expression ( )   ::=         term ( )                                 

項を解析する関数 term() を呼び出す//※ 関数 term() を出るときには,必ず次の字句 (1語 )を syllable_buffにもってきている

次の語が演算子“+”か“-”である間,繰り返す

逆ポーランド表記に置換するために演算子を一旦記憶する

次の一語を取り出し syllable_buffに格納する

項を解析する関数 term()を呼び出す //※ 関数 term()を出るときには,必ず次の字句(一語)を                 syllable_buffにもってきている

一旦記憶した演算子を後に置いて疑似コードを生成する

 関数 expression ( ) 

 例えば,関数 expression ( )  のプログラム手順

   Evaluator(仮想マシンとしての機能)

CPU レジスタ群

   レジスタ A   ( rA)

 レジスタ B   ( rB)

TOS ( Top of Stack : :   の先頭スタック位置)

rA, rB とスタック先頭の 2語( Stack[TOS], Stack[TOS-1] )とはハードウェア的に対応が取られる

疑似コードを評価・実行するスタックマシンとは!!

スタック領域主記憶

BOS ( Base of Stack : :   の基底スタック位置)

Offset( 基底位置からの乖離 )

  p_code_tbl の PC ( )が指す位置から疑似コードをフェッチするプログラム カウンタ.

 演算命令群

 論理及び関係命令群

 ロード,および索引命令群

 スタック,およびサブルーチン命令群

 分岐命令群

終わり

 疑似コードを命令部とアドレス部に分解する.

  PCを一つ進める

PC の終わりかYesNo

Evaluator における疑似コードの評価・実行手順

疑似コードの判別

【 182ページ参照】

質問?

  情報処理実験 「数式インタプリタ」

     解 説解 説      

       “スタック操作の基本       “スタック操作の基本””

演算の種類によって異なるスタック操作

  2項演算(+,-,*,/,剰余 %,べき乗^など)

    < a >    < b > スタックの先頭

TOS(Top_of_Stack)

2項演算

< a > + <b>

   スタックの先頭( pop後)

   単項演算(階乗П,sin,cos,tan 等関数など)

    < a > スタックの先頭

単項演算

   < П a >

関数 call/return 時のスタック操作

   < p1 >=21

   < p2 >=87

  

int a = 12,   b =21,   c;

f ( b, 87 ); :

Lex_Levelレジスタ# 2

# 1

#0

MSCW:関数 1の位置

RCW:戻り位置 =0

1

2

3

4

5

6

7

    < b >=21

    < c >

    < a >=12

7

  [ #2: offset=4]

    < a >=12

   < p1 >=21

< a + p1>=33

   < p2 >=87

< a +p1-p2>= -54

   < x >

     < x >= -54

-54

次の疑似 の実行してゆくコード

サンプルプログラム

12

21

87

CONST_TBL

0

1

2

3

CSTC 0    // 変数 a(=12) の確保

CSTC 1 // 変数 b(=21) の確保

PUSH // 変数 c の確保

MKSW #2: 1   // 関数fを呼出す

VALC #1: 3    // b の値を積む

CSTC 2      // 値 87 を積む

ENTR

:

疑似コード生成

int f (int p1,float p2) { int x; x =   a + p1 – p2; return x; }

PUSH // 変数xの確保

NAMC #2:4 // x の 作アドレス成

VALC #1:2   // a の値

VALC #2:2   // p1 の値

ADD

VALC #2:3   //   p2 の値

SUBT

STOR

RETN

0

1

2

3

4

5

6

7

8

疑似コード生成

関数 f( 関数 No.=1) の疑似コード

stack基底

※[ LL=#1 ]

※[ LL=#2 ]

質問?