我似乎无法使用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,它会挂起,我似乎无法弄清楚原因..
解决方案是什么?
答案 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()