0

我似乎无法使用 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

但是当我运行程序时,输入字符串测试,然后按回车,它挂在那里,我似乎无法弄清楚为什么..

解决方案是什么?

4

2 回答 2

6

出于性能和简单性的原因,FParsec 逐块读取输入流(或在开始解析之前将完整流读入字符串)。有关更多详细信息,请参见例如此答案:Chunked Parsing with FParsec

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

于 2012-10-11T23:09:10.910 回答
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()
于 2012-10-11T19:16:42.803 回答