2013-01-03 29 views
1

我想在代碼扔 此前後添加捕獲異常的機制,但我不能讓它編譯:未能趕上SML一個例外,由於語法錯誤

這裏的無一例外處理代碼 - 它編譯偉大工程:

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 

-

我嘗試添加/刪除分號在錯誤建議,但沒有奏效。

任何想法有什麼不對?

親切的問候

+0

我會強烈建議您不要使用引用。使用它們並不會帶來什麼好處,並且您將失去進行函數式編程的全部意義! –

回答

3

看來你已經missunderstod如何序列(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 :: = ... | exphandlematch | ...

因此,句柄的左側必須是表達式。你已經把它作爲一個序列的最後一部分(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 

還記得減去一個是在SML ~1


正如我在對您的問題的評論中指出的那樣,您在進行函數式編程時應該停止使用引用。如果你需要使用它們,那麼你幾乎總是做錯了。

如果你一直保持它的功能,那麼代碼本來就這麼簡單:

fun calc1 input = (calcMyRomanExpression o replaceRomanDec) input 

或者也可以簡單

val calc2 = calcMyRomanExpression o replaceRomanDec 
+1

另外,'輸入'周圍不需要括號' – newacct

+0

我假定你的意思是'replaceRomanDec'函數。無論如何,我已經更新。 –