其他答案和頂部的第一條評論都指出了一個誤用的關鍵字begin
。這是一個小問題,但沒有解決安東尼奧問的問題。對於初學者,我不熟悉你使用你的函數的上下文,我只是想告訴你你的程序在基於跟蹤的方法出錯的地方。
首先,我對您的代碼進行一些修改,以使其更具可讀性,而且也更容易找出棧幀裏的東西出了問題:
let separate = fun formula ->
let rec aux = fun counter start_position size ->
match formula.[start_position + size] with
| '(' -> aux (counter + 1) start_position (size + 1)
| ')' -> if (counter - 1) = 0 then (
(Printf.printf "%d %d %d\n" counter start_position size);
(
((Printf.printf "pass1\n"); (String.sub formula (start_position + 1) size))
,
(String.sub formula (size + start_position + 3) ((String.length formula) - (size + start_position + 2)))
)
)
else aux (counter - 1) start_position (size +1)
| _ -> aux counter start_position (size + 1)
in aux 0 (String.index formula '(') 0
;;
separate "&(A)(B)";;
(*
1 1 2
Exception: Invalid_argument "String.sub/Bytes.sub".
Raised at file "pervasives.ml", line 33, characters 25-45
Called from file "string.ml", line 47, characters 2-23
Called from file "//toplevel//", line 10, characters 4-108
Called from file "toplevel/toploop.ml", line 180, characters 17-56
*)
運行它,你會發現那麼觸發無效參數異常的呼叫在aux 1 1 2
的呼叫中。
然後你就可以使用這些代碼來測試爲什麼出錯:
let (counter, start_position, size) = (1,1,2) in
let formula = "&(A)(B)" in
(
(size + start_position + 3)
,
(String.length formula) - (size + start_position + 2)
) ;;
(*
- : int * int = (6, 2)
*)
這就是你怎麼知道爲什麼String.sub
不接受你的論點:
String.sub "&(A)(B)" 6 2;;
(* Exception: Invalid_argument "String.sub/Bytes.sub".
Called from file "toplevel/toploop.ml", line 180, characters 17-56 *)
這是遠因爲我可以幫助你。在OCaml中調試需要時間,但它是可行的。回到良好的印刷技巧。 我希望這是足夠的信息,讓你明白爲什麼你的邏輯在這裏有問題。我希望你能根據你的問題背景找出解決問題的方法。
由於'begin'是OCaml中的關鍵字,因此您在此給出的代碼在語法上不是有效的。你應該給出一個簡短的,自包含的,有效的例子來說明你的問題。作爲一般觀察,'String.sub'需要第一個int參數爲> = 0且<=字符串的長度,它要求第二個int> = 0,並且它要求和爲<=字符串的長度。 –