超出程序结束的语法错误

时间:2010-03-24 12:57:24

标签: ocaml

我正在尝试用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

有人可以帮我弄清楚错误是由什么引起的,并帮助我修复它吗?

2 个答案:

答案 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