使用Parsec解析数据并省略注释

时间:2012-10-20 17:20:34

标签: parsing haskell parsec

我正在尝试编写一个Haksell Parsec Parser,它将文件中的输入数据解析为LogLine数据类型,如下所示:

--Final parser that holds the indvidual parsers.
final :: Parser [LogLine]
final = do{ logLines <- sepBy1 logLine eol
        ; return logLines
        }


--The logline token declaration
logLine :: Parser LogLine
logLine = do
name <-  plainValue -- parse the name (identifier)
many1 space -- parse and throw away a space
args1 <- bracketedValue -- parse the first arguments
many1 space -- throw away the second sapce
args2 <- bracketedValue -- parse the second list of arguments
many1 space -- 
constant <- plainValue -- parse the constant identifier
space
weighting <- plainValue --parse the weighting double
space
return $ LogLine name args1 args2 constant weighting

它解析一切都很好,但现在我需要为文件添加注释,我必须修改解析器以便忽略它们。 它应该支持仅以“ - ”开头并以“\ n”结尾的单行注释 我已经尝试定义评论标记如下:

comments :: Parser String
comments = do 
    string "--"
    comment <- (manyTill anyChar newline)
    return ""

然后将其插入final解析器,如下所示:

final :: Parser [LogLine]
final = do 
        optional comments
        logLines <- sepBy1 logLine (comments<|>newline)
        optional comments
        return logLines

编译很好,但它不解析。我已经尝试了几个小修改,但最好的结果是解析了第一个注释的所有内容,所以我开始认为这不是这样做的方法。 PS: 我见过这个Similar Question,但它与我想要实现的略有不同。

2 个答案:

答案 0 :(得分:3)

如果我在评论中正确理解了您对格式的描述,那么您的格式示例就是

name arg1 arg2 c1 weight
-- comment goes here

可选地后跟更多的日志行和/或评论。

然后问题是日志行和注释行之间有换行符,这意味着分隔符解析器的comments部分失败 - comments必须以{{1}开头} - 不消耗输入,因此尝试"--"成功。然后下一行以newline开头,这使"--"失败而不消耗输入,从而结束plainValue

解决方案是让分隔符首先使用换行符,然后使用以下多个注释行:

sepBy1

通过允许序列以分隔符(final = do skipMany comments sepEndBy1 logLine (newline >> skipMany comments) 而不是sepEndBy1)结束,自动跳过最终sepBy1之后的任何注释行。

答案 1 :(得分:0)

我理解你的问题的方式,每一行都是注释或logLine。如果是这样,final应该是这样的:

final :: Parser [LogLine]
final = do 
        logLines <- sepBy1 (comment<|>logLine) newline
        return logLines