построение лексического анализатора с использованием ml-lex - PullRequest
3 голосов
/ 25 января 2011

Мне нужно создать новый экземпляр lexer, привязанный к стандартному потоку ввода.
Тем не менее, когда я набираю

val lexer = makeLexer( fn n => inputLine( stdIn ) );

Я получаю ошибку, которую не понимаю:

stdIn:1.5-11.13 Error: operator and operand don't agree [tycon mismatch]
  operator domain: int -> string
  operand:         int -> string option
  in expression:

(makeLexer - это имя функции, присутствующее в моем исходном коде)

Ответы [ 2 ]

3 голосов
/ 25 января 2011

inputLine возвращает string option, и я предполагаю, что ожидается string.

То, что вы хотите сделать, это либо makeLexer взять string option, вот так:

fun makeLexer  NONE    = <whatever you want to do when stream is empty>
  | makeLexer (SOME s) = <the normal body makeLexer, working on the string s>

или измените свою строку на:

val lexer = makeLexer( fn n => valOf ( inputLine( stdIn ) ) );

valOf принимает тип параметра и распаковывает его.

Обратите внимание, что поскольку inputLine возвращает NONE, когда поток пустой, вероятно, лучше использовать первый подход, а не второй.

2 голосов
/ 26 января 2011

Пример создания интерактивного потока приведен на стр. 38 (или 32 в документе) Руководства пользователя для ML-Lex и ML-Yacc

Примеркод может быть проще с использованием inputLine.Поэтому я бы использовал пример, данный Себастьяном, имея в виду, что inputLine может вернуть NONE, используя stdIn atleast, если пользователь нажмет CTRL-D.

val lexer =
let 
  fun input f =
      case TextIO.inputLine f of
        SOME s => s
      | NONE => raise Fail "Implement proper error handling."
in 
  Mlex.makeLexer (fn (n:int) => input TextIO.stdIn)
end

Также пример калькулятора на стр. 40) показывает, как использовать это в целом

В общем, руководство пользователя содержит несколько хороших примеров и объяснений.

...