attoparsec of parsec in haskell

Ik moet een aantal bestanden ontleden en ze converteren naar een aantal vooraf gedefinieerde datatypes.

Haskell lijkt daarvoor twee pakketten te leveren:

  1. attoparsec
  2. parsec

Wat is het verschil tussen beide en welke is beter geschikt voor het ontleden van een tekstbestand volgens bepaalde regels?


Antwoord 1, autoriteit 100%

Pasec

Parsec is goed voor “op de gebruiker gerichte” parsers: dingen waar je een beperkte hoeveelheid invoer hebt, maar foutmeldingen er toe doen. Het is niet erg snel, maar als je kleine invoer hebt, zou dit niet uit moeten maken. Ik zou bijvoorbeeld Parsec kiezen voor vrijwel alle programmeertaaltools omdat – in absolute termen – zelfs de grootste bronbestanden niet zogroot zijn, maar foutmeldingen er echt toe doen.

Parsec kan op verschillende invoertypes werken, wat betekent dat je het kunt gebruiken met een standaard Stringof met een stroom tokens van een of andere externe lexer. Omdat het Stringkan gebruiken, verwerkt het Unicode perfect voor je; de ingebouwde basisparsers zoals digiten letterzijn Unicode-bewust.

Parsec wordt ook geleverd met een monad-transformator, wat betekent dat u het in een monad-stack kunt plaatsen. Dit kan handig zijn als u bijvoorbeeld extra status wilt bijhouden tijdens uw parse. Je zou ook voor meer trippy effecten kunnen gaan, zoals niet-deterministische ontleding, of zoiets: de gebruikelijke magie van monadetransformatoren.

Attoparsec

Attoparsec is veel sneller dan Parsec. U moet het gebruiken wanneer u verwacht grote hoeveelheden input te krijgen of wanneer prestaties er echt toe doen. Het is geweldig voor zaken als netwerkcode (parseren van pakketstructuur), het ontleden van grote hoeveelheden onbewerkte gegevens of het werken met binaire bestandsindelingen.

Attoparsec kan werken met ByteStrings, dit zijn binairegegevens. Dit maakt het een goede keuze voor het implementeren van zaken als binaire bestandsindelingen. Aangezien dit echter voor binaire gegevens is, behandelt het geen zaken als tekstcodering; daarvoor moet je de attoparsec-module voor Textgebruiken.

Attoparsec ondersteunt incrementeel ontleden, wat Parsec niet doet. Dit is erg belangrijk voor bepaalde toepassingen, zoals netwerkcode, maar maakt voor andere niet uit.

Attorparsec heeft slechtere foutmeldingen dan Parsec en offert een aantal functies op hoog niveau op voor prestaties. Het is gespecialiseerd in Textof ByteString, dus je kunt het niet gebruiken met tokens van een aangepaste lexer. Het is ook geen monadetransformator.

Welke?

Uiteindelijk richten Parsec en Attoparsec zich op zeer verschillende niches. Het grote verschil is de prestatie: als je het nodig hebt, kies dan voor Attoparsec; als je dat niet doet, ga dan gewoon met Parsec.

Mijn gebruikelijke heuristiek is het kiezen van Parsec voor programmeertalen, configuratiebestandsindelingen en gebruikersinvoer, evenals bijna alles wat ik anders zou doen met een regex. Dit zijn dingen die meestal met de hand worden geproduceerd, dus de parsers hoeven niet te schalen, maar ze moeten fouten wel goed rapporteren.

Aan de andere kant zou ik Attoparsec kiezen voor zaken als het implementeren van netwerkprotocollen, omgaan met binaire data en bestandsformaten of het inlezen van grote hoeveelheden automatisch gegenereerde data. Dingen waarbij je te maken hebt met tijdsdruk of grote hoeveelheden data, die meestal niet direct door een mens geschreven zijn.

Zoals je ziet, is de keuze eigenlijk vaak vrij eenvoudig: de use-cases overlappen elkaar niet erg. De kans is groot dat het vrij duidelijk is welke je voor een bepaalde toepassing moet gebruiken.

Other episodes