Синтаксическая ошибка за пределами программы - PullRequest
4 голосов
/ 24 марта 2010

Я экспериментирую с написанием игрушечного компилятора в ocaml. В настоящее время я пытаюсь реализовать правило офсайда для моего лексера. Однако у меня возникли некоторые проблемы с синтаксисом 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 ]

10 голосов
/ 24 марта 2010

Трейлинг ; после определений main , check и s ошибочны.

Заменить эти 3 случая на ;; следующим образом:

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" };;
2 голосов
/ 21 сентября 2010

Просто удаление ; работ:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...