首页 > 解决方案 > 基本 ocaml 程序未编译

问题描述

我试图编写一段代码来检查一个句子是否是回文(如果我们不考虑空格和大小写),但我的代码无法编译。我收到以下错误:

File "main.ml", line 12, characters 0-2:
Error: Syntax error

此错误对应于第二个程序,第 12 行是 ;; 处于。

整个节目

let scan_word () = Scanf.scanf " %s" (fun x -> x)
in
let scan_int () = Scanf.scanf " %d" (fun x -> x)
in
let scan_float () = Scanf.scanf " %f" (fun x -> x)
in
let scan_char () = Scanf.scanf " %c" (fun x -> x)
in
let maj_to_min = function
    | c when (c >= 'a' && c <= 'z') -> c
    | c -> (char_of_int ( (int_of_char c) - (int_of_char 'A') + (int_of_char 'a')))
in

let convert_string s = 
    let n = String.length s in
    let cur = ref 0 in
    let arr = Array.make n ' ';
    for i = 0 to (n-1)
    do
        if s.[i] <> ' ' 
        then begin
            arr.(!cur) <- maj_to_min s.[i];
            incr cur;
        end;
    done;
    (Array.sub arr 0 cur)
in

let is_palindrome arr =
    let n = Array.length arr in
    let ans = ref true in

    for i = 0 to (n-1)
    do
        ans := (!ans) && (arr.(i) = arr.(n-1-i));
    done;
    !ans
in

let n = read_int () in

for i = 1 to n
do
    let s = read_line () in 
    if (is_palindrome (convert_string s)) = true  then print_endline s
done;;

无法编译的最小程序:

let scan_word () = Scanf.scanf " %s" (fun x -> x)
in
let scan_int () = Scanf.scanf " %d" (fun x -> x)
in
let scan_float () = Scanf.scanf " %f" (fun x -> x)
in
let scan_char () = Scanf.scanf " %c" (fun x -> x)
in
let maj_to_min = function
    | c when (c >= 'a' && c <= 'z') -> c
    | c -> (char_of_int ( (int_of_char c) - (int_of_char 'A') + (int_of_char 'a')))
;;

maj_to_min 将大写字母转换为小写字母。
我想了解我在编写代码时在哪里犯了错误!提前致谢。

标签: compiler-errorsocaml

解决方案


它无法编译,因为您的代码在语法上不是有效的 OCaml。

OCaml 程序是一系列值、类型、模块和其他定义。您的特定示例正在尝试定义多个值。OCaml 中的值定义具有以下语法

let <name> = <value> 

请注意,没有in部分。所以正确的(至少在语法上)程序看起来像这样

let scan_word () = Scanf.scanf " %s" (fun x -> x)
let scan_int () = Scanf.scanf " %d" (fun x -> x)
let scan_float () = Scanf.scanf " %f" (fun x -> x)
let scan_char () = Scanf.scanf " %c" (fun x -> x)
let maj_to_min = function
    | c when (c >= 'a' && c <= 'z') -> c
    | c -> (char_of_int ( (int_of_char c) - (int_of_char 'A') + (int_of_char 'a')))

该程序将定义 5 个函数。两者都不会被调用,因此您可能希望添加一个将调用它的定义。

let <name> = <expr-1> in <expr-2>和之间的主要区别在于let <name> = <expr>后者是发生在程序/模块顶层的值定义。它最接近于其他语言中的什么是命名语句。前者,我的意思是let <name> = <expr-1> in <expr-2>是一个表达式,它可以出现在任何需要表达式的地方。通常它用于构建复杂的表达式。例如,

let input_user () = 
    let name = scan_word () in
    let age = scan_int () in
    let weight = scan_float () in
    let gender = scan_char () in
    printf "%s is %d years old, weights %g pounds, and has gender %c\n"
       name age weight gender

现在要让您的二进制文件执行您可以调用此函数的操作,请将以下值定义添加到程序的顶层,例如,

   let () = input_user ()

这将作为程序的入口点。

更详细地说,这是一个 OCaml 程序的一般结构:

(* this is the top-level of your file, each file defines a module 
   which has the name equal to the file name (but capitalized), 
   let's imagine that our file is named example.ml therefore it 
   defines a module named Example
 *)


(* this is a top-level constant that is visible to all code that is below 
    it. You can also access it from other files as `Example.version`.
 *)
let version = "0.0.1"


(* this is a mutable reference, the closest to the mutable and global 
   variable in C *)
let calls = ref 0

(* this is a simple function with two imperative expressions, which uses 
   values defined above *)
let make_a_call () = 
    incr calls;
    Printf.printf "we made %d calls so far in version %s\n" !calls version


(* this is a function, that defines local variables `d` and `e` and
   uses them. These variables are seen only in the body of this 
   function. More generally `let <v> = <e> in <body>` evaluates `<e>`
   binds it to `<v>` and makes `<v>` visible in the scope of `<body>` *)
let complex_function x y = 
   let d = x + y - 1 in
   let e = x * y + 2 in
   (d + e) / (x + y)


(* we can even define function inside other functions, the 
   same as with `d` and `e` above, the `inner_function` is only 
   visible inside the `complex_function_with_functions` *)
let complex_function_with_functions x = 
   let inner_function y = 
      x + y in
   inner_function 5 + inner_function 6 


(* this is the main function. The name doesn't matter at all, well at
   least to OCaml. But it is usually a good idea to have one at least
   to cherish others who will be reading your code. This function
   demonstrates how you can interleave imperative expressions with
   `let` bindings` *)
let main () = 
   make_a_call ();
   let r = complex_function_with_functions 12 in
   make_a_call ();
   let p = complex_function r 16 in 
   make_a_call ();
   Printf.printf "wow: we get %d and %d, don't know what it means\n" r p


(* finally, let's call the main function to actually run our program *)

let () = main ()

一个专业提示,你真的不需要编译这个文件来运行它,因为 OCaml 有一个解释器,所以如果你把这个代码放在名为的文件中,example.ml那么它就像,

$ ocaml example.ml 
we made 1 calls so far in version 0.0.1
we made 2 calls so far in version 0.0.1
we made 3 calls so far in version 0.0.1
wow: we get 35 and 12, don't know what it means

推荐阅读