1

コードで以前にスローした後に例外をキャッチするメカニズムを追加しようとしていますが、コンパイルできません:

例外処理なしのコードは次のとおりです-コンパイルしてうまく機能します:

fun calc(input : string ) : int = 


    let 
        val outStr = ref "someString"
        val outInt = ref 0

    in 
        (
            outStr := replaceRomanDec(input);       (* replace roman number with decimal *)
            outInt := calcMyRomanExpression(!outStr)    

        );

        (!outInt)

    end;

handleしかし、ここにandを入れようとするとexception :

fun calc(input : string ) : int = 

    exception CalculatorParser

    let 
        val outStr = ref "someString"
        val outInt = ref 0

    in 
        (
            outStr := replaceRomanDec(input);       (* replace roman number with decimal *)
            outInt := calcMyRomanExpression(!outStr);
            handle CalculatorParser =>  -1
        );

        (!outInt)



    end;

私は得る:

stdIn:1761.2-1761.28 Error: syntax error: deleting  EXCEPTION ID
-               );
=
=               (!outInt)
=
=
=
=       end;
stdIn:1576.1-1757.2 Error: syntax error: deleting  RPAREN SEMICOLON

-

エラーで提案されているようにセミコロンを追加/削除しようとしましたが、何も機能しませんでした。

何が問題なのですか?

敬具

4

1 に答える 1

3

式のシーケンス (expr_1; expr_2; ...; expr_n) がどのように機能するかを誤解しているようです。

まず、別のシーケンスで使用するためだけに、最初に outStr と outInt を独自のシーケンスで「グループ化」する必要はありません。

第二に、ローカル宣言 (let) の一部でシーケンスを囲む括弧は必要ありませんin ... end。それを処理するための派生形式 (構文糖衣) があるからです。

また、「逆参照」の前後に括弧を追加する必要はありません。

したがって、簡略化されたバージョンは次のようになります。

fun calc (input : string ) : int =
    let
      val outStr = ref "someString"
      val outInt = ref 0
    in
      outStr := replaceRomanDec input;       (* replace roman number with decimal *)
      outInt := calcMyRomanExpression (!outStr);
      !outInt
    end

ハンドルの文法は次のとおりです。

::= ... | exp ハンドル 一致| ...

したがって、ハンドルの左側は式でなければなりません。シーケンスの最後の部分として配置しました (exp_1 ; expr_2; expr_3):

expr_1   =>   outStr := replaceRomanDec(input);
expr_2   =>   outInt := calcMyRomanExpression(!outStr);
expr_3   =>   handle CalculatorParser => -1

から、ハンドルの左側に式が指定されていないことがわかります。したがって、構文エラーが発生します。

例外処理の結果が -1 であるため、CalculatorParser 例外をスローするのは calcMyRomanExpression であると想定します。したがって、解決策は次のようになります。

fun calc(input : string ) : int =
    let
      val outStr = ref "someString"
      val outInt = ref 0
    in
      outStr := replaceRomanDec(input);       (* replace roman number with decimal *)
      outInt := (calcMyRomanExpression(!outStr) handle CalculatorParser => ~1);
      !outInt
    end

~1また、マイナス 1 はSML にあることも覚えておいてください。


あなたの質問へのコメントで指摘したように、関数型プログラミングを行うときは参照の使用をやめるべきです。それらを使用する必要がある場合、ほとんどの場合、間違っています。

機能を維持していれば、コードは次のように単純になった可能性があります。

fun calc1 input = (calcMyRomanExpression o replaceRomanDec) input

またはさらに単純な

val calc2 = calcMyRomanExpression o replaceRomanDec
于 2013-01-03T22:56:21.850 に答える