Microsoft Word - problem3.doc

Similar documents
Microsoft Word - problem5.doc

Microsoft PowerPoint ppt

Microsoft PowerPoint ppt

Microsoft PowerPoint - prog03.ppt

Microsoft PowerPoint ppt

Microsoft Word - Javacc.docx

PowerPoint プレゼンテーション

(Microsoft PowerPoint - \223\306\217KJAVA\221\346\202R\224\ ppt)

Microsoft PowerPoint ppt

Microsoft PowerPoint - 03BNFScanner.ppt [互換モード]

Prog1_6th

JavaプログラミングⅠ

デジタル表現論・第4回

情報工学実験 C コンパイラ第 2 回説明資料 (2017 年度 ) 担当 : 笹倉 佐藤

メソッドのまとめ

デジタル表現論・第6回

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

プログラミング基礎I(再)

Microsoft PowerPoint - prog09.ppt

Microsoft PowerPoint - prog09.ppt

PowerPoint プレゼンテーション

基本情報STEP UP演習Java対策

PowerPoint プレゼンテーション

JAVA入門

Java プログラミング Ⅰ 3 回目変数 変数 変 数 一時的に値を記憶させておく機能型 ( データ型 ) と識別子をもつ 2 型 ( データ型 ) 変数の種類型に応じて記憶できる値の種類や範囲が決まる 型 値の種類 値の範囲 boolean 真偽値 true / false char 2バイト文

PowerPoint プレゼンテーション

Java講座

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

スライド 1

プログラミングA

基礎計算機演習 実習課題No6

Prog1_10th

Microsoft PowerPoint - prog04.ppt

文字列操作と正規表現

Microsoft PowerPoint - 03BNFScanner-print.ppt

Prog2_9th

Javaプログラムの実行手順

プログラミング入門1

Microsoft PowerPoint - 計算機言語 第7回.ppt

JavaプログラミングⅠ

文法と言語 ー文脈自由文法とLR構文解析2ー

情報処理Ⅰ

Microsoft Word - CompA-Ex doc

Microsoft Word - CombB-Ex

問 次の Fortran プログラムの説明及びプログラムを読んで、設問に答えよ。

Prog1_15th

プログラミング入門1

PowerPoint プレゼンテーション

Microsoft PowerPoint - chap10_OOP.ppt

メディプロ1 Javaプログラミング補足資料.ppt

プログラミング入門1

第二回独習 Java ゼミ 第二章クラスとメソッド 2.1 メソッドの構造 2.2 静的メソッドと静的変数の概要 2.3 インスタンスメソッドとインスタンス変数の概要 2.4 Integerクラス 2006/04/19 神津健太

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

Javaによるアルゴリズムとデータ構造

PowerPoint プレゼンテーション

Javaの作成の前に

JavaプログラミングⅠ

プログラミング入門1

プログラムの基本構成

プログラミング入門1

プログラミング入門1

Week 1 理解度確認クイズ解答 解説 問題 1 (4 2 点 =8 点 ) 以下の各問いに答えよ 問題 bit 版の Windows8.1 に Java をインストールする時 必要なパッケージはどれか 但し Java のコンパイルができる環境をインストールするものとする 1. jdk

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

プログラミング入門1

GEC-Java

オブジェクト指向プログラミング・同演習 5月21日演習課題

Microsoft Word - java a.doc

ガイダンス

JavaプログラミングⅠ

JavaプログラミングⅠ

Microsoft PowerPoint - prog08.ppt

C#の基本2 ~プログラムの制御構造~

2

プログラミング入門1

Prog1_2nd

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

情報工学実験 C コンパイラ第 2 回説明資料 (2018 年度 ) 担当 : 笹倉 佐藤

PowerPoint Presentation

プログラミング入門1

JavaプログラミングⅠ

プログラミング入門1

Java プログラミング Ⅰ 3 回目変 数 今日の講義講義で学ぶ内容 変数とは 変数の使い方 キーボード入力の仕方 変 数 変 数 一時的に値を記憶させておく機能 変数は 型 ( データ型 ) と識別子をもちます 2 型 ( データ型 ) 変数に記憶する値の種類変数の型は 記憶できる値の種類と範囲

