I assume the reader has some familiarity with monadic parsing in Haskell, particularly with the Attoparsec library, as well as with the diff formats parsed. For the latter, I invite you to read my previous article, where I described a grammar for diffs in these formats.
Like in the grammar article, I call the diffed files left and right files. The parser takes a ByteString as input, and the lines coming from the diffed files reported in the diff are kept in that type. However, text not coming directly from the diffed files is converted to the Text type.
The entry point for our parser is the function diffParse:: ByteString -> Either String Diff which, given a (ByteString) input, returns a value of type Diff or an error string. To produce its result, it supplies a Parser Diff to Attoparsec’s function parseOnly, of type:
I define parsers for each diff variant named, respectively, emptyParser, normalDiffParser, uniDiffParser, and gitDiffParser. Combining these parsers with the alternative operator <|> from Control.Applicative we have a parser for Diff, which we can supply to parseOnly: