gpt4 book ai didi

Haskell Parsec - 解析两个内容列表

转载 作者:行者123 更新时间:2023-12-02 20:07:30 25 4
gpt4 key购买 nike

我正在使用Advent of Code part 16作为学习如何使用秒差距的借口,但我在如何处理这个特定情况上遇到了困难。

输入的格式如下:

Before: [3, 2, 3, 0]
2 3 1 1
After: [3, 2, 3, 0]

Before: [1, 0, 2, 1]
7 0 1 1
After: [1, 1, 2, 1]

...

Before: [0, 0, 2, 1]
6 2 3 1
After: [0, 6, 2, 1]



5 0 2 3
5 1 3 1
...
5 3 2 2

换句话说,首先是许多组三行解析成一个结构,由空行分隔,然后是三个空行,然后是许多四位数字的行。

我为每个结构都有工作解析器 - SampleMaskedOperation,以及解析器 samplemaskedOp分别1 - 但我不知道如何将它们放在一起以将其解析为 ([Sample], [MaskedOperation])

我尝试了以下方法:

parseInput :: GenParser Char st ([Sample], [MaskedOperation])
parseInput = do
samples <- sample `sepBy` (count 2 newline) <* count 3 newline
operations <- maskedOp `sepBy` newline
return (samples, operations)

但是当它到达三个换行符时失败,需要另一个样本:

(line 3221, column 1):
unexpected "\n"
expecting "Before:"

我如何告诉parsec我想获取尽可能多的数据,然后使用分隔符(额外的换行符),然后开始读取其他内容?


1 阅读“代码出现”问题了解上下文;名称并不重要。

最佳答案

恐怕您不能在这里使用sepBy

让我们将其简化为将“a”解析为样本,将“b”解析为换行符。您将像这样解析字符串

a b b a b b b c b c b c b

那么解析器在遍历这样的字符串时会怎么想呢?让我们看一下:


Parsing a or an empty sequence

[a] b b a b b b c b c b c b

Oh, an a. The sequence is non empty, so I will parse many "bb" >> "a" from now.

a [b b a] b b b c b c b c b

Success! Let's get some more or finish

a b b a [b b] b c b c b c b

Okay, I have found another bb, so the sequence continues. Parsing a

a b b a b b [b] c b c b c b

wat


问题是解析器不会回滚,除非明确要求这样做。要赋予解析器回滚能力,您必须使用 try 组合器对其进行标记,否则它将无法“取消消耗”已消耗的输入。

目前,我没有看到比重写 sepBy 组合器更好的方法,以使其意识到在解析每个分隔符后,如果解析 separator ,可能需要将其返回到缓冲区>> 目标 失败:

sepTry a sep = sepTry1 a sep <|> pure []
sepTry1 a sep = liftA2 (:) a (many (try $ sep *> a))

请注意,解析 a 必须包含在 try 部分 - 这是实际触发失败的地方。

为了可视化差异,让我们看看相同的场景,但使用 sepTry 代替:


...

a [b b a] b b b c b c b c b

Success! Let's try to get one more if possible

a b b a ![b b] b c b c b c b

Okay, I have found another bb, so the sequence continues. Parsing a

a b b a !b b [b] c b c b c b

Not what I expected. Return failure and move cursor to back exclamation mark.

a b b a ![]b b b c b c b c b

Failed parsing bba, parsing sequence finished. Parse bbb

a b b a [b b b] c b c b c b

Success!


在您的情况下,在每个 Sample 之后,此解析器将尝试读取 2 个换行符,后面带有 Sample ,或者如果失败,则读取 3 个换行符并继续 MaskedOperation s

关于Haskell Parsec - 解析两个内容列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54335403/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com