Parser müssen nicht kompliziert sein: Ein 75-Zeilen-URL-Parser ersetzt 23k Zeilen C++

Parsers don't have to be complicated

Parser müssen nicht kompliziert sein: Ein 75-Zeilen-URL-Parser ersetzt 23k Zeilen C++

In einem persönlichen Blogbeitrag erzählt der Autor, wie er jahrelang zwischen Parser-Generatoren wie Lemon und ad-hoc Scannern hin- und hergerissen war, bis er mit bx::Scanner eine schlanke Alternative schuf. Das Design setzt auf Zero-Copy, nicht-besitzende StringViews, einen einzigen Cursor und eingebaute Zeilen- und Spaltenverfolgung. Anhand von Beispielen wie INI-Parsing, URL-Parsing und Pfadnormalisierung zeigt er, wie die Bibliothek repetitive Aufgaben vereinfacht und typische Bugs vermeidet. Das Ergebnis: weniger Abhängigkeiten, weniger Code und eine deutliche Reduktion von Fehlerquellen.

Die Scanner-Technik macht es unmöglich, über das Ende einer fehlerhaften Zeile hinauszulaufen, statt es nur unwahrscheinlich zu machen.
  1. imoverclocked

    Das Schwierigste am Schreiben eines Parsers ist es, kognitiv zu akzeptieren, was als gültige Eingabe gelten soll. Man kann den besten Parser schreiben, der schnell und gut spezifiziert ist, aber unweigerlich wird ihn jemand auf unerwartete Weise (miss)brauchen.

    Berühmte Beispiele: Trotz so vieler anfänglicher guter Absichten müssen HTML-Tags nicht geschlossen werden, JSON-Zahlen werden allzu oft als Strings kodiert, YAML kann so aussehen, wie die meisten es erwarten, oder es kann zunehmend wie JSON aussehen ... und so weiter und so fort.

  2. f311a

    Leider scheitert einfaches URL-Parsing an so vielen Dingen. Es gibt einen Grund, warum jede URL-Parsing-Bibliothek mindestens ein paar tausend Zeilen Code umfasst.

    Eine gängige Methode, es zu testen, ist einfach eine IPv6-URL zu übergeben: http://[f021:d981:b487:e57d:193e:550e::]/

  3. mrkeen

    Wenn man eine Linie von 'Ad-hoc-Byte-Gefummel' zu 'Parser-Kombinatoren' zieht, ist das hier höchstens 20 % davon entfernt.

    Wenn man sich den verlinkten URL-Parser ansieht, warum sieht er nicht so aus:

    url = do scheme

    authority

    path

    query

    fragment

    wobei

    scheme = ...

    authority = ...

    usw.

    Er sieht völlig ad-hoc aus.

Mehr von diesem Tag

2026-08-07