简体   繁体   English

Parsec调试

[英]Parsec debugging

I've been working with parsec and I have trouble debugging my code. 我一直在使用parsec,我在调试代码时遇到问题。 For example, I can set a breakpoint in ghci, but I'm not sure how to see how much of the input has been consumed, or things like that. 例如,我可以在ghci中设置断点,但我不知道如何查看已经消耗了多少输入,或者类似的东西。

Are there tools / guidelines to help with debugging parsec code? 是否有工具/指南来帮助调试parsec代码?

This page might help. 页面可能有所帮助。

Debug.trace is your friend, it allows you to essentially do some printf debugging. Debug.trace是你的朋友,它允许你基本上做一些printf调试。 It evaluates and prints its first argument and then returns its second. 它评估并打印其第一个参数,然后返回其第二个参数。 So if you have something like 所以,如果你有类似的东西

foo :: Show a => a -> a
foo = bar . quux

You can debug the 'value' of foo's parameter by changing foo to the following: 您可以通过将foo更改为以下内容来调试foo参数的'value':

import Debug.Trace(trace)

foo :: Show a => a -> a
foo x = bar $ quux $ trace ("x is: " ++ show x) x

foo will now work the same way as it did before, but when you call foo 1 it will now print x is: 1 to stderr when evaluated. foo现在的工作方式和以前一样,但是当你调用foo 1它会在评估时打印x is: 1到stderr。

For more in-depth debugging, you'll want to use GHCI's debugging commands. 要进行更深入的调试,您需要使用GHCI的调试命令。 Specifically, it sounds like you're looking for the :force command, which forces the evaluation of a variable and prints it out. 具体来说,它听起来像你正在寻找:force命令,它强制评估变量并将其打印出来。 (The alternative is the :print command, which prints as much of the variable as has been evaluated, without evaluating any more.) (替代方法是:print命令,打印尽可能多的已经评估的变量,而不再进行评估。)

Note that :force is more helpful in figuring out the contents of a variable, but may also change the semantics of your program (if your program depends upon laziness). 请注意:force更有助于计算变量的内容,但也可能会更改程序的语义(如果您的程序依赖于懒惰)。

A general GHCI debugging workflow looks something like this: 一般的GHCI调试工作流程如下所示:

  • Use :break to set breakpoints 使用:break来设置断点
  • Use :list and :show context to check where you are in the code 使用:list:show context来检查您在代码中的位置
  • Use :show bindings to check the variable bindings 使用:show bindings检查变量绑定
  • Try using :print to see what's currently bound 尝试使用:print来查看当前绑定的内容
  • Use :force if necessary to check your bindings 使用:force必要时:force检查绑定

If you're trying to debug an infinite loop, it also helps to use 如果您正在尝试调试无限循环,它也有助于使用

  • :set -fbreak-on-error
  • :trace myLoopingFunc xy

Then you can hit Ctrl-C during the loop and use :history to see what's looping. 然后你可以在循环期间Ctrl-C并使用:history来查看循环的内容。

You might be able to use the <?> operator in Text.Parsec.Prim to make better error messages for you and your users. 您可以使用Text.Parsec.Prim中<?>运算符为您和您的用户制作更好的错误消息。 There are some examples in Real World Haskell. Real World Haskell中有一些例子 If your parser has good sub-parts then you could setup a few simple tests (or use HUnit ) to ensure they work separately as expected. 如果您的解析器具有良好的子部件,那么您可以设置一些简单的测试(或使用HUnit )以确保它们按预期单独工作。

Another useful trick: 另一个有用的技巧

_ <- many anyChar >>= fail this will generate an error ( Left ) of: _ <- many anyChar >>= fail这会产生一个错误( Left ):

unexpected end of input
the remaining 'string'

I think the parserTrace and parserTraced functions mentioned here http://hackage.haskell.org/package/parsec-3.1.13.0/docs/Text-Parsec-Combinator.html#g:1 do something similar to the above. 我认为这里提到的parserTraceparserTraced函数http://hackage.haskell.org/package/parsec-3.1.13.0/docs/Text-Parsec-Combinator.html#g:1做了类似的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM