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

.net FParsec-如何从标准输入流解析,.net,parsing,f#,fparsec,.net,Parsing,F#,Fparsec,我似乎无法使用FParsec成功解析标准输入流。我将我的案例简化为以下非常简单的代码: match (runParserOnStream (pstring "test" .>> FParsec.CharParsers.newline) () "stdin" (Console.OpenStandardInput ()) Console.InputEncoding) with | Success(result, _, _) -> printfn "Success: %A

我似乎无法使用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键,它挂在那里,我似乎不明白为什么


解决方案是什么?

因为FParsec的源代码是可用的,所以很容易一步一步地浏览它,并查看它读取输入流,直到缓冲区已满或流结束时发出信号

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

let rec parseConsoleInput()=
让parser=pstring“text”。>>eof
控制台。写入(“>”)
将Console.ReadLine()与
|空|“”->()
|输入->
将运行解析器输入与
|成功(结果)——>打印fn“成功:%A”结果
|失败(msg,,->printfn“失败:%s”消息
parseConsoleInput()

出于性能和简单性考虑,FParsec逐块读取输入流(或在开始解析之前将整个流读取为字符串)。有关更多详细信息,请参见此答案:


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

我认为您永远不会到达输入流的结尾。是的,这也是我的猜测,但应该有一种方法告诉FParsec,一旦解析了正确的形式并且没有歧义,它就可以停止,或者这意味着完全没有办法用FParsec解析器进行REPL。我猜它直到缓冲区满了才会解析。你使用的是最新版本吗?是的,我自己构建的。我甚至不确定我的推理是否正确,但一定有办法做到我想做的事!:)在由->“test”定义的语法中,唯一有效的输入是“test”,因此Fparsec可以在解析所述字符串后停止。如果流中还有剩余的字符,那么根据语法输入是不正确的。此外,什么是可解析块是由语法定义的,而不是以任何其他方式定义的。运行F#repl以了解我的意思。在F#repl中,必须以“;”结束输入。如果您想用FParsec解析来自这样一个REPL的输入,您可以简单地扫描输入中的“;”,将“;”分隔的块复制到字符串中,然后用FParsec.@raph.amiard单独解析这些字符串。在F#中,没有好的方法知道“可解析块”何时结束。特别是,我可以用任意数量的空行分隔行,而不会影响代码的含义。这就是为什么需要添加
表示当你的“可解析块”endsHey stephan出现时,我自己就是这么做的,因为我不想花太多时间对它吹毛求疵。谢谢