第9章 ソフトウェア技術 9.1 プログラミング言語 9.2 オペレーティングシステム 9.3 データベース技術 9.4 マルチメディア技術 9.5 ソフトウェア開発 9.1 プログラミング言語 9.1.1 9.1.2 9.1.3 9.1.4 プログラミング言語の種類 言語プロセッサの種類 言語プロセッサの処理 数式処理 9.1.1 プログラミング言語の種類 (1) 分類 プログラミング言語は,次のように分類できる。 汎用プログラミング言語 低水準言語 機械語 アセンブラ言語 第4世代言語 高水準言語 手続き型言語 非手続き型言語 エンドユーザ言語 シミュレーション 統計処理 特殊問題向き言語 数式処理 構造解析 (2) 低水準言語 コンピュータの命令体系に依存した言語.機械語とアセンブラ言語がある. ① 機械語 0と1の2進数の組合せで処理内容を記述したもの。 ただし,実際には16進数等でアドレス等の計算を行いながら記述する。 ハードウェアへの依存性が高く汎用性が低いだけでなく, 命令コードや命令のフィールド等にもついても熟知する必要があり, 扱いにくい。 ② アセンブラ言語 機械語の命令コードや命令のフィールドについての知識や, アドレス計算等を行う等の面倒をなくし,記号で表現したもの。 基本的には,機械語命令と1対1で対応.ハードウェアに依存するので, 機種毎にアセンブラ言語が異なる。 現在では,マクロアセンブラが主流であり, 複数命令をまとめて定義できる機能を持つアセンブラが多い。 (3) 高水準言語 ハードウェアの命令体系を意識しないで記述できる言語。 手続き型言語と非手続き型言語がある。 [特徴] ① 手続き型言語 ・ アルゴリズムに対応した手順を記述する。 ・ 処理手順等を表現するための知識が必要である。 ② 非手続き型言語 ・ 処理手順が定型化されており(必ずしもそうでない言語もあるが), 手続き型言語にくらべ生産性が高い。 ・ 言語特有の関数や基本となるアルゴリズムが規定されているので, 自由度が低い場合も多い。 プログラムの動作概念 プログラミング言語を,その言語で書かれたプログラムの動作概念から, ① 手続き型言語(COBOL, Fortran, C, Pascal等) ② 関数型言語または宣言型言語(Lisp,Prolog等) ③ データ主導またはオブジェクト指向言語(SmallTalk,C++等) に分類することもある。 (3) 高水準言語の例 [手続き型言語] FORTRAN 科学技術計算分野向き。高水準言語の草分け.科学技術計算用関数が豊富・ COBOL 事務分野向き。事務処理分野での表現や機能が豊富。 ALGOL 科学技術計算向き。再帰呼び出し等が可能。言語体系が整然としている。 PL/1 事務処理,科学技術計算の両分野でも使える言語として開発された。 BASIC 教育用として開発されたが,パソコン用言語として一般的。 C UnixのOS開発用言語として開発.データ構造表現が柔軟。 Pascal ALGOL系の教育用言語。データ抽象化の概念に優れる。 Ada 本来は軍需用の組み込み計算機用言語として開発.Pascalの特徴を備える。 C++ Cにオブジェクト指向型の概念を取り入れる。 Java C++に類似しているが,ポインタ等,コンピュータ構造を意識した部分がない。 Visual Basic オブジェクト指向等の概念を取り入れたBASIC。 [非手続き型言語] Lisp リスト処理用関数型言語。データもプログラムも同じ形式。 Prolog 論理型言語。述語論理の書換え規則による実行を行い,探索問題等に強い。 APL ベクトルや木構造を表現できる数学的な表記を基本とした関数型言語。 RPG 報告書作成用の表形式言語(Report Program Generator)。 Smolltalk オブジェクト指向型言語の草分け。クラス定義等に優れる。 (4) 第4世代言語(4GL) 業務処理用のプログラム開発や保守を 容易に行うことを目的とした言語やソフトウェアパッケージ。 短期間で言語を習得できるとされているが, 最近はあまり使われていない。 (5) エンドユーザ言語 表計算ソフト,データベース,文書作成ソフト,CADソフト, GIS ソフトなどに組込まれたエンドユーザ用の言語。 従来は,手順等が限定されたスクリプト言語としての 表記法がほとんどであったが, 高水準言語と同じ記述で柔軟性に富む言語が 用意されていることもある。 [例] AutoLisp,Visual Basic,Javaなど (6) 特殊問題向き言語 特殊な問題を応用分野に適した表現で記述できる言語。 処理内容が特化している一方,適用分野が限定されている。 過去は,POL(Problem Oriented Language)とも呼ばれた。 [例] ① シミュレーション(GPSS, Simula) ② 統計処理(SPSS) ③ 数式処理(FORMAC) ④ 構造解析(COGO) 9.1.2 言語プロセッサの種類 (1) 言語プロセッサとは 機械語以外で記述されたプログラムは, コンピュータが認識できる表現(機械語)に変換したり, 解釈して実行するための制御が必要である。 ① 翻訳(コンパイル) : 機械語に変換すること。 ② 通訳(インタプリート) : ③ アセンブル 解釈しながら実行すること。 : アセンブラ言語で記述されたプログラムの翻訳。 (ただし,基本的な処理はコンパイルと同一) これらのプログラムを総称して言語プロセッサと呼ぶ。 (2) 用語 ① 原始プログラム(ソースプログラム) プログラム言語で記述したプログラム。 ② 目的プログラム(オブジェクトプログラム) 言語プロセッサで翻訳したできたプログラム。 通常,複数のオブジェクトプログラムを 連係編集プログラム(リンケージエディタとも呼ぶ)で組合せ, 実行可能なロードモジュールを作成してプログラムが完成する。 ③ 相対形式プログラム 連係編集プログラムで組み合わせる前のオブジェクトプログラム。 ④ 実行形式プログラム ロードモジュールを実行形式プログラムと呼ぶこともある。 パソコン等では,連係編集プログラムを通さず,言語プロセッサから, 直接実行可能なロードモジュールを作成する場合もある。 (3) 言語プロセッサの分類 (a) アセンブラ アセンブラで記述されたプログラムを目的プログラムに翻訳(アセンブリ)。 (b) コンパイラ 高水準言語で記述されたプログラムを目的プログラムに翻訳(コンパイル)。 ただし,直接目的プログラムに変換せず, いったんアセンブラ言語に変換し, 目的語への変換はアセンブラに任せる処理系もある。 (c) インタプリタ 高水準言語で記述されたプログラムを1文ずつ解釈(インタプリート)して実行。 (d) ジェネレータ 高水準言語で表現可能な機能よりマクロな表現形式を設定し, 記述されたプログラムを高水準言語のソースプログラムに展開する。 インタプリタについての補足 インタプリタは,実行するたびに文を解釈するので実行スピードが遅い。 このため文の解釈をあらかじめ行って,解読が容易な中間言語に変換し, 実行時は中間言語を解読しながら実行することもある。 あらかじめ行う文の解釈をコンパイルと称しているインタプリタもあるので, コンパイラにおけるコンパイルと混同しないよう注意する必要がある。 ジェネレータについての補足 ① ジェネレータは,特殊問題向き言語で使われる手法であるが, 一般的な処理を記述する方法であるNSチャートやデシジョンテーブルを FORTRANやCOBOLのソースプログラムに展開するものもある。 ② 特殊なジェネレータとしては,プログラミング言語の文法を入力して, 構文解析部分のソースプログラムを生成する コンパイラジェネレータ(例えばXPL等)がある。 ③ エンドユーザ言語でよく使われる方法であるが, 母体とするソフトウェアで操作を行うと, スクリプト言語やマクロ言語で書かれたソースプログラムを 生成する機能(スクリプト記録機能,マクロ記録機能等と呼ばれる)を持つ ソフトウェアがある。 この機能も,広い意味でジェネレータとして捉えることができる。 9.1.3 言語プロセッサの処理 (1) 処理概要 [アセンブラやコンパイラの処理] 最適化を行わないコンパイラもあるので注意が必要である。 ソースプログラム 字句解析 構文解析 (Lexical Analyze) (Syntax Analyze) 最適化を行わない言語プロセッ サもあるので,最適化プロセス のデータフローは点線で描いて いる。 意味解析 コード生成 (Semantic Analyze) (Code Generation) 最適化 (Optimize) オブジェクト プログラム 処理概要(続き) [インタプリタの処理] インタプリタは,本来,ソースプログラムを解釈しながら実行するが, 文の解釈を高速化するため中間言語に一旦変換してから 実行するのが最近の傾向である。 中間言語 ソースプログラム if a = b then input #5, else A(I) = 1.0 end if do while flg I=1:k=2 if aa then flg=true else 中間言語 への変換 コ マ ン ド 処 理 へ の 分 岐 実行用 パラメータ 処理1 処理2 …… 中間言語に変換せず直接ソースプログラムを 解釈しながら実行するのが,本来の意味での インタプリタであるが,性能を上げるため 中間言語に変換するのが一般的である。 文の解釈 (2) 生成プログラムの種類 名 称 再使用可能 (re-usable) プログラム 再 帰 (recursive) プログラム 再入可能 (re-entrant) プログラム 性 質 逐次再使用可能プログラム.既にローディングしてあるプログラム を,再ローディングなしに再利用しても正しい結果を出力する プログラム.但し,複数タスクから同時に使用できない. プログラム内部から自分自身を呼び出しても正しい結果を返すこと ができる.最初に可能にしたのは Algol が有名。 現在では多くの言語で可能になっている。 複数のタスクから同時に呼び出されても,それぞれの呼び出しに 対して,正しい結果を返却する.このためには,プログラム実行 用のメモリを,呼び出したタスク側に確保するか, メモリ管理の待ち行列管理等が必要。 (3) 言語プロセッサの記述言語 言語プロセッサの記述言語は,以下のように実に様々である。 ① 言語プロセッサは,旧来アセンブラで記述することが多かったが, 高水準言語の性能向上と共に,高水準言語で記述されることも多くなってきた。 ② 言語プロセッサ自身を解釈される言語自身で記述する方法は, 伝統的にLisp言語で行われている。 ③ 特殊問題向き言語のFortranジェネレータをFortranで記述, 宣言型言語であるPrologの処理系を関数型言語であるLispで記述, 宣言型言語である代数的仕様記述言語を宣言型言語であるPrologで記述 など色々な例がある。 (4) インタプリタの実現法の変形 インタプリタの実現方法として次のような手法が採用されることがある。 ① インタプリタの中間言語を仮想的なハードウェアの機械語命令 (仮想マシン命令)として設定する。 ② 中間言語への変換はコンパイラと同じ処理を行い,仮想マシン命令に対応 したアセンブラ(仮想アセンブラ)言語のソースプログラムとして出力する。 ③ 最後に,仮想アセンブラで仮想マシン命令に展開する。 この方式によるインタプリタは,以下のように実行される。 ① ローディングのシミュレーション 仮想マシン命令を格納したファイルを読込む。 ② 仮想ハードウェアの実行シミュレーション 仮想マシンでの命令フェッチ,オペランドフェッチ,命令実行を, ソフトウェアでシミュレートする。 手法についての補足 ① 高水準言語の解釈では,字句解析,構文解析,意味解析を行う必要があり, これらの処理に比べ,仮想マシンのシミュレートは,はるかに単純である。 従って,この方法で言語プロセッサを実現しておくと, 単純な仮想マシン命令のインタプリタを作成することによって, 様々なハードウェアで言語プロセッサを実現できる。 ② この方法によるインタプリタの実現方法としては,初期のPascalが有名である。 初期のPascalの中間言語はPコードと呼ばれており, 単純な仮想マシン命令から構成されている。 このためPascalは様々なハードウェア上で実行可能になっている。 ③ 一方,仮想アセンブラ言語のソースプログラムとして出力されているので, 仮想アセンブラ言語を,目的とするハードウェアのマクロアセンブラの マクロ命令として定義すれば,簡単に言語プロセッサのコンパイラ版が 完成することになる.このようなコンパイラのインプリメント方式を C言語に適用したのがWhite Smithであるが, 現在ではコンパイラの実現方法として一般的である。 9.1.4 数式処理 (1) 逆ポーランド記法 言語プロセッサの構文解析で,最も古典的な話題は, 数式における演算子の優先度解釈である。 [例]A+B/C の実行 除算が加算より優先順位が高いので, B/Cを行ってからAを加算する。 この処理を行うために,コンパイラやインタプリタでは, 先に実行する演算子が先に表記される逆ポーランド記法に変換する。 [例の逆ポーランド記法] ABC/+ 意味:Aに(BをCで『除した』値)を『加える』 (2) 逆ポーランド記法への変換 ただし,単純化のために2項演算子のみとする。 ① 結果領域及びスタックを空にする。 ② 変数や定数のとき,そのまま結果領域に移す。 ③ 前括弧“(”のとき,スタックに積む。 ④ 後括弧“)”のとき,前括弧までをスタックの上から順に結果領域に移し, ポップアップする。 ⑤ 演算子のとき,スタック上の演算子の優先順位が自分より高いかどうかを判 定する。 ⅰ)自分より低い場合は,自分をスタックに積む。 ⅱ)自分より高いか同じであれば,スタック上の演算子を結果領域に移し, ポップアップする.これを自分より優先順位が低い演算子がスタック のトップに来るまで繰り返す.スタックが空,前括弧,または自分 より低い演算子が見つかったら,自分をスタックに積む。 ⑥ 式の終了のときは,上から順に結果領域に移しスタックが空になるまで ポップアップする。 変換の様子① 変数なので,結果領域に移す [結果領域] [解釈する演算式] A A A×B+(C+D/E)×F [スタック] 変換の様子② 演算子なので,スタックに積む [結果領域] [解釈する演算式] A ×B+(C+D/E)×F [スタック] × 変換の様子③ 変数なので,結果領域に移す [結果領域] [解釈する演算式] B AB B+(C+D/E)×F [スタック] × 変換の様子④ 自分より強い演算子を掃出して,自分をスタックに積む [結果領域] [解釈する演算式] × AB× +(C+D/E)×F [スタック] + 変換の様子⑤ 前括弧なので,スタックに積む [結果領域] [解釈する演算式] AB× (C+D/E)×F [スタック] ( + 変換の様子⑥ 変数なので,結果領域に移す [結果領域] [解釈する演算式] C AB×C C+D/E)×F [スタック] ( + 変換の様子⑦ 演算子なので,スタックに積む [結果領域] [解釈する演算式] AB×C +D/E)×F [スタック] + ( + 変換の様子⑧ 変数なので結果領域に移す [結果領域] [解釈する演算式] D AB×CD D/E)×F [スタック] + ( + 変換の様子⑨ スタック上の演算子の優先順位が自分より低いので,スタックに積む [結果領域] [解釈する演算式] AB×CD /E)×F / [スタック] + ( + 変換の様子⑩ 変数なので,結果領域に移す [結果領域] [解釈する演算式] E AB×CDE E)×F / [スタック] + ( + 変換の様子⑪ 後括弧なので,前括弧までをスタックから掃出す。 [結果領域] [解釈する演算式] AB×CDE/+ /+ )×F / [スタック] + ( + 変換の様子⑫ スタック上の演算子の優先順位が自分より低いので,スタックに積む [結果領域] [解釈する演算式] AB×CDE/+ A ×F [スタック] × + 変換の様子⑬ 変数なので,結果領域に移す [結果領域] [解釈する演算式] AB×CDE/+F F F [スタック] × + 変換の様子⑭ 最後なので,スタックからポップアップして,結果領域に移す [結果領域] [解釈する演算式] AB×CDE/+F×+ ×+ [スタック] × + (3) 逆ポーランド記法の利用 逆ポーランド記法による表現により, 機械語への変換やインタプリートが単純になる。 インタプリートする場合は, ① 逆ポーランド記法を前からスキャンする。 ② 変数や定数のときは変数の値や定数をスタックにプッシュ。 ③ 演算子が来たらスタック上の値をポップアップして演算を行い, 結果を更にプッシュする。 の処理を繰り返せば, 最後にスタックに残ったものが演算結果である。 機械語への変換では,インタプリートする手順を 機械語の変換に置きかえればよい。 9.1 プログラミング言語 完
© Copyright 2024 ExpyDoc