2015-10-07 3 views
0

Может кто-нибудь помочь мне объяснить, почему у меня есть синтаксическая ошибка на этой строке: let wordMap = StringMap.empty? Это содержится в файле .mll. Модуль StringMap определен выше.Ошибка синтаксиса OCaml в Parser

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;; 

Я знаю, что это ничего не печатает, это просто для тестирования.

ответ

2

Объявление типа:

let v = expr 

могут появляться только на внешнем уровне модуля. Это способ объявить глобальные имена модуля.

Но у вас есть такое заявление (о wordlist) внутри выражения:

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

Во всех отличных от уровня внешнего модуля мест, let должен сопровождаться in. Это способ объявить локальную переменную (в любом выражении).

let v = expr1 in expr2 

Я не знаю, из каких имен вы хотите быть глобальными. Но одним из способов решения проблемы было бы удалить первые in. Тогда у вас будет три глобальных имени, lexbuf, wordlist и wordMap.

Другим способом было бы добавить in после определения wordlist. Тогда у вас не будет глобальных имен.

+0

Я не включил свой полный код. На самом деле у меня есть после слова Word, но я не был уверен, что это было необходимо. Пожалуйста, проверьте код, который я изменил, он все равно дает мне синтаксическую ошибку! – jstnchng

+0

Вам также нужно 'in' после' wordlist'. Не только после 'wordMap'. –

+0

Я пробовал это раньше, и это сработало, просто хотелось посмотреть, есть ли альтернативы/понять причину синтаксической ошибки. Еще раз спасибо Джеффри. – jstnchng

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 как результат.

0

Золотое правило для такого рода проблем: используйте надлежащий инструмент отступов, режим caml, режим tuareg или opp-indent. Если эти инструменты показывают отступ, отличный от вашего намерения, часто бывает, что вы сделали синтаксическую ошибку.

Смежные вопросы