• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0
                有的時候,IO的異常處理由于需要一個IOEnv類型的參數而顯得非常麻煩。這個時候我們可以定制自己的一套異常處理系統,從而讓程序變得清晰起來。自己的異常處理系統不同于IO,是沒有副作用的函數集合。下面讓我們看一看如何使用自定義的異常處理系統來分析一個四則運算表達式。

                首先,為了使用do-end,我們需要定義一套共4個函數:
             1 type Parser T = maybe T (pair string (list token))
             2 func parsed T :: T -> Parser T
             3 def parsed x = success x
             4 func error T :: (pair string (list token)) -> Parser T
             5 def error x = fail x
             6 func (>>>) T1 T2 :: Parser T1 -> Parser T2 -> Parser T2
             7 def (>>>) a b = a >>= \p->b
             8 func (>>=) T1 T2:: Parser T1 -> (T1 -> Parser T2) -> Parser T2
             9 def (>>=) a b = select a of
            10   case fail x : fail x
            11   case success x : b x
            12 end

                加上類型的原因是,異常處理系統需要對類型進行嚴格的約束,但是我們的代碼產生的類型比期望的類型更加寬松。現在使用我們已經熟悉到無法再熟悉、連方法都可以倒著背出來、代碼都能夠倒著寫的遞歸下降法進行分析:
             1 def getfactor tokens = do
             2   select head tokens of
             3     case t_num x : parsed (pair x (tail tokens))
             4     case t_leftbrace : do
             5       expression = getexp (tail tokens);
             6       select expression of
             7         case pair value remains :
             8           if(token_startwith t_rightbrace remains)
             9             (parsed (pair value (tail remains)))
            10             (error (pair "此處需要右括號" remains))
            11       end;
            12     end
            13     else : error (pair "此處需要表達式" tokens)
            14   end;
            15 end
            16 
            17 def getterm tokens =
            18   let
            19     def _getterm current tokens ismul = do
            20       factor = getfactor tokens;
            21       value = parsed (pairfirst factor);
            22       remains = parsed (pairsecond factor);
            23       new_current = parsed (if ismul (fmul current value) (fdiv current value));
            24       if (isempty remains)
            25         (parsed (pair new_current remains))
            26         select head remains of
            27           case t_mul : _getterm new_current (tail remains) true
            28           case t_div : _getterm new_current (tail remains) false
            29           else : parsed (pair new_current remains)
            30         end;
            31     end
            32   in _getterm 1.0 tokens true
            33 
            34 def getexp tokens =
            35   let
            36     def _getexp current tokens isadd = do
            37       term = getterm tokens;
            38       value = parsed (pairfirst term);
            39       remains = parsed (pairsecond term);
            40       new_current = parsed (if isadd (fadd current value) (fsub current value));
            41       if (isempty remains)
            42         (parsed (pair new_current remains))
            43         select head remains of
            44           case t_add : _getexp new_current (tail remains) true
            45           case t_sub : _getexp new_current (tail remains) false
            46           else : parsed (pair new_current remains)
            47         end;
            48     end
            49   in _getexp 0.0 tokens true

                上面的三個函數接受的是list token。token及相關函數的定義如下:
             1 data token
             2   = t_leftbrace
             3   | t_rightbrace
             4   | t_add
             5   | t_sub
             6   | t_mul
             7   | t_div
             8   | t_num float
             9 
            10 data token_stream = token_stream (list token) string
            11 
            12 def token_getnum input =
            13   let
            14     def _getnum output input =
            15       select input of
            16         case list x tail : if (and (cegt x '0') (celt x '9')) (_getnum (list x output) tail) (pair output input)
            17         case empty : pair output input
            18       end
            19   in select _getnum "" input of
            20     case pair output input : pair (reverse output) input
            21   end
            22 
            23 def token_atof input = select atof input of
            24   case success number : number
            25 end
            26 
            27 def token_split input =
            28   let
            29     def _split stream = select stream of
            30       case token_stream tokens remain : select remain of
            31         case empty : stream
            32         case list '(' tail : _split (token_stream (list t_leftbrace tokens) tail)
            33         case list ')' tail : _split (token_stream (list t_rightbrace tokens) tail)
            34         case list '+' tail : _split (token_stream (list t_add tokens) tail)
            35         case list '-' tail : _split (token_stream (list t_sub tokens) tail)
            36         case list '*' tail : _split (token_stream (list t_mul tokens) tail)
            37         case list '/' tail : _split (token_stream (list t_div tokens) tail)
            38         else : select token_getnum remain of
            39           case pair num tail : select num of
            40             case empty : stream
            41             case list x xs : _split (token_stream (list (t_num (token_atof num)) tokens) tail)
            42           end
            43         end
            44       end
            45     end
            46   in select _split (token_stream empty input) of
            47     case token_stream tokens remain : token_stream (reverse tokens) remain
            48   end
            49 
            50 def token_toint token = select token of
            51   case t_leftbrace : 0
            52   case t_rightbrace : 1
            53   case t_add : 2
            54   case t_sub : 3
            55   case t_mul : 4
            56   case t_div : 5
            57   case t_num x : 6
            58 end
            59 
            60 def token_startwith token tokens = select tokens of
            61   case empty : false
            62   case list first remains : iequ (token_toint token) (token_toint first)
            63 end

                我們可以開始寫main函數了:
            1 def main127 =select token_split "(1+2)*(3+4)" of
            2     case token_stream tokens remains : getexp tokens
            3   end

                程序完成,看一下運行結果:
            1 main127返回值:(system.success (system.pair 21.0 ""))
            posted on 2008-12-18 21:23 陳梓瀚(vczh) 閱讀(1448) 評論(0)  編輯 收藏 引用 所屬分類: 腳本技術
            香蕉99久久国产综合精品宅男自| 国产精品久久久天天影视| 精品久久人人妻人人做精品 | 久久午夜无码鲁丝片午夜精品| 久久九九免费高清视频| 亚洲精品NV久久久久久久久久| 精产国品久久一二三产区区别| 久久久久久夜精品精品免费啦| 国产AⅤ精品一区二区三区久久| 欧美性大战久久久久久| 亚洲国产精品无码久久久秋霞2| 亚洲伊人久久大香线蕉苏妲己 | 久久婷婷五月综合国产尤物app| 久久精品男人影院| 99久久综合国产精品免费| 精品久久久久久综合日本| 无码人妻少妇久久中文字幕| 精品一区二区久久| 久久伊人五月丁香狠狠色| 91久久成人免费| 久久99国产亚洲高清观看首页| 亚洲国产成人久久综合野外| 久久精品www| 久久一日本道色综合久久| 久久婷婷午色综合夜啪| 久久久91精品国产一区二区三区 | AV狠狠色丁香婷婷综合久久| 无码国内精品久久综合88 | 久久精品无码免费不卡| 久久这里只精品国产99热| 久久精品无码专区免费青青| 久久久亚洲裙底偷窥综合| 香蕉99久久国产综合精品宅男自| 久久精品免费一区二区三区| 久久婷婷五月综合97色| 欧美噜噜久久久XXX| 久久久久亚洲AV无码专区体验| A级毛片无码久久精品免费 | 久久性精品| 久久亚洲熟女cc98cm| 伊人久久久AV老熟妇色|