我正在尝试用ocaml编写一个玩具编译器。目前,我正在尝试为我的词法分析器实现offside rule。但是,我在使用ocaml语法时遇到了一些麻烦(编译器错误非常缺乏信息)。下面的代码(33行)导致第34行出错,超出了源代码的末尾。我不确定是什么导致了这个错误。
open Printf
let s = (Stack.create():int Stack.t);
let rec check x =
(
if Stack.is_empty s then
Stack.push x s
else if Stack.top s < x then
(
Stack.push x s;
printf "INDENT\n";
)
else if Stack.top s > x then
(
printf "DEDENT\n";
Stack.pop s;
check x;
)
else
printf "MATCHED\n";
);
let main () =
(
check 0;
check 4;
check 6;
check 8;
check 5;
);
let _ = Printexc.print main ()
Ocaml输出:
File "lexer.ml", line 34, characters 0-0:
Error: Syntax error
有人可以帮我弄清楚错误是由什么引起的,并帮助我修复它吗?
答案 0 :(得分:10)
main , check 和 s 的定义之后的尾随; 是错误的。
将这三个出现用 ;; 替换如下:
let s = (Stack.create():int Stack.t);;
let rec check x =
(
(* ...sequence of imperative statements... *)
);;
let main () =
(
(* ...sequence of imperative statements... *)
);;
; 用于以下情况:
一些例子:
let hello_world1 () =
print_endline "Hello";
print_endline "World !"
;;
let hello_world2 () =
begin
print_endline "Hello";
print_endline "World !"
end
;;
let hello_world3 () =
(
print_endline "Hello";
print_endline "World !";
)
;;
let some_list =
[1; 2; 3]
;;
let some_array =
[| 'a'; 'b'; 'c' |]
;;
type my_process =
{
pid: int;
executable_path: string;
}
;;
let p1 = { pid = 142; executable_path = "./my_exec" };;
答案 1 :(得分:2)
只需移除;
即可:
open Printf
let (s:int Stack.t) = Stack.create()
let rec check x =
(
if Stack.is_empty s then
Stack.push x s
else if Stack.top s < x then
(
Stack.push x s;
printf "INDENT\n";
)
else if Stack.top s > x then
(
printf "DEDENT\n";
Stack.pop s;
check x;
)
else
printf "MATCHED\n";
)
let main () =
(
check 0;
check 4;
check 6;
check 8;
check 5;
)
let _ =
Printexc.print main ()
运行它:
gaius@debian:~/Projects/TestCase$ ./lexer
INDENT
INDENT
INDENT
DEDENT
DEDENT
INDENT