Microsoft PowerPoint - 13Kadai.pptx

Similar documents
parser.y 3. node.rb 4. CD-ROM

Microsoft PowerPoint - 08LR-conflicts.ppt [互換モード]

Microsoft PowerPoint - Prog05.ppt

Java Scriptプログラミング入門 3.6~ 茨城大学工学部情報工学科 08T4018Y 小幡智裕

テキスト処理第 2 回 田中哲産業技術総合研究所情報技術研究部門 akira/textprocess/

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

Microsoft PowerPoint - 03BNFScanner-print.ppt

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

Microsoft Word - VBA基礎(3).docx

Microsoft PowerPoint - ruby_instruction.ppt

情報処理Ⅰ

第12回 モナドパーサ

18/12/06 情報工学実験 C コンパイラ (2018 年度 ) 担当 : 笹倉 佐藤 その 3 yacc の構造 定義部 %% 定義部の終了 規則部 %% 規則部の終了 ユーザ定義サブルーチン部 :C のプログラムを書く 形は lex と同じ 1

Java講座

JavaプログラミングⅠ

B演習(言語処理系演習)第一回

シェルプログラミング コマンドをパイプでつなげるだけでは済まないような ある程度まとまった処理を複数のコマンドを制御構文を用いたりしてファイルとしたものを ( シェル ) スクリプトと呼ぶ シェルプログラム バッチなどともいう.bash_profile もシェルスクリプトなので このファイルを解読し

Microsoft PowerPoint - 11RubyIntro-No02.ppt [互換モード]

ソフトウェア基礎 Ⅰ Report#2 提出日 : 2009 年 8 月 11 日 所属 : 工学部情報工学科 学籍番号 : K 氏名 : 當銘孔太

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

II 3 yacc (2) 2005 : Yacc 0 ~nakai/ipp2 1 C main main 1 NULL NULL for 2 (a) Yacc 2 (b) 2 3 y

コンピュータ工学講義プリント (7 月 17 日 ) 今回の講義では フローチャートについて学ぶ フローチャートとはフローチャートは コンピュータプログラムの処理の流れを視覚的に表し 処理の全体像を把握しやすくするために書く図である 日本語では流れ図という 図 1 は ユーザーに 0 以上の整数 n

Functional Programming

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

テキスト処理第 12 回 ( ) 田中哲産業技術総合研究所情報技術研究部門 u.ac.jp /

プログラミングA

プログラミング言語処理系論 (4) Design and Implementation of Programming Language Processors

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

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

Taro-Basicの基礎・条件分岐(公

PowerPoint プレゼンテーション

プログラミングA

Microsoft Word - Javacc.docx

Microsoft PowerPoint ppt

Scilab 勉強会 ( 第 3 回 ) 高橋一馬, 十文字俊裕, 柏倉守 平成 17 年 11 月 15 日 関数 ファイルはエディタを用いて作成する.Scilab にはエディタ SciPad が附属している.SciPad では なく他のエディタを利用してもよい. 作成した関数は Scilab に

復習 プログラミング 1 ( 第 4 回 ) 関数の利用 2 ループ処理 (while 文 ) 1. Chapter の補足 2 1. 関数とローカル変数 2. Chapter 3.1 の補足 1. Iteration, looping ( 反復処理 ) 2. ループ処理の例 実行例 3

メソッドのまとめ

Microsoft Word - DF-Salford解説09.doc

program7app.ppt

r9.dvi

プログラミング入門1

プログラミング基礎

CプログラミングI

オートマトン 形式言語及び演習 1. 有限オートマトンとは 酒井正彦 形式言語 言語とは : 文字列の集合例 : 偶数個の 1 の後に 0 を持つ列からなる集合 {0, 110, 11110,

Microsoft PowerPoint - prog03.ppt

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

Programming D 1/15

02: 変数と標準入出力

Microsoft Word - VBA基礎(6).docx

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

Prog1_3rd

Microsoft Word - CompA-Ex doc

break 文 switch ブロック内の実行中の処理を強制的に終了し ブロックから抜けます switch(i) 強制終了 ソースコード例ソースファイル名 :Sample7_1.java // 入力値の判定 import java.io.*; class Sample7_1 public stati

演習1

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

Tips29: JavaScript で電話番号 ( 局番 ) の検証 / 編集 [ ] JavaScript JAVA 論理値 (True,False ) リテラル true, false が使えるリテラル

このルールをそのまま正規表現として書くと 下記のようになります ^A[0-9]{2}00[0-9]{3}([0-9]{2})?$ ちょっと難しく見えるかもしれませんが 下記のような対応になっています 最初 固定 年度 固定 通番 ( 枝番 ) 最後 ルール "A" 数字 2 桁 0 を 2 桁 数字

Microsoft PowerPoint - C_Programming(3).pptx

Microsoft PowerPoint ppt

Ruby演習テキスト1

Microsoft PowerPoint - Compiler03note.pptx


Taro-cshプログラミングの応用.jt

Microsoft PowerPoint - Compiler06.pptx

メソッドのまとめ

Microsoft PowerPoint - 3.pptx

C 言語の式と文 C 言語の文 ( 関数の呼び出し ) printf("hello, n"); 式 a a+4 a++ a = 7 関数名関数の引数セミコロン 3 < a "hello" printf("hello") 関数の引数は () で囲み, 中に式を書く. 文 ( 式文 ) は

slide5.pptx

Microsoft PowerPoint - 2-LispProgramming-full

02: 変数と標準入出力

Microsoft Word - problem5.doc

Microsoft PowerPoint - Compiler06note.pptx

プレポスト【解説】

Ruby Ruby ruby Ruby G: Ruby>ruby Ks sample1.rb G: Ruby> irb (interactive Ruby) G: Ruby>irb -Ks irb(main):001:0> print( ) 44=>

Microsoft PowerPoint - Compiler03.pptx

Prog1_10th

kiso2-06.key

第 2 章 PL/SQL の基本記述 この章では PL/SQL プログラムの基本的な記述方法について説明します 1. 宣言部 2. 実行部 3. 例外処理部

※ ポイント ※

* ライブラリ関数 islower(),toupper() を使ったプログラム 1 /* 2 Program : trupper.c 3 Student-ID : K 4 Author : TOUME, Kouta 5 Comments : Used Library function i

ML Edinburgh LCF ML Curry-Howard ML ( ) ( ) ( ) ( ) 1

演算増幅器

Cプログラミング1(再) 第2回

r1.dvi

kantan_C_1_iro3.indd

つくって学ぶプログラミング言語 RubyによるScheme処理系の実装

PowerPoint プレゼンテーション

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

プログラミング入門1

プログラミング実習I

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

PowerPoint プレゼンテーション

Microsoft PowerPoint - kougi6.ppt

ohp07.dvi

Sort-of-List-Map(A)

JavaプログラミングⅠ

Microsoft PowerPoint - lec10.ppt

プログラミングD - Java

PowerPoint プレゼンテーション

Transcription:

提出 講義での説明を聞いて下さい 櫻井彰人 コンパイラ理論課題 締め切りは 8 月 1 日とします 順不同で できるものをできるだけ多く回答して下さい 電子メールで sakurai あっと ae どっと keio どっと ac どっと jp に送ってください ファイル形式は pdf か MsWord で ただし プログラムはテキストファイルで レポート課題 1 それぞれ 1 問として考えます 電卓 タイプのプログラムで 浮動小数点数を実装して下さい 字句解析部分だけの改造ですみます 電卓 タイプのプログラムで 大小 等不等を判別する式と論理式を実装してください 電卓 タイプのプログラムで 代入式を実装して下さい 補足 論理式 論理式の導入は 直線的 優先順位に注意 算術演算子より弱い ただ 論理式は限られた場所だけで用いることにする rule target: exp lexp lexp: exp '==' exp result = (val[0]==val[2]) exp '!=' exp result = (val[0]!=val[2]) exp '>=' exp result = (val[0]>=val[2]) exp '<=' exp result = (val[0]<=val[2]) exp '> exp result = (val[0]> val[2]) exp '<' exp result = (val[0]< val[2]) lexp '&&' lexp result = (val[0] && val[2]) lexp ' ' lexp result = (val[0] val[2]) '!' lexp result =!( val[1]) '(' lexp ')' result = val[1] TRUE result=true FALSE result=false 忘れてはいけない nonassoc '==' '!=' '>=' '<=' '>' '<' nonassoc '!' left '&&' ' ' when / A(== >= <=!=)/ when / A(&& )/ 勿論 まとめても結構 最も弱いところに追加 エスケープ記号の右なので 文字としての縦棒

少々無理ですが print ぐらいしたいので args : result = [] exp result = val # result = [val[0]] lexp result = val args ',' exp result.push( val[2] ) ヒント : 代入式 下記のようなものがどこかに書かれています IDENT '=' exp result = do_assign( val[0], val[2] ) def do_assign( vname, val ) @vtable[ vname ] = val レポート課題 2 練習問題 3: 直前結果の参照 変数と関数呼び出しが使えるようにして下さい直前の結果を参照することができると便利です %% という特別な変数を用意してください そして? Math.exp(3) = 20.0855369231877? x=%%*2 = 40.1710738463753 ヒント : 直前結果の参照 when / A%%/ と '%%' result = @lastresult と @lastresult = do_parse をしかるべきところに入れればよい. (3 番目は 入れる ではなく 置き換える です )? レポート課題 3 calc.y で文字列を扱えるようにして下さい intp.y の文字列部分をコピーすればよい スキャナーの "NUMBER" のあとに when / A"(?:[^" ]+.)*"/, / A'(?:[^' ]+.)*'/ @q.push [:STRING, eval($&) ] exp の定義中 ( "NUMBER" のあとに ) STRING 上記の正規表現は何を行っているのか説明して下さい レポート課題 4 ファイルが読めるようにしよう 行番号も実装しよう ---- footer コマンドライン引数の 1 番目 parser = Calcp.new begin if ARGV.length>=1 then デフォールトのファイル名 fname = ARGV[0] else fname = 'test' 行番号関連 File.open(fname) f parser.parse(f) rescue NoMethodError, ArgumentError, ParseError print $!, " at line #parser.lineno", " n" ファイルを 一行ずつ処理します def parse(str) lineno = 1

ファイルが読めるようにしよう (2) def parse(f) @lineno = 1 f.each do line line.strip! print( ">>", line, " n" ) until line.empty? case line line = $' @q.push [false, '$'] do_parse puts( "=>"+@result.to_s ) @lineno += 1 target: exp @result = result /* none */ @result = result = 0 def lineno @lineno 下記も可 attr_reader :lineno 行番号部分 @lineno += 1 @q.push [false, '$'] @lastresult = do_parse def parse(f) @lineno = 0 f.each do line %% 用です def lineno @lineno rescue NoMethodError, ArgumentError, ParseError print $!, " at line #parser.lineno", " n" レポート課題 5 練習問題 4: if then else Ruby の if then else と if then 相当の文が使えるようにしてください if 部分には数式を書き その値が 0 ならば else 部分の値を 0 以外であれば then 部分の値を if 式の値とする 何となくできるようにするのは 簡単です 例えば then 部分 else 部分には " 代入のない " 式しか現れないとする 無駄な計算をしてもよいとする 結果には不要な式 ( 例えば 条件が成立しているときの else 部分 ) の計算をしてもよいとする 例解 例えば exp の定義に次のようなものを付け加えればよい if val[1]!=0 then result=val[3] else result=nil if val[1]!=0 then result=val[3] else result=val[5] a = 0 if a then 1 else 2 = 2 a = 1 if a then 1 else 2 = 1 プログラム作成上の注意 if, then, else, といったキーワードが出てくる 変数として認識しては困る 予約語 ( つまり システムが使用することを予約している語 ) とする def parse(str) when / A[a-zA-Z_] w*/ word = $& @q.push [(RESERVED[word] :IDENT), RESERVED_V.key?(word)? RESERVED_V[word] : word.intern ] when / A d+. d+/ @q.push [:NUMBER, $&.to_f] RESERVED = 'if' => :IF, 'else' => :ELSE, 'while' => :WHILE, 'then' => :THEN, 'do' => :DO, 'def' => :DEF, 'true' => :TRUE, 'false' => :FALSE, 'nil' => :NIL, '' => :END RESERVED_V = 'true' => true, 'false' => false, 'nil' => nil しかし 失敗? 代入式が書けるようにすると 結果が思わしくない if val[1]!=0 then result=val[3] else result=nil if val[1]!=0 then result=val[3] else result=val[5] a=0 if a then b=1 else b=2 print( "b= ", b," n") b= 2 a=1 if a then b=1 else b=2 print( "b= ", b," n") b= 2

代入式を書けるようにする 式として 代入式も認める right '^' nonassoc UMINUS left '*' '/' left '+' '-' right '=' rule target: exp assign /* none */ result = 0 exp: exp '+' exp result += val[2] exp '-' exp result -= val[2] assign assign : IDENT '=' exp result = do_assign( val[0], val[2] ) この現象が起こることを確認してください 思わしくない理由 "then" 部分も "else" 部分も 必ず 構文解析を行い構文解析に成功すれば 意味解析 ( インタープリターでは 実行 ) もしてしまう if 全体の値は正しいのだが 副作用がある部分 ( 代入!) はおかしくなる また 効率が悪い ( 計算する必要のない計算を行ってしまう ) if val[1]!=0 then result=val[3] else result=nil if val[1]!=0 then result=val[3] else result=val[5] レポート課題 6 calc.y つまり電卓形式のプログラムでは ループ (while ループ for ループ until ループ他 ) を実装することは難しい理由を説明して下さい レポート課題 7 練習問題 6 intp.y を動かしてみてください そして次の確認と改善をして下さい コマンドラインからファイル名を読むようにして下さい if then else の構文が複数行に渡ることを強制しています 一行内に書いてもよいようにして下さい ( 山勘を働かせて ) べき乗 (^) を導入してください 注意 : FuncallNode.new を呼ぶときの べき乗の関数名は ^ ではなく ** です ファイルの読み込み begin tree = nil if ARGV.length>=1 then fname = ARGV[0] 変更です else fname = 'src.intp' File.open(fname) f tree = Intp::Parser.new.parse(f, fname) tree.evaluate rescue Racc::ParseError, Intp::IntpError, Errno::ENOENT raise #### $stderr.puts "#File.basename $0: #$!" exit 1 べき乗 expr: expr '^' expr result = FuncallNode.new(@fname, val[0].lineno, '**', [val[0], val[2]]) nonassoc UMINUS right '^' left '*' '/' left '+' '-' nonassoc EQ

If-then-else-: 失敗ではないが if_stmt : IF stmt THEN EOL stmt_list else_stmt END val[1], val[4], val[5] ) IF stmt THEN stmt_list else_stmt END 追加した val[1], val[3], val[4] ) shift/reduce conflict がたくさん出る というのは stmt_list から EOL stmt EOL という形が導出され 追加した部分からも もとからある部分からも 同じものが生成されうる すなわち 曖昧な文法になっているからである stmt_list : result = [] stmt_list stmt EOL result.push val[1] stmt_list EOL If-then-else-: 失敗ではないが else_stmt : ELSE EOL stmt_list result = val[2] result = nil ELSE stmt_list 追加した result = val[1] shift/reduce conflict がたくさん出る というのは stmt_list から EOL stmt EOL という形が導出される すなわち 曖昧な文法になっているからである If-then-else- つまり 逆に ( つまり この問題の原因を逆手にとり ) stmt_list が空文を許すように定義されているため if_stmt と else_stmt で EOL を落とすだけでよい! これで万事解決かというと そうでもない : if then a=1 else というように else の左側に (EOL なしに ) 文を書くことはできない これは stmt_list の定義によると stmt_list の最後は必ず EOL でなければならないからである つまり a=1 else などとするには stmt_list の定義を書き換えて 最後に EOL が来る必要をなくせばよい if_stmt : IF stmt THEN stmt_list else_stmt END val[1], val[3], val[4] ) else_stmt : ELSE stmt_list result = val[1] result = nil stmt_list : result = [] stmt result=[val[0]] stmt_list EOL stmt result.push val[2] stmt_list EOL