解析器中的OCaml语法错误

时间:2015-10-07 07:15:00

标签: ocaml ocamllex

有人可以帮我解释为什么我在这一行有语法错误: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;;

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

3 个答案:

答案 0 :(得分:2)

声明如下:

let v = expr

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

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

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

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

let v = expr1 in expr2

我不清楚你想要哪些名字是全球性的。但解决问题的一种方法是删除第一个in。然后,您将拥有三个全局名称lexbufwordlistwordMap

另一种方法是在in的定义之后添加wordlist。那你就没有全球名字了。

答案 1 :(得分:0)

您的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

函数main返回wordList作为结果。

答案 2 :(得分:0)

这种麻烦的黄金法则:使用适当的缩进工具,caml-mode,tuareg-mode或ocp-indent。如果这些工具显示的缩进与您的意图不同,通常会出现语法错误。