Haskell 解析器分离器

4

我正在使用Parsec编写一个日志文件的解析器。该日志文件的每一行都遵循一个共同的结构 A:B:C:D,其中组件A、B、C和D遵循简单的规则。我已经为每个组件编写了解析器,并希望将它们合并成一个单一的解析器。我的当前方法可以工作,但我感觉应该有更好的解决方案。一个直接的缺点是,对于具有超过4个组件的日志文件,它不会很好地扩展。

parser :: (a -> b -> c -> d -> e) -> Parser a -> Parser b -> Parser c -> Parser d -> Parser e
parser f pa pb pc pd = f <$> pa <* (char ':') <*> pb <* (char ':') <*> pc <* (char ':') <*> pd

我找了一个合适的解析组合器,但是唯一接近的组合器是 sepBy,它不适用于这种情况。感谢任何帮助!
1个回答

6

我认为最好的选择是引入您自己的运算符,例如:

infixl 4 <:>
p <:> q = p <* char ':' <*> q

那么您就不需要定义一个单独的parse函数,只需编写实现即可:

myParser = f <$> pa <:> pb <:> pc <:> pd

这很容易扩展:

myParser2 = g <$> pa <:> pb <:> pc <:> pd <:> pe

这是一个好主意!不幸的是,我定义 <:> 的方式似乎比 <$> 更强,这意味着我必须在 (f <$> pa) 周围加上括号。你有什么建议吗? - Lando-L
@Lando-L 我在我的回答中添加了一个修复声明,这应该使它正常工作。我将其设置为与<*>相同的修复性,我使用GHCi中的:info (<*>)进行了查找。 - Noughtmare
再次感谢。我不知道固定性的概念。我会好好研究它的。 - Lando-L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接