Microsoft PowerPoint - lec06 [互換モード]

JavaプログラミングⅠ

Prog1_3rd

ポインタ変数

Java プログラミング Ⅰ 7 回目 switch 文と論理演算子 今日の講義講義で学ぶ内容 switch 文 論理演算子 条件演算子 条件判断文 3 switch 文 switch 文 式が case のラベルと一致する場所から直後の break; まで処理しますどれにも一致致しない場合 def

Microsoft PowerPoint - 3.ppt [互換モード]

Java言語 第1回

kiso2-03.key

メソッドのまとめ

<4D F736F F D2091E F196E291E889F090E C4816A82CC838C E646F6378>

Microsoft PowerPoint - Compiler06note.pptx

問題1 以下に示すプログラムは、次の処理をするプログラムである

PowerPoint プレゼンテーション


JavaプログラミングⅠ

コンピュータ中級B ~Javaプログラミング~ 第3回 コンピュータと情報をやりとりするには?

Microsoft PowerPoint - Compiler06.pptx

ガイダンス

Transcription:

コンパイラ演習 : 作成問題 3 ( 担当 : 佐々木晃 ) 次のような言語のコンパイラを作成することが目的である 目的機械は hsm 仮想機械とする 昨年度までの講義資料 ( 中田先生 開先生による ) も参考にすること 演習問題 B3 問題番号 : B3 課題名 : コンパイラの作成 3 (1) 記号表の実装 (2) JavaCC プログラム課題 3 (1) 記号表の実装 記号表を実現するクラス NameTable を作成し 動作を確かめよ 記号表に登録する名前 ( エントリ ) はクラス Name として つづり と 登録したアドレス を情報として持つこととする その他の機能は例を参考にせよ ( ただし メソッド本体は 省略している ) ソースプログラムのアップロードは不要です プログラムはレポートに添付してください 実行例や 内容の説明は必要です (2) JavaCC プログラム課題 3 次のような機能を持つ言語のコンパイラを作成せよ 文法は前回と同じ 文法 : <PROGRAM>::= <MAIN> <MAIN>::= 'int' 'main' '(' ')' <BLOCK> <BLOCK>::= '' <INTDECLLIST> <STATEMENTLIST> '' <INTDECLLIST>::= empty <INTDECLLIST> <INTDECL> <INTDECL>::= 'int' <IDENTLIST> ';' <IDENTLIST>::= <IDENT> <IDENTLIST> ',' <IDENT> <STATEMENTLIST>::=empty <STATEMENTLIST> <STATEMENT> <STATEMENT>::= <SUBSTITUTION> '=' <EXPRESSION> ';' 'putint' '(' <EXPRESSION> ')' ';' <SUBSTITUTION>::= <IDENT> <EXPRESSION>::= <TERM> <EXPRESSION> '+' <TERM> <EXPRESSION> '-' <TERM> <TERM>::= <UNARY> <TERM> '*' <UNARY> <TERM> '/' <UNARY> <UNARY>::== <FACTOR> '-' <UNARY> <FACTOR>::= <IDENT> <NUMBER> '(' <EXPRESSION> ')' 字句の定義 ( 終端記号 ) o 空白 タブ 改行 ( これらは構文の中では使われない スキップする )

o <IDENT>::= 英字で始まる英数字の繰り返し文字列 o <NUMBER>::= 数字の 1 回以上の繰り返し文字列 o 括弧記号 区切り記号など o 演算記号 o その他キーワード ( 予約語 ) int, main, putint など (empty は ε( 空の記号列 ) を意味する ) -------------------------------------------- putint <EXPRESSION> の値を整数で出力 例 : int main() int a; int b; a = 1; b = 2; 結果 : PUSH 0 2 LDC 0 1 STV 0 0 LDC 0 2 STV 0 1 POP 0 2 HLT 0 0 メモ : 紙レポートに入れるべきもの JavaCC のソースプログラム ( 別途プログラムは指定場所にアップロードすること ) 実行結果 (1) ソースプログラム実行結果は 求められている機能がひととおり実装できたことを証明するものであるから それに足る例題 ( ソースプログラム ) をいくつか用意すること (2) ソースプログラムの翻訳結果 (hsm コード エラーの場合はエラーメッセージ ) (3) 翻訳結果を hsm 上で実行させたときのスナップショット (putint による出力がない場合など 最後まで実行させると スタックの中身がなくなり本当に実行しているかわからない場合は POP する手前の結果が良いだろう ) いつもどおり考察は必要です 補足説明 ( 作成問題 3) 下記のプログラムにおける記号表を考えてみよう int main() int abc; int cd; int efg; cd = 10; putint(cd); このプログラムでは 変数 abc, cd, efg の登録と cd の検索を行っている この動作に従って 次のような確認を手動で行ってみよ ( 参考例の main メソッドを参照 ) 1. 変数 "abc","cd", "efg" を登録する

2. 1 の状態での記号表の内容を出力せよ 3. 変数 "cd" を表から検索して 内容を表示せよ 動作例 : id:abc, address:0 記号表の内容を表示 ( 上記 2) id:cd, address:1 id:efg, address:2 id:cd, address:1 変数 cd に対するエントリの検索結果 ( 上記 3) 上記の動作確認のほか 2 重宣言のエラーや 未宣言の変数の式での使用のエラーとなる例も 確認しこれをレポートに載せて下さい 記号表のプログラムプログラムの例 ( メソッドの中身中身は一部省略 ): NameTable.java class Name String ident; int type; int address; Name(String id, int a) // コンストラクタ public String tostring() // エントリの内容の文字列表現を返す // 例 id:abc, address:3 public class NameTable Name[] nametable; // テーブル本体 名前 ( エントリ ) の配列 int index; int nextaddress; // 次に宣言される変数の address の値 int maxindex; NameTable(int max) // コンストラクタ テーブルに登録できるエントリ数は max とする int addname(string ident) throws RuntimeException // テーブルに名前 ( エントリ ) を登録する エラーがあったら例外を投げる // 領域のどこに登録したかを返す Name searchname(string ident) throws RuntimeException // テーブルにつづり ident をもつ名前 ( エントリ ) を探索し あればそれを返す // エラーがあったら例外を投げる int getnextaddress() // nextaddress を返す public String tostring() // nametable の内容の文字列表現を返す // 例 : // id:abc, address:0

// id:c, address:1 // id:def, address:2 // ( ネームテーブルをプリントするときのため ) // 下記は実装例 StringBuffer buf = new StringBuffer(); for (int i=0; i<index; i++) buf.append(nametable[i].tostring()); buf.append("\n"); return buf.tostring(); public static void main(string arg[]) NameTable nt = new NameTable(256); nt.addname("abc"); nt.addname("cd"); nt.addname("efg"); System.out.println(nt); // println(#) は 内部で #.tostring() を呼ぶことに注意 Name entry = nt.searchname("cd"); System.out.println(entry); 例外を投げるときは throw new RuntimeException(" エラーメッセージ "); のようにすればよい Java II などの講義資料を参考にすること 補足説明 ( 作成問題 3) コンパイラの作成問題 3 のヒント ( 昨年度の解説ページを改変 ) 変数名に対するアドレスとして, スタックの何段目を利用させるかの管理には, 変数表 ( 記号表 ネームテーブル ) を作成する必要がある. コンパイラの内部では, 構造体の配列などによるテーブルを用いて変数表を実装する. 例えば, 以下のようなクラスを用意すると良い ( 本日の問題 (1) と同じものです Main メソッドがないだけです ) class Name String ident; int address; Name(String id, int a) // コンストラクタ public String tostring() // エントリの内容の文字列表現を返す // 例 id:abc, address:3 public class NameTable Name[] nametable; // テーブル本体 名前 ( エントリ ) の配列 int index; int nextaddress; // 次に宣言される変数の address の値 int maxindex; NameTable(int max) // コンストラクタ テーブルに登録できるエントリ数は max とする

int addname(string ident) throws RuntimeException // テーブルに名前 ( エントリ ) を登録する エラーがあったら例外を投げる // 領域のどこに登録したかを返す Name searchname(string ident) throws RuntimeException // テーブルにつづり ident をもつ名前 ( エントリ ) を探索し あればそれを返す // エラーがあったら例外を投げる int getnextaddress() // nextaddress を返す public String tostring() // nametable の内容の文字列表現を返す // 例 : // id:abc, address:0 // id:c, address:1 // id:def, address:2 // ( ネームテーブルをプリントするときのため ) // 下記は実装例 StringBuilder buf = new StringBuilder(); for (int i=0; i<index; i++) buf.append(nametable[i].tostring()); buf.append("\n"); return buf.tostring(); Name クラスの ident には, 変数名を保持しておく.(token.image を利用する ) address には,base からの相対アドレスを保持する.( 今回は,base は,0 です.) 例外を投げるときは throw new RuntimeException(" エラーメッセージ "); のようにすればよい 宣言文で必要とされる処理は, 上記のテーブルに必要なデータを登録することである. データを登録する前に, 同じ名前が既に登録されているか調べ, もし登録されていれば, 二重定義の処理をして終了する. 登録処理の概要は, 以下の通りである. nametable の index 番目を利用する変数を登録する場合 (index の初期値は,0 とする ) nametable[0]~nametable[index-1] までに今から登録する名前と同じ identifier があるかチェックし, あれば ( 二重定義されていれば ), 然るべき処理をして終了. そうでなければ, Name の新しいインスタンスを作り ( ここでは n とする ) nametable[index] に登録する n に登録する内容等は下記のとおり n.ident へ文字列代入 ; n.address=nextaddress; nextaddress=n.address+1; index++; 今回は, 変数領域の確保として, PUSH 0 nt.getnextaddress();

および,HLT 命令の直前で, POP 0 nt.getnextaddress(); が必要となる. ここで nt は名前表 すなわち NameTable のインスタンスである 参照 代入で必要とされる処理は, 必要とされる変数が利用する段 ( アドレス ) を計算して求めることである. 1. 字句解析が検出した文字列と等しい identifier を持つテーブル要素を見つけ出す. もし見付けられなかったら, 変数または配列の未定義の処理をして終了する. 2. 見つけ出した変数の address を,LDV 命令で利用する. 3. putint 文,getint 文, の処理でアドレスの決定が必要な場合, 上記と同じ方法が利用できる. JavaCC の記述記述に関するするヒント <SUBSTITUTION> について代入文では 代入の左辺に非終端記号 <SUBSTITUTION> を導入して 下記のようにしている これは 将来配列要素への ( たとえば a[10]=...) 代入を行うためである <STATEMENT>::= <SUBSTITUTION> '=' <EXPRESSION> ';'... <SUBSTITUTION>::= <IDENT> さて 代入文に対するコードは 上記のとおり STV 命令を用いて次のようになるはずである void Statement() Substitution() '=' Expression() STV 命令の出力... ところが 変数に対する番地は substitution の <IDENT> の文字を読まなければ計算できない void Substition() Token tk; tk=<ident> tk.image???; javacc では 非終端記号で解析した結果をメソッドの返り値として 情報を ( 解析木の上のほうに ) 渡すことができる ( 下のほうに渡す場合はメソッドのパラメータを用いる ) したがって 下記のようにするとよい void Statement() String st; st=substitution() '=' Expression() STV 命令の出力 (st を使って STV の番地を計算が可能 ); //(1)... String Substition() Token tk; tk=<ident> return tk.image; //(2) この場合 Substitution() というメソッドの中で終端記号 <IDENT> の文字列が求められるので この文字列を return で返すようにする (2) (1) の st=substitution() で Substitution() で求めた文字列 (=<IDENT> の返り値 ) が変数 st に代入される もちろん 今回の場合 <STATEMENT>::= <SUBSTITUTION> '=' <EXPRESSION> ';' を <STATEMENT>::= <IDENT> '=' <EXPRESSION> '; とすれば 問題は生じない

プログラムについてのについての補足 JavaCC の中に クラスを記述するには下記のようにする パッケージとしてクラス等を作成する場合は 適宜メソッド フィールド等を public 宣言する必要などがある PARSER_BEGIN(Compiler3) import java.io.*; public class Compiler3 //... static NameTable nametable; public static void main(string args[]) nametable = new NameTable(256);... class Name... class NameTable... PARSER_END(Compiler3)