由于语法错误而未能在SML中捕获异常

时间:2013-01-03 20:12:38

标签: exception sml smlnj

我正在尝试添加捕获异常后捕获异常的机制 以前在代码中,但我无法编译:

这是没有异常处理的代码 - 它编译并且工作得很好:

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;

但是当我尝试将handleexception放在此处时:

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

-

我尝试按照错误中的建议添加/删除分号,但没有任何效果。

知道什么是错的吗?

亲切的问候

1 个答案:

答案 0 :(得分: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 处理 匹配 | ...

因此,句柄的左侧,必须是表达式。您已将其作为序列的最后一部分(exp_1; expr_2; expr_3):

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

从我们看到没有提供句柄左侧的表达式。因此,您会收到语法错误。

由于异常处理的结果是-1,我假设是calcMyRomanExpression抛出CalculatorParser异常。因此,解决方案可以是:

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

还要记住,在SML中减去一个是~1


正如我在对您的问题的评论中所指出的,在进行函数式编程时,您确实应该停止使用引用。如果你需要使用它们,那么你几乎总是做错了。

如果你保持它的功能,那么代码就可以这么简单:

fun calc1 input = (calcMyRomanExpression o replaceRomanDec) input

甚至更简单

val calc2 = calcMyRomanExpression o replaceRomanDec