Pegjs: Möglichkeit, bestimmte Produktionen zu ignorieren

Erstellt am 8. Okt. 2010  ·  29Kommentare  ·  Quelle: pegjs/pegjs

Es wäre schön, den Lexer/Parser anweisen zu können, bestimmte Produktionen (zB Whitespace- und Kommentarproduktionen) zu ignorieren, damit es unnötig wird, alle anderen Produktionen mit Kommentar-/Whitespace-Zugaben zu überfrachten. Dies ist jedoch möglicherweise nicht möglich, da Lexing in das Parsen integriert ist?

Dankeschön

feature

Hilfreichster Kommentar

@atesgoral - Ich bin

Also habe ich getan, was jeder Schwächling tun würde - reguläre Ausdrücke verwendet. (Und dann hatte ich zwei Probleme :-)

Aber es hat den Zweck erfüllt, sodass ich mich der nächsten Herausforderung stellen konnte. Viel Glück bei Ihrem Projekt!

Alle 29 Kommentare

Einverstanden. Gibt es derzeit einen sauberen Weg, dies zu tun?

@benekastah : Es gibt

Dies wäre schwierig, ohne die Funktionsweise von PEG.js zu ändern. Mögliche Lösungen sind:

  1. Erlaubt, dem generierten Parser einen Lexer voranzustellen.
  2. Betten Sie Informationen zu festgeschriebenen Regeln irgendwo in die Grammatik ein. Das würde wahrscheinlich auch bedeuten, zwischen lexikalischer und syntaktischer Ebene der Grammatik zu unterscheiden – was ich vermeiden möchte.

Ich werde jetzt nicht daran arbeiten, aber es ist etwas, worüber man in der Funktion nachdenken sollte.

Ich bräuchte diese Funktion dazu.

Vielleicht könnten Sie ein "Skip"-Token einführen. Wenn also eine Regel dieses Token zurückgibt, wird es ignoriert und erhält keinen Knoten am AST (auch bekannt als Eintrag im Array).

Ich suche auch nach einer Möglichkeit, dies zu tun.

Ich habe eine große Grammatikdatei (sie analysiert das ASN.1-Format für SNMP-MIB-Dateien). Ich habe es nicht geschrieben, aber ich habe es trivial aus der ursprünglichen Form transformiert, um einen Parser in PEG.js zu erstellen. (Das ist gut. Tatsächlich ist es extrem glatt, dass ich weniger als 15 Minuten gebraucht habe, um es so zu optimieren, dass PEG.js es akzeptiert.)

Leider wurde die Grammatik mit der Fähigkeit geschrieben, Leerzeichen und Kommentare einfach zu ignorieren, wenn sie darauf stoßen. Folglich können keine echten MIB-Dateien verarbeitet werden, da der Parser beim ersten Auftreten von Leerzeichen stoppt.

Ich bin nicht bestrebt, die Grammatik herauszufinden, damit ich alle richtigen Leerzeichen in alle Regeln einfügen kann (es gibt ungefähr 126 Produktionen ...) Gibt es eine andere Möglichkeit, dies zu tun?

Hinweis: Für den Fall, dass ich die Grammatik von Hand ändern muss, habe ich in einem Ticket in der Google Groups-Liste um Hilfe bei einigen Fragen gebeten. http://groups.google.com/group/pegjs/browse_thread/thread/568b629f093983b7

Vielen Dank!

Vielen Dank an die Leute bei Google Groups. Ich glaube, ich habe genug Informationen, um zu tun, was ich will.

Aber ich freue mich wirklich auf die Möglichkeit in PEG.js, Leerzeichen/Kommentare als etwas zu ignorieren, das komplett ignoriert werden muss, damit ich nicht ein paar Stunden brauchen würde, um eine ansonsten saubere Grammatik zu ändern ... Danke!

Reich

Ich stimme der Behauptung zu, dass pegjs die Fähigkeit benötigt, Token zu überspringen. Ich kann mir das ansehen, denn wenn Sie eine ernsthafte Grammatik schreiben möchten, werden Sie verrückt, wenn Sie ws zwischen jeden Token setzen.

Da die generierten Parser modular sind. Erstellen Sie als Workaround einen vereinfachten Lexer und verwenden Sie seine Ausgabe als Eingabe für den realen, z.

elideWS.pegjs:

s = Eingabe:(whitespaceCharacter / textCharacter)*
{
var result = "";

for(var i = 0;i < input.length;i++) Ergebnis += input[i];
Ergebnis zurückgeben;
}

whitespaceCharacter = [ nt] { return ""; }
textCharacter = c:[^ nt] { return c; }

aber das führt zu Problemen, wenn Whitespace ein Trennzeichen ist - wie bei Bezeichnern

Stoßen Sie ziemlich oft auf dieses Problem.
Aber es ist nicht einfach, einen guten Lexer zu schreiben (man kann am Ende einen guten Teil der ursprünglichen Grammatik duplizieren, um einen kohärenten Lexer zu haben).

Was ich mir gedacht habe, ist, Überspringregeln definieren zu können, die als Alternative verwendet werden können, wenn es keine Übereinstimmung gibt. Dies führt jedoch dazu, dass eine nicht brechende Klasse erforderlich ist. Beispiel mit arithmetics.pegjs mit Floats

  = Term (("+" / "-") Term)*

Term
  = Factor (("*" / "/") Factor)*

Factor
  = "(" Expression ")"
  / Float

Float "float"
  = "-"? # [0-9]+ # ("." # [0-9]+) // # means that skip rules cannot match

// skip rule marked by "!="
// skip rules cannot match the empty string
_ "whitespace"
  != [ \t\n\r]+

Verdaue das immer noch. Irgendeine Anregung? Könnte eine sehr dumme Idee sein.

Der Unterschied besteht also darin, dass Sie unterscheiden möchten, wann der Gesamtmotor ist
Betrieb im Lexer-Modus (Leerzeichen ist wichtig) und wenn nicht (Leerzeichen ist
ignoriert).

Gibt es einen Fall, in dem Sie im Lexer-Modus Leerzeichen nicht ignorieren möchten?
als eine Option? Oder umgekehrt, wenn nicht innerhalb einer Regex? Ich denke nicht.

Wäre folgendes gleichwertig?

Schweben
"-?[0-9]+("." [0-9]+)”

oder auf andere Weise Peg erweitern, um die typischen Regexs direkt und außerhalb zu verarbeiten
ein in Anführungszeichen gesetzter String (der Regexes enthält) Whitespace wird ignoriert.

Am 19. April 2014 um 15:22 Uhr schrieb Andrei Neculau [email protected] :

Stoßen Sie ziemlich oft auf dieses Problem.
Aber es ist nicht einfach, einen guten Lexer zu schreiben (man kann am Ende einen guten Teil der ursprünglichen Grammatik duplizieren, um einen kohärenten Lexer zu haben).

Was ich mir gedacht habe, ist, Überspringregeln definieren zu können, die als Alternative verwendet werden können, wenn es keine Übereinstimmung gibt. Dies führt jedoch dazu, dass eine nicht brechende Klasse erforderlich ist. Beispiel mit arithmetics.pegjs mit Floats

Ausdruck
= Begriff ("+" / "-") Begriff)*

Begriff
= Faktor ("_" / "/") Faktor)_

Faktor
= "(" Ausdruck ")"
/ Schweben

Schweben "schweben"
= "-"? # [0-9]+ # ("." # [0-9]+) // # bedeutet, dass Skip-Regeln nicht übereinstimmen können

// Überspringe die mit "!=" markierte Regel
// Überspringregeln können nicht mit der leeren Zeichenfolge übereinstimmen
_ "Leerzeichen"
!= [ tnr]+
Verdaue das immer noch. Irgendeine Anregung? Könnte eine sehr dumme Idee sein.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.

@waTeim Eigentlich nein.

Traditionell wird der Parsing-Prozess in Lexing und Parsing unterteilt. Beim Lexing ist jedes Zeichen von Bedeutung, auch Leerzeichen. Aber diese werden dann in einen "Abwurf"-Token lexiert. Der Parser verwirft dann, wenn er zum nächsten Token vorrückt, alle abgelegten Token. Der wichtige Teil ist, dass Sie alles verwerfen können, nicht nur Leerzeichen. Dieses Verhalten ist genau das, was @andreinecula beschreibt.

Die Grundidee, dies zu implementieren, besteht darin, beim Übergang von einem Zustand in den nächsten zusätzlich alle Verwerfungsregeln zu prüfen.

Am 23. April 2014 um 14:54 Uhr schrieb Sean Farrell [email protected] :

@waTeim Eigentlich nein.

Wir sind uns also einig. Der traditionelle Ansatz ist ausreichend. Muss man nicht haben
Der strikte Parser-Teil erkennt die Existenz von verworfenen Token und es gibt
kein Grund, den Lexer-Teil bedingt zu verhalten (kontextsensitiv)
bezüglich der Erkennung von Token.

Daher sind keine Klebeelemente (z. B. '#') in der Sprache erforderlich
weil es reicht das

1) Token können ausschließlich aus Regex erstellt werden und sind nicht kontextsensitiv.
2) Token können ausnahmslos zum Ablegen markiert werden.

Traditionell wird der Parsing-Prozess in Lexing und Parsing unterteilt. Beim Lexing ist jedes Zeichen von Bedeutung, auch Leerzeichen. Aber diese werden dann in einen "Abwurf"-Token lexiert. Der Parser verwirft dann, wenn er zum nächsten Token vorrückt, alle abgelegten Token. Der wichtige Teil ist, dass Sie alles verwerfen können, nicht nur Leerzeichen. Dieses Verhalten ist genau das, was @andreinecula beschreibt.

Die Grundidee, dies zu implementieren, besteht darin, beim Übergang von einem Zustand in den nächsten zusätzlich alle Verwerfungsregeln zu prüfen.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.

Ok dann hab ich dich falsch verstanden. Es mag Fälle für Lexer-Zustände geben, aber das ist eine völlig andere Anforderung und liegt IMHO außerhalb des Anwendungsbereichs von peg.js.

@waTeim @rioki Vergessen Sie meinen Vorschlag.

Hand auf, nehmen Sie diese Regel . Wenn Sie die Grammatik der Regel vereinfachen möchten, indem Sie *WS wegnehmen, wie würden Sie dann PEGjs anweisen, *WS zwischen field_name und : nicht zuzulassen?

@andreinecula Da Ihre Grammatik Leerzeichen empfindlich ist, ist dies nicht anwendbar. Die Ablegemarker wären Teil der Grammatik, genauer gesagt der Lexing-Teil. Ich weiß nicht, was hier das große Problem ist, das wurde schon in den 70er Jahren ausreichend gelöst. Jede Sprache hat ihre eigenen überspringbaren Token und wo sie anwendbar sind. Die Leerzeichen und Kommentare sind ebenso Teil der Sprachdefinition und damit Teil der Grammatik. Es stellte sich nur heraus, dass bei den meisten Sprachen die überspringbaren Token zwischen jedem anderen Token liegen können und die Verwendung einer Verwerfungsregel es VIEL einfacher macht, als expr = WS lit WS op WS expr WS ";" für jede Regel zu schreiben. Stellen Sie sich einfach eine Grammatik wie die für C mit Whitepsace-Behandlung vor?

Ich verstehe, dass es nicht einfach ist, Abwurfregeln in Pegjs zu integrieren, aber das bedeutet nicht, dass es kein lobenswertes Ziel ist.

Oh Mann, kostenloser Antwortbereich! Ich habe viel zu sagen, sorry für die Länge.

1) Für die TL; DR-Leute, wenn ich irgendwelche Peg-Elemente hinzufügen könnte, die ich wollte, hätte ich es so geschrieben

header_field
= field_name ":" field_value

Leerzeichen (IGNORIEREN)
= [t]+

Die Ergänzung, die ich machen würde, ist ein Abschnitt mit Optionen, der in jede Produktion aufgenommen werden kann

Die http-bis-Sprache würde durch dieses Umschreiben nicht eingeschränkt (siehe Anhang a).

2) Mein Problem mit der vorgeschlagenen #

Es fühlt sich an, als ob Sie den Benutzer austauschen müssen, um die Parser-Definition mit einem Haufen zu füllen
von Nicht-Terminals (normalerweise Leerzeichen/Trennzeichen) verwerfen, wobei der Benutzer das Ausfüllen verlangt
die Parser-Definition mit einer Reihe von „Hier-Zeichen werden nicht verworfen“-Metazeichen
unnötigerweise. Zugegeben, es würde weniger Vorkommnisse geben. Es ist der seltene Fall, wenn
Leute konsumieren tatsächlich Trennzeichen und machen etwas damit, und wie ich es kommentiere

Anhang a, HTTP-bis gehört nicht zu diesen Vorkommnissen, sondern ist nur schlecht dokumentiert.

3) Benutzerdefinierte Parser-Zustände

Aber ich kann sehen, wie es für den Parser-Definierer einfacher wäre, die einfach auszuschneiden und einzufügen
Sprachspezifikation aus der Definition, also wenn Sie so etwas haben müssen, dann
dies könnte mit lexikalischen Zuständen geschehen, auf die zuvor Sean anspielte. Ich glaube, ich würde es tun
auf die folgende Weise.

Produktion1(Zustand==1)
= Zeug

Produktion2(Zustand==2)
= Zeug

Produktion3
= Zeug {Zustand = 1}

Produktion4
= Zeug {Zustand = 2}

Mit anderen Worten, genauso wie lex/yacc es möglich macht, dass Produktionen nur verfügbar sind

wenn sich das System in einem bestimmten Zustand befindet, und erlauben Sie dem Benutzer, diesen Zustandswert festzulegen.

4) Weitere Optionen

Oder Sie könnten es dem Benutzer mit einem anderen erleichtern und für den Leser sichtbarer machen
Möglichkeit

Produktion (DONTIGNORE)
= Zeug

Dies würde es dem Parser ermöglichen, die Standardaktion des Verwerfens von markierten Token zu überschreiben
als verwerfen, aber nur für diese eine Produktion. Das ist wirklich das gleiche wie 3, nur einfacher
lesen. Das ist weniger flexibel als der #Vorschlag, da entweder eine Produktion ganz ignoriert wird

oder nicht ignorieren, aber ich glaube nicht, dass zusätzliche Flexibilität erforderlich ist.

5) Das Hinzufügen eines Parameters zu getNextToken() ermöglicht Kontextsensitivität

Ich denke, alles läuft darauf hinaus (ich mache hier einige Annahmen) derzeit die
Parser-Teil ruft getNextToken(input) auf, und was stattdessen passieren muss, ist hinzufügen a

Parameter dazu getNextToken(Eingabe,Optionen).

Anhang a) Diese HTTP-bis-Spezifikation

Ok, ich habe einiges gelesen, aber nicht alles gelesen

Hypertext Transfer Protocol (HTTP/1.1): Nachrichtensyntax und Routing
Entwurf-ietf-httpbis-p1-messaging-26

Ich mag nicht, wie sie ihre Grammatik definiert haben. Ich schlage nicht vor, die Eingabe zu ändern
akzeptiert, aber ich hätte es nicht so definiert, wie sie es taten. Insbesondere gefällt mir nicht, warum sie es haben
definierte OWS und RWS und BWS, die alle genau der gleichen Zeichenfolge entsprechen
aber in unterschiedlichen Kontexten. Sie haben definiert

OWS ::== (SP | HTAB)*
RWS ::== (SP | HTAB)+
BWS ::== OWS

das ist nur die Wiederholung von Tabs und Leerzeichen

Aus keinem guten Grund. Sie haben das Parsen der Sprache erschwert – erfordern den lexikalischen Analysator
um den Kontext zu verfolgen – und das war nicht nötig.

Sie haben OWS als „optionales Leerzeichen“ definiert, BWS als „schlechtes Leerzeichen“ oder anderweitig optional
Leerzeichen, aber im „schlechten“ Kontext – wo es nicht notwendig ist – und RWS benötigt Leerzeichen, wo es ist
notwendig, um Token abzugrenzen. Nirgendwo wird dieser Leerraum verwendet, außer vielleicht gibt es einen Parser
Warnung, wenn es mit BWS übereinstimmt ("unnötiges nachfolgendes Leerzeichen erkannt" oder ähnliches), was alles ist
Trennzeichen tun sowieso.

In ihrer Spezifikation wird RWS nur hier verwendet

Via = 1#( empfangen-Protokoll RWS empfangen-von [ RWS Kommentar ] )

 received-protocol = [ protocol-name "/" ] protocol-version
                     ; see Section 6.7
 received-by       = ( uri-host [ ":" port ] ) / pseudonym
 pseudonym         = token

aber 'Protokollversion' sind Zahlen und vielleicht Buchstaben, während 'empfangen von' Zahlen und Buchstaben sind. Mit anderen Worten,
der lexikalische Analysator wird diese 2 Teile nicht richtig erkennen, es sei denn, sie werden durch Leerzeichen getrennt
und es wird ein Syntaxfehler mit oder ohne expliziter Identifizierung von RWS auftreten, wenn nicht mindestens 1 vorhanden ist
Leerzeichen. Also einfach RWS ganz aus den Produktionen entfernen und Whitespace behandeln
überall als Trennzeichen und es ändert nicht die Sprache, sondern nur wie es dokumentiert ist.

Am 24. April 2014 um 13:23 schrieb Andrei Neculau [email protected] :

@waTeim @rioki Vergessen Sie meinen Vorschlag.

Hand auf, nehmen Sie diese Regel. Wenn Sie die Grammatik der Regel vereinfachen möchten, indem Sie die OWS entfernen, wie würden Sie dann PEGjs anweisen, OWS zwischen field_name und : nicht zuzulassen?


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.

@waTeim Ich denke, du

Ich habe nie eine richtige Verwendung von Lexer-Zuständen gesehen, die vom Parser stammen. Das grundlegende Problem hierbei ist, dass der Lexer mit einem Blick nach vorne, wenn der Parser das Token sieht, um den Zustand zu wechseln, bereits den nächsten Token irrtümlicherweise lexiert hat. Was Sie vorschlagen, ist ohne Back-Tracking fast unmöglich zu implementieren, und das ist nie eine gute Funktion in einem Parser.

Beim Schreiben einer Grammatik legen Sie grundsätzlich fest, welche Produktionen als geparst gelten und was getrunken werden kann. Im Beispiel von @andreineculau gibt es zwei Möglichkeiten, entweder Sie behandeln Leerzeichen im Parser oder Sie definieren den nachgestellten ":"-Teil des Tokens. ( [a-zA-Z0-9!#$%&'+-.^_|~]+ ":" ).

Ich könnte vorschlagen, das Problem in die Angabe einer Whitelist zu verwandeln – welche Teile ich erfassen und transformieren möchte – anstelle einer Blacklist. Obwohl Whitespace ein Problem des aktuellen Erfassungssystems ist, ist die Verschachtelung von Regeln ein anderes. Wie ich in Ausgabe #66 geschrieben habe, scheint mir das LPeg-System, das direkt über Transformationen oder String-Captures anzugeben, was Sie erfassen möchten, nützlicher zu sein, als eine Handvoll zu überspringender Produktionen anzugeben und sich immer noch mit der Verschachtelung jeder anderen Produktion zu befassen.

In meinem Kommentar in Ausgabe #66 finden Sie ein einfaches Beispiel für LPeg im Vergleich zu PEG.js in Bezug auf Captures. Obwohl die Namen etwas kryptisch sind, lesen Sie im Abschnitt Captures der LPeg-Dokumentation nach, wie Sie eine bestimmte Produktion (oder einen Teil davon) erfassen oder transformieren können.

Hallo, ich habe ein Snippet erstellt , um einige allgemeine Fälle zu ignorieren: null , undefined und Zeichenfolgen mit nur Leerzeichen.
Es kann im Kopf der Grammatikdatei erforderlich sein, wie zum Beispiel:

{
  var strip = require('./strip-ast');
}

Die zwei Möglichkeiten, es zu verbessern:

  • Anpassbarer Filter für Begriffe – um die spezifischen Begriffe zu ignorieren, für die eine bestimmte Grammatik erforderlich ist.
  • Verschachtelte leere Arrays überspringen — dies kann in der zweiten Stufe nach strip , es entfernt «Pyramiden» verschachtelter leerer Arrays.
    Bei Interesse können wir es zu einem Paket aufrüsten.

@richb-hanover Wo sind Ihre ASN.1-Definitionsparser-Bemühungen gelandet?

@atesgoral - Ich bin

Also habe ich getan, was jeder Schwächling tun würde - reguläre Ausdrücke verwendet. (Und dann hatte ich zwei Probleme :-)

Aber es hat den Zweck erfüllt, sodass ich mich der nächsten Herausforderung stellen konnte. Viel Glück bei Ihrem Projekt!

Nachdem man sich Chevrotain und seine Skip-Option angeschaut hat , ist so etwas sehr wünschenswert.

Zu oft schreiben wir so etwas:

Pattern = head:PatternPart tail:( WS "," WS PatternPart )*
{
  return {
    type: 'pattern',
    elements: buildList( head, tail, 3 )
  };
}

Wäre cool, wenn wir stattdessen Folgendes schreiben könnten:

WS "whitespace" = [ \t\n\r] { return '@<strong i="11">@skipped</strong>' }

IgnoredComma = "," { return '@<strong i="12">@skipped</strong>' }

Pattern = head:PatternPart tail:( WS IgnoredComma WS PatternPart )*
{
  return {
    type: 'pattern',
    elements: [head].concat(tail)
  };
}

@richb-hanover, und alle anderen, die auf der Suche nach einem ähnlichen Bedarf hierher gekommen sind, habe ich auch meine eigenen Parser geschrieben: https://www.npmjs.com/package/asn1exp und https://www.npmjs. com/package/asn1-tree

Ein Überspringen wäre relativ einfach mit es6 symbol zu implementieren, oder vielleicht dauerhafter, indem dem Parser zum Zeitpunkt des Parsens ein Prädikat übergeben wird (ich bevorzuge die letztere Option).

Bin auch gerade darüber gestolpert.
Da ich nichts über das Innere von PEG.js weiß, lass mich einen Knochen da draußen werfen ...

Wenn wir eine Regel schreiben, können wir am Ende einen Rückgabeblock hinzufügen.
In diesem Block können wir Dinge wie text() und location() aufrufen. Dies sind interne Funktionen.

Irgendwo im Code geht der zurückgegebene Wert dieses Blocks in den Ausgabestream.

Was müsste also in PEG.js geändert werden, wenn ich einen von einer Regel zurückgegebenen Wert überspringen möchte, wenn dieser Wert die Rückgabe eines Aufrufs einer lokalen skip Funktion ist?

zB comment = "//" space ([^\n])* newline { return skip() }

Wie oben erwähnt, könnte skip() ein Symbol zurückgeben, das dann irgendwo vom Code überprüft und entfernt wird.
Etwas wie das, was lzhaki gesagt hat, aber intern in der Bibliothek

Ich verstehe deine Frage nicht. Suchen Sie nach einer Möglichkeit, unter bestimmten Umständen gegen eine Regel zu verstoßen? Verwenden Sie &{...} oder !{...} . Andernfalls verwenden Sie einfach nicht den zurückgegebenen Wert der Regel comment :

seq = comment r:another_rule { return r; };
choice = (comment / another_rule) { <you need to decide what to return instead of "comment" result> };

Wenn es jemandem hilft, ignoriere ich Leerzeichen, indem ich meine oberste Regel das Array der Ergebnisse filtern lasse.

Beispiel:

    = prog:expression+ {return prog.filter(a => a)}

expression
    = float
    / number
    / whitespace

float
    = digits:(number"."number) {return parseFloat(digits.join(""),10)}

number 
    = digits:digit+ {return parseInt(digits.join(""),10)}

digit 
    = [0-9]

whitespace
    = [ \t\r\n] {return undefined}

Dadurch wird die Eingabe glücklich geparst, während Leerzeichen aus dem Ergebnisarray herausgehalten werden.
Dies funktioniert auch für Dinge wie Kommentare, lassen Sie einfach die Regel undefiniert zurückgeben und die Regel der obersten Ebene filtert sie heraus

Das funktioniert nur bei Top-Level-Produktionen. Sie müssen jedes Elternteil, das ein filterbares Kind enthalten könnte, manuell filtern.

@StoneCypher Es stimmt, es erfordert einige Arbeit auf höchster Ebene, aber es funktioniert für mich, und ich denke, solange die Gamma nicht zu komplex ist, sollte man mit einem Filter auf höchster Ebene davonkommen.

Abgesehen davon kann ich mir nur eine Funktion auf oberster Ebene vorstellen, die Leerzeichen aus der Eingabe filtert und jede Übereinstimmung durchläuft. Sicher langsamer und erfordert viel mehr Aufrufe, aber einfach, wenn Sie (wie ich) alles an einen Token-Generator übergeben. Sie können die Filterfunktion aufrufen, von der aus Sie Token generieren, und müssen sich nur um die Generierung Ihrer Token kümmern und der Whitespace wird mehr oder weniger automatisch gefiltert

Eines der Dinge, die mir am aktuellen HEAD von pegjs gefallen haben, ist seine (undokumentierte) Unterstützung für die Auswahl von Feldern, ohne Labels erstellen und Rückgabeanweisungen ausführen zu müssen. Es sieht aus wie das:

foo = <strong i="6">@bar</strong> _ <strong i="7">@baz</strong>
bar = $"bar"i
baz = $"baz"i
_ = " "*
parse('barbaz') // returns [ 'bar', 'baz' ]

Ich habe das Gefühl, dass dies eine schöne, saubere und explizite Syntax für diesen Anwendungsfall und eine Reihe anderer bietet.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen