解析器中的 OCaml 语法错误

OCaml Syntax Error in Parser

谁能帮我解释一下为什么我在这一行有语法错误:let wordMap = StringMap.empty?这包含在 .mll 文件中。上面定义了模块StringMap。

let lexbuf = Lexing.from_channel stdin in
    let wordlist =
        let rec next l = match token lexbuf with
            EOF -> l
            | Word(s) -> next (s :: l)
        in next []

    let wordMap = StringMap.empty in 
        let wcList  = StringMap.fold (fun word count l -> (string_of_int count ^ " " ^ word) :: l) wordMap [] in 

        List.iter print_endline wcList;;

我知道它什么都不打印,这只是为了测试。

像这样的声明:

let v = expr

只能出现在模块的最外层。这是声明模块全局名称的方式。

但是你在表达式中有这样一个声明(wordlist):

let lexbuf = ... in
let wordlist = ...

在模块外层以外的所有地方,let 后面必须跟in。这是声明局部变量的方法(在任何表达式中)。

let v = expr1 in expr2

我不清楚您希望哪个名称成为全球名称。但解决问题的一种方法是删除第一个 in。那么您将拥有三个全局名称,lexbufwordlistwordMap.

另一种方法是在 wordlist 的定义之后添加 in。那么你将没有全局名称。

您的 let-bindings 有问题。如果我按如下方式重写你的代码,这应该可以工作:

    let main () =
      let lexbuf = Lexing.from_channel stdin in
      let wordlist =
         let rec next l = match token lexbuf with
            EOF -> l
          | Word s -> next (s :: l) in
         next [] 
      in
     wordlist

   let wordMap = StringMap.empty

函数mainreturnwordList作为结果。

解决此类问题的黄金法则:使用合适的缩进工具、caml-mode、tuareg-mode 或 ocp-indent。如果这些工具显示的缩进与您的意图不同,则通常是您犯了语法错误。