2016/07/30 13:00- CC-semi [状況確認] !! 初回に配布したプログラムがに全然觝れていない !! -> 主題なのに後回し !! -> 寄り道すぎて、遅れている 個人的には、 まずは、美味しい思いをしてから、苦労する # ショートケーキは、苺から 苦労しとかないと、ありがた味が判らない # 西瓜に塩 早いとこ、初回のファイルの話をしたいと*は*思っている [前回] 「式」言語をやった 「言語」なので、「構文(Synatax)」と「意味(Semantics)」を決めて、インタープリターを作成した パーサー : 構文規則を処理する部分を作成 パーサーに意味規則にそって「意味処理」を加えた # 「意味」「意味規則」とは何か ??? # 「意味」は、ようするに「意味集合の要素」 # 例 : 「式」言語では、計算結果の数値(整数) # 「意味処理」 # とりあえずは、「意味集合上の『関数』」として捉える # 例 : '+' -> 「足し算」 # 二つの整数からその「和」計算して、新しい整数を求める関数 # # 「和」って?... # # 将来「メタ関数」も「意味関数」として登場する... パーサーの作り方 ( LL(k) の場合 ) Top-Down パーサーの形で、(ほぼ)自動的に書ける 非終端記号に対応して関数を一つ作る ( (LL(k) : LL(1) なので) 1 文字先読みをする) # 先読みをして、場合によっては元に戻す # ungetc 関数 文法 : 言語(集合)表現の一つ # 言語表現 ( 言語 : 「文」集合 ) # 集合表現 ( 「文」全体の集合 ) # # 「H」言語では { ε, H, HH, HHH, ... } # 受理機械表現 (言語を入力すると、受理か不受理をする..) # 文法表現 ( 「文」の生成規則の集合 ) # # 「H」言語では # # <文> ::= ε| H <文> <文> に相当する文字列を生成する規則の集まり -- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< -- 「式言語[2]」の構文規則 (BNF) <文> ::= ε| <文> <行>'\n /* 複数行に対応 */ <行> ::= <式> ';' | ';' <項> ::= <整数値> | '(' <式> ')' <式> ::= <項> | <項> '+' <項> <整数値> ::= <整数値> <数字> | ε <数字> ::= '0' | '1' | ... | '9' -- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< -- <名前> : 非終端要素 文字集合を表す '文字' : 終端要素 { 文字 } : 一文字からなる集合を表す ε : 空文字列 文法規則 「::=」 左の集合は、右の集合で定義される # 左側は、通常 非終端記号が一つあるだけ # # 自由文脈文法 (Contexit Free Grammer[CFG] Class 2) の場合 # # 「普通」の「プログラミング言語」は CFG + αで実現されている事が多い # 一般には、限定されていない ::= 右側は A B -> A の要素の後に、B の要素がくる A | B -> A の要素、または B の要素 例: 「H」言語 <文> ::= <文> 'H' | ε 文の生成 <文> -> ε (右) => ε は H 言語の文 <文> -> <文> 'H' (左) -> <文> 'H' 'H' (左) -> ε 'H' 'H' (右) => HH は H 言語の文 例2: 簡単英語 <文> ::= <主語> <述語> | <主語> <述語> <目的語> <主語> ::= 'I' | 'You' <述語> ::= 'have' | 'get' <目的語> ::= 'pen' | 'desk' 文の生成 <文> -> <主語> <述語> <目的語> -> 'I' 'have' 'pen' => I have pen : 文 # チョムスキー 「式言語[0] 」-> 「式言語[1] 」 <整数値> が複数桁に変化 「文法」を変更した 式言語[0] -- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< -- <整数値> ::= '0' | '1' | ... | '9' /* 一桁 */ /* 文字が表す、一桁の数 */ -- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< -- 式言語[1/2] -- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< -- <整数値> ::= <整数値> <数字> | ε <数字> ::= '0' | '1' | ... | '9' -- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< -- この様に、言語を変更するには、文法を変更する 「式」言語の立場から考えると.. 「整数値」は一桁か二桁かはどうでも良い 一般に、 構文木の根っこの方は重要かつ数が少ない(パターン化が難しい) 構文木の葉の方は、重要でなく、かつ数が多い(パターン化できる) 例: 根 : if 文 / while 文 / case 文 -> パターン化しにくい 葉 : 予約語、整数、文字列、名前 (C 言語) int, double, for, while, ... 取り敢えず名前と同じ 文字に繰返しというパターン 123, 456, ... 数字の繰返しというパターン "Hello, World", ... " と " の間に "以外の文字の繰返しパターン main, sin, cos, ... 「パターン化しやすい」 # 第 3 言語に分類される # DFA で受理可能な言語 # ::= の右には、 # 終端記号 1 つ # 終端記号 1 つと非終端記号 1 つ # しかでない文法で表現できる(記憶??) # ショートカットは、 # shell script 等で、重要 # 例 : a のコマンドの後に b をしたい # a ; b # 例 : a のコマンドが成功したら b をしたい # a && b # a のコマンドが失敗すると b はしない # 例 : a のコマンドが失敗した場合に b をしたい # a || b # a のコマンドが成功すると b はしない # 例 : test コマンド # test の後の引数で条件判断をする # test -f abc -> abc があると true # eat or die !! # perl # xxx or die; # xxx でエラーがおきると終了