【问题标题】:Failing to catch an exception in SML due to syntax error由于语法错误,未能在 SML 中捕获异常
【发布时间】:2012-12-18 06:16:19
【问题描述】:

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

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

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

-

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

知道有什么问题吗?

亲切的问候

【问题讨论】:

  • 我强烈建议您不要使用引用。使用它们不会带来任何好处,而且你会失去进行函数式编程的全部意义!

标签: exception sml smlnj


【解决方案1】:

您似乎误解了表达式序列 (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

【讨论】:

  • 另外,input 周围不需要括号
  • 我假设您的意思是 replaceRomanDec 函数。无论如何,我已经更新了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多