FParsec - 如何从标准输入流解析

时间:2012-10-11 19:02:29

标签: .net parsing f# fparsec

我似乎无法使用FParsec成功解析标准输入流。我把我的情况简化为这个非常简单的代码:

match (runParserOnStream (pstring "test" .>> FParsec.CharParsers.newline) () "stdin" (Console.OpenStandardInput ()) Console.InputEncoding) with
    | Success(result, _, _)   -> printfn "Success: %A" result
    | Failure(errorMsg, perr, _) -> printfn "Failure: %s" errorMsg

但是当我运行程序时,输入字符串测试,然后按Enter,它会挂起,我似乎无法弄清楚原因..

解决方案是什么?

2 个答案:

答案 0 :(得分:6)

出于性能原因和简单性,FParsec以块为单位读取输入流(或在开始解析之前将完整的流读入字符串)。参见例如这个答案有更多细节:Chunked Parsing with FParsec

如果要使用FParsec解析来自REPL的输入,可以实现一个简单的扫描程序,它等待输入流中的终结符(例如“;;”后跟换行符,就像在FSI控制台中一样)和然后,当它遇到这样的终结符时,将输入复制到终结符中,并将其交给FParsec解析器进行评估。

答案 1 :(得分:2)

由于FParsec的源代码可用,因此很容易逐步执行它并看到它读取输入流,直到缓冲区已满或流已结束信号。

或者,您可以一次阅读一行:

let rec parseConsoleInput() =
  let parser = pstring "text" .>> eof
  Console.Write("> ")
  match Console.ReadLine() with
  | null | "" -> ()
  | input -> 
    match run parser input with
    | Success(result, _, _) -> printfn "Success: %A" result
    | Failure(msg, _, _) -> printfn "Failure: %s" msg
    parseConsoleInput()