スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#で入門 コンパイラ 、インタプリタ編 LR(1)のクラス化

 LL(1)でもやったように、LR(1)構文解釈器をクラス化して、トークンの定義と文法を与えておけば、ソースから具象抽象木を自動生成できるようにしたいと思います。 
 
コードはあとでのっけることにして、まずはシグネチャーを示します。 
 
作られる具象抽象木の型は次の通り 
type embodyST = 
  | Leaf of Token 
  | Node of (int * string * embodyST list) 
  with 
    member dispStr : inc:int -> string 
  end 
 
構文解釈するクラスの型は次の通りです。 
type LR1TokenizeAndParse = 
  class 
    new : inDefLst:(string * string) list * inStrLst:string list -> 
            LR1TokenizeAndParse 
    member GetEBASTtree : sourceLst:string list -> embodyST 
    member GetNntnSetAdnTnSet : unit -> Set<string> * Set<string> 
    member GetTokens : sourceLst:string list -> Token list 
 
次の様に使います。 
(この文法は0以上の数の、四則演算表現(括弧の使用は可)を処理する文法です。) 
 
トークン化ルールをtnR1に束縛しておきます。 
> let tnR1 = 
   [("RPAR","\("); 
    ("LPAR","\)"); 
    ("ADD","\+"); 
    ("SUB","\-"); 
    ("MUL","\*"); 
    ("DIV","\/"); 
    ("NUM","0|[1-9][0-9]*"); 
    ];; 
 
val tnR1 : (string * string) list = 
  [("RPAR", "\("); ("LPAR", "\)"); ("ADD", "\+"); ("SUB", "\-"); ("MUL", "\*"); 
   ("DIV", "\/"); ("NUM", "0|[1-9][0-9]*")] 
 
文法ルールをgrammersStrLst1に束縛しておきます。 
> let grammersStrLst1 = 
   ["1:Program = Exp";  
    "2:Exp =  Term"; 
    "3:Exp = Term ADD Term"; 
    "4:Exp = Term SUB Term"; 
    "5:Term = Fact"; 
    "6:Term = Fact MUL Fact"; 
    "7:Term = Fact DIV Fact"; 
    "8:Fact = NUM"; 
    "9:Fact = RPAR Exp LPAR"];; 
 
val grammersStrLst1 : string list = 
  ["1:Program = Exp"; "2:Exp =  Term"; "3:Exp = Term ADD Term"; 
   "4:Exp = Term SUB Term"; "5:Term = Fact"; "6:Term = Fact MUL Fact"; 
   "7:Term = Fact DIV Fact"; "8:Fact = NUM"; "9:Fact = RPAR Exp LPAR"] 
 
インスタンスを生成します。 
 
let tp1 = new LR1TokenizeAndParse (tnR1,grammersStrLst1) 
 
> let tp1 = new LR1TokenizeAndParse (tnR1,grammersStrLst1);; 
 
val tp1 : LR1TokenizeAndParse 
 
ではソースコードを何種類か解釈させて、具象構文木を求めてみます。 
 
例1 
"3"の解釈 
 
> tp1.GetEBASTtree([" 3 "]).dispStr 4;; 
 
val it : string = 
  "    (1)1:Program = Exp 
        (2)2:Exp =  Term 
            (5)5:Term = Fact 
                (8)8:Fact = NUM 
                    [NUM 3 (1,2)]  
 
例2 
"1 - 2"の解釈 
> tp1.GetEBASTtree([" 1 -  2 "]).dispStr 4;; 
 
val it : string = 
  "    (1)1:Program = Exp 
        (4)4:Exp = Term SUB Term 
            (5)5:Term = Fact 
                (8)8:Fact = NUM 
                    [NUM 1 (1,2)]  
            [SUB - (1,4)]  
            (5)5:Term = Fact 
                (8)8:Fact = NUM 
                    [NUM 2 (1,7)]  
 
例2 
"3 * ( 6 / 2)"の解釈 
 
> tp1.GetEBASTtree(["3 * ( 6 / 2)"]).dispStr 4;; 
val it : string = 
  "    (1)1:Program = Exp 
        (2)2:Exp =  Term 
            (6)6:Term = Fact MUL Fact 
                (8)8:Fact = NUM 
                    [NUM 3 (1,1)]  
                [MUL * (1,3)]  
                (9)9:Fact = RPAR Exp LPAR 
                    [RPAR ( (1,5)]  
                    (2)2:Exp =  Term 
                        (7)7:Term = Fact DIV Fact 
                            (8)8:Fact = NUM 
                                [NUM 6 (1,7)]  
                            [DIV / (1,9)]  
                            (8)8:Fact = NUM 
                                [NUM 2 (1,11)]  
                    [LPAR ) (1,12)]  
 
では、このクラスのコードをのっけておきます。 
このクラスは今後ずっと使っていきたいと考えています。(今後も毎回ソースは省略せずにのっける予定なので、毎回同じコード(このクラスの定義部分)が最初にくると思います。 
では、コードは以下の通りです。 

続きを読む

スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。