Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell Parsec计算中的执行顺序_Haskell_Parsec - Fatal编程技术网

Haskell Parsec计算中的执行顺序

Haskell Parsec计算中的执行顺序,haskell,parsec,Haskell,Parsec,我很难弄清楚如何调试用Parsec编写的解析器。最奇怪的是执行的顺序。我有以下代码: import Data.Text (pack) import Debug.Trace import Text.Parsec.Text (Parser) import Text.Parsec material :: Parser MTL material = do name <- many finishLine >> string "newmtl" >> whitespaces

我很难弄清楚如何调试用Parsec编写的解析器。最奇怪的是执行的顺序。我有以下代码:

import Data.Text (pack)
import Debug.Trace
import Text.Parsec.Text (Parser)
import Text.Parsec

material :: Parser MTL
material = do
  name <- many finishLine >> string "newmtl" >> whitespaces >> manyTill anyChar (try finishLine)
  illumCmds <- parseIllum
  texMapCmds <- parseTexMaps
  let mtl = constructMaterial name illumCmds texMapCmds
  traceShow mtl $ return ()
  return mtl

parseMTL :: FilePath -> IO [MTL]
parseMTL filepath = do
  s <- readFile filepath
  case parse (many material) filepath (pack s) of
    Left x -> error $ show x
    Right x -> return x

loadMTL :: FilePath -> IO ()
loadMTL fp = do
  putStrLn $ "Start loading MTL: " ++ show fp
  parseMTL fp >>= print
  putStrLn $ "Finished."
所以我发现我的程序中有一个错误,我希望通过使用
trace
,我可以缩小它的范围(显示thunk将强制对其进行评估,并且它将解决所有以前的解析,直到调用
trace
)。然而,我有一些行为,我不太明白。我的输出如下:

... other stuff ...
MTL { ... everything looks good here ... }
... other stuff ...
Loading MTL: filepath.mtl
lobjview.exe: Text.ParserCombinators.Parsec.Prim.many: 
combinator 'many' is applied to a parser that accepts an empty string.
# Default material file.  Created by Morgan McGuire and released into
# the Public Domain on July 16, 2011.
#
# http://graphics.cs.williams.edu/data

newmtl default
  Ns 10.0000
  Ni 1.5000
  Tr 0  0
  illum 2
  Ka 1 1 1
  Kd 1 1 1
  Ks 0.2 0.2 0.2
  Ke 0 0 0
  map_Kd default.png
所以我的第一个问题是:

  • 为什么我的
    跟踪
    显示在
    IO
    monad的输出之前
我决定分析我的代码,并使用
+RTS-xc
运行它,以查看此错误来源的堆栈跟踪。最好的猜测是:

Text.Parsec.Prim.CAF
--> evaluated by: Lambency.Loaders.MTLLoader.whitespace,
called from Lambency.Loaders.MTLLoader.finishLine.comment,
called from Lambency.Loaders.MTLLoader.finishLine.endMarker,
called from Lambency.Loaders.MTLLoader.finishLine,
对应于此代码的:

whitespace :: Parser Char
whitespace = tab <|> char ' '

whitespaces :: Parser [Char]
whitespaces = many whitespace

finishLine :: Parser ()
finishLine = many (whitespace <|> comment) >> endMarker >> return ()
  where
    endMarker = endOfLine

    comment :: Parser Char
    comment = char '#' >> manyTill anyChar (try $ lookAhead endMarker) >> return '_'

你可以发布
endOfLine
的定义,或者源代码的链接吗?这很大程度上取决于你的
部分内容--
部分。在您给出的代码中,
material
只解析空字符串,因此对其应用
many
是一个错误。@JohnL
endOfLine
来自。@luqui我不相信它是否依赖于此。我编辑了我的文章以包含完整的代码,只是为了表明它不会只解析空字符串,但我的问题是,我认为这不重要。为什么
traceShow
的输出在
IO
调用的输出之前正确显示?既然
traceShow
的输出是正确的,为什么我的解析器会因为它提供的错误而失败?@Mokosha您的
许多
调用看起来都没有引发您看到的错误。所以我推测问题在别处。当你提问时,你应该让别人很容易重复你的问题。一点一点地给出部分程序没有帮助。例如,您的示例输出提到
加载MTL
,但您的代码片段打印
开始加载MTL
。老实说,我不相信你给我们看的和你实际运行的是一致的。
# Default material file.  Created by Morgan McGuire and released into
# the Public Domain on July 16, 2011.
#
# http://graphics.cs.williams.edu/data

newmtl default
  Ns 10.0000
  Ni 1.5000
  Tr 0  0
  illum 2
  Ka 1 1 1
  Kd 1 1 1
  Ks 0.2 0.2 0.2
  Ke 0 0 0
  map_Kd default.png