Antra

Themen

PEG-Kurzreferenz

Diese Seite ist keine Einführung und kein Tutorial.

Sie ist als schnelle Nachschlage-Seite gedacht: Was gibt es alles? Wie sieht die Syntax aus? Was kommt zurück?

Für Erklärungen und schrittweisen Aufbau sind diese Kapitel besser:

Einstiegspunkte#

APIInputErfolgFehlschlagZweck
PEG.match(grammar, input)StringCapture-Arrayundefknapper Text-Match
PEG.match(grammar, input, start)String + StartoffsetCapture-ArrayundefText-Match ab Position
PEG.match_result(grammar, input)String%Ok[captures]%Err[msg]Text-Match mit Diagnose
PEG.match_result(grammar, input, start)String + Startoffset%Ok[captures]%Err[msg]Text-Match mit Diagnose ab Position
PEG.match_bytes(grammar, input)ByteStringCapture-Arrayundefbinärer Match
PEG.match_bytes(grammar, input, start)ByteString + Byte-OffsetCapture-Arrayundefbinärer Match ab Offset
PEG.match_bytes_result(grammar, input)ByteString%Ok[captures]%Err[msg]binärer Match mit Diagnose
PEG.match_bytes_result(grammar, input, start)ByteString + Byte-Offset%Ok[captures]%Err[msg]binärer Match mit Diagnose ab Offset

Primitive Patterns#

FormBeispielBedeutungModus
String-Literal"cat"matcht exakt diesen TextText, Bytes
positive Zahl3konsumiert blind genau 3 Zeichen oder BytesText, Bytes
-1-1matcht nur am Ende des InputsText, Bytes
Character-Range'a'..'z'matcht genau ein Zeichen im BereichText
Regex-Primitiv[:regex, regex"[0-9]+"]matcht einen Regex-Praefix an der aktuellen PositionText
Regel-Keyword:wordspringt in benannte Regel oder Built-inText, Bytes

Eingebaute Zeichenklassen#

Built-inBedeutung
:aalphanumerisch
:dZiffer
:wBuchstabe
:sWhitespace
:hhexadezimales Zeichen
:gdruckbares ASCII-Zeichen

Struktur-Operatoren#

OperatorAliasFormBedeutung
:sequence:*[:sequence, a, b, c]alles nacheinander
:choice:+[:choice, a, b, c]erste passende Alternative
:any-[:any, x]0 oder mehr
:some-[:some, x]1 oder mehr
:opt:?[:opt, x]0 oder 1
:repeat-[:repeat, 3, x]genau n Wiederholungen
:between-[:between, 1, 5, x]zwischen min und max

Lookahead und Steuerung#

OperatorAliasFormBedeutung
:not:![:not, x]negativer Lookahead, konsumiert nichts
:if-[:if, cond, patt]matcht patt nur wenn cond hier passt
:to-[:to, x]konsumiert bis direkt vor x
:thru-[:thru, x]konsumiert bis inklusive x
:expect-[:expect, patt, "beschreibung"]benennt einen Fehler lesbar
:cut-[:cut]commitet auf den aktuellen Ast

Capture-Operatoren#

OperatorAliasFormErgebnis
:capture:<-[:capture, patt]konsumierter Ausschnitt als Capture
:group-[:group, patt]tiefere Captures als Unter-Array
:position-[:position]aktuelle Zeichen- oder Byte-Position
:constant-[:constant, v]statischer Wert auf dem Capture-Stack
:replace-[:replace, patt, fn]ersetzt die Captures von patt durch fn(...)

Byte-Operatoren#

Diese Formen funktionieren nur in PEG.match_bytes(...) oder PEG.match_bytes_result(...).

OperatorFormBedeutungCapture
:bytes[:bytes, n]konsumiert genau n Bytesnein
:byte[:byte, n]matcht genau ein Byte mit Wert nnein
:u8[:u8]liest 1 Byte als Integerja
:u16be[:u16be]liest 2 Bytes big-endianja
:u16le[:u16le]liest 2 Bytes little-endianja
:u32be[:u32be]liest 4 Bytes big-endianja
:u32le[:u32le]liest 4 Bytes little-endianja
:u64be[:u64be]liest 8 Bytes big-endianja
:u64le[:u64le]liest 8 Bytes little-endianja
:cstring[:cstring]liest bis zum Null-Byteja, als ByteString
:take[:take, patt]liest erst Länge mit patt, dann Payloadja

Was :capture im Byte-Modus liefert#

PatternTextmodusByte-Modus
[:capture, patt]String-LiteralwertByteString
[:capture, [:bytes, n]]nicht anwendbarByteString
[:u8], [:u16be], ...nicht anwendbarInteger-Capture

Typische Rückgabewerte#

MusterRückgabe
Erfolg ohne Captures[]
Erfolg mit Capturesz. B. ["age", "42"]
Erfolg mit :groupz. B. [["age", "42"]]
Result-Erfolg%Ok[...]
Result-Fehler%Err["..."]

Wann welches Werkzeug?#

BedarfEmpfehlung
nur schnell prüfen, ob etwas passtPEG.match(...)
brauchbare Fehlermeldung für TextPEG.match_result(...)
brauchbare Fehlermeldung für BytesPEG.match_bytes_result(...)
lesbarer Pflichtfehler:expect
nach erkennbarem Präfix keinen Fallback mehr:cut
mehrere Captures zu einem Knoten bündeln:group
Capture transformieren:replace

Ein sehr kleines Musterarchiv#

ZielMuster
ganzer Input muss passen[:sequence, ..., -1]
Wort[:some, :w]
Zahl[:some, :d]
name:42[:group, [:sequence, [:capture, [:some, :w]], ":", [:capture, [:some, :d]], -1]]
präziser Pflichtseparator[:expect, ":", "colon"]
Commit nach Präfix[:sequence, prefix, [:cut], ...]
bis Zeilenende lesen[:to, :newline]

Wichtigste Praxisregeln#

RegelKurzfassung
-1 nicht vergessensonst darf am Ende Müll übrig bleiben
:expect sparsam, aber gezielt setzengute Fehler statt technischer Details
:cut erst nach klarem Präfix setzensonst commitest du zu früh
bei echten Parsern eher Result-APIs nutzenundef ist für Diagnose zu arm
Byte-Formate konsequent mit Byte-API parsenText- und Byte-Modus nicht mischen

Quelle dieser Seite