compiler-errors - 基本 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 将大写字母转换为小写字母。
我想了解我在编写代码时在哪里犯了错误!提前致谢。
解决方案
它无法编译,因为您的代码在语法上不是有效的 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
推荐阅读
- c++ - C++20 std::ranges::sort 是否不需要支持 std::vector
? - python - 使用特定字符串的近似 URL 抓取多个网站
- powerbi - 该表达式引用多个列。不能将多列转换为标量值
- javascript - Blazor 服务器端 - _Host.cshtml 中 js 文件引用的位置
- python - 如何使用机器人框架单击三个 div 标签内的按钮
- sql - 将 MSI 属性传递给 sqlstring
- ansible - 在ansible playbook中指定库存文件路径
- python - python中两个字符串之间的匹配模式
- powerbi - 将 Hotjar 连接到 PowerBI 作为数据源
- javascript - 为什么这个 javascript 片段记录 1?