Wie werden Kommentare generell in Programmiersprachen und Markups behandelt? Ich schreibe einen Parser für eine benutzerdefinierte Auszeichnungssprache und möchte dem Prinzip der geringsten Überraschung folgen , also versuche ich, die allgemeine Konvention zu bestimmen.
Soll beispielsweise ein in ein Token eingebetteter Kommentar das Token stören oder nicht? Im Allgemeinen ist so etwas wie:
Sys/* comment */tem.out.println()
gültig?
Wenn die Sprache für neue Zeilen empfindlich ist und der Kommentar die neue Zeile umfasst, sollte die neue Zeile berücksichtigt werden oder nicht?
stuff stuff /* this is comment
this is still comment */more stuff
behandelt werden als
stuff stuff more stuff
oder
stuff stuff
more stuff
?
Ich weiß, was einige bestimmte Sprachen tun, und ich suche auch nach Meinungen, aber ich suche, ob es einen allgemeinen Konsens darüber gibt, was von einem Aufschlag in Bezug auf Token und neue Zeilen im Allgemeinen erwartet wird oder nicht.
Mein besonderer Kontext ist ein Wiki-ähnliches Markup.
Antworten:
Normalerweise werden Kommentare als Teil des Tokenisierungsprozesses gescannt (und verworfen), jedoch vor dem Parsen. Ein Kommentar funktioniert wie ein Token-Trennzeichen, auch wenn kein Leerzeichen in der Nähe steht.
In der C-Spezifikation wird ausdrücklich darauf hingewiesen, dass Kommentare durch ein einzelnes Leerzeichen ersetzt werden. Es ist jedoch nur eine Spezifikationssprache, da ein Parser aus der realen Welt eigentlich nichts ersetzt, sondern einen Kommentar genauso scannt und verwirft, wie er Whitespace-Zeichen scannt und verwirft. Aber es erklärt auf einfache Weise, dass ein Kommentar Token genauso trennt wie ein Leerzeichen.
Der Inhalt von Kommentaren wird ignoriert, sodass Zeilenumbrüche in mehrzeiligen Kommentaren keine Auswirkungen haben. Sprachen, die empfindlich auf Zeilenumbrüche reagieren (Python und Visual Basic), enthalten normalerweise keine mehrzeiligen Kommentare, aber JavaScript ist eine Ausnahme. Beispielsweise:
Ist äquivalent zu
nicht
Einzeilige Kommentare erhalten den Zeilenumbruch
ist äquivalent zu
nicht
Da Kommentare gescannt, aber nicht analysiert werden, besteht die Tendenz, dass sie nicht verschachtelt werden. So
ist ein Syntaxfehler, da der Kommentar vom ersten geöffnet und vom ersten
/*
geschlossen wird*/
quelle
/* like this */
) als ein Leerzeichen und Kommentare mit EOL-Abschluss (// like this
) als eine Leerzeile betrachtet.(define x #| this is #| a sub-comment |# the main comment |# 3) x
Erträge3
.Um die Frage zu beantworten:
Ich würde sagen, keiner würde erwarten, dass ein in ein Token eingebetteter Kommentar legal ist.
Als Faustregel gilt, dass Kommentare wie Leerzeichen behandelt werden sollten. Jeder Ort, an dem Leerzeichen zulässig wären, sollte auch einen eingebetteten Kommentar enthalten. Die einzige Ausnahme wären Strings:
Es wäre ziemlich seltsam, Kommentare in Zeichenfolgen zu unterstützen, und würde es mühsam machen, sie zu umgehen!
quelle
Hello /* world*/!
anstatt die Kommentarbegrenzer zu unterdrücken. Willkommen auch bei Programmierern!In whitespace-unempfindlichen Sprachen werden Token durch ignorierte Zeichen (dh Leerzeichen oder solche, die Teil eines Kommentars sind) begrenzt.
So sind zum Beispiel
Sys tem
zwei Token, währendSystem
einer ist. Die Nützlichkeit dieser Funktion wird möglicherweise deutlicher, wenn Sie einen Vergleich anstellennew Foo()
undnewFoo()
einer davon eine Instanz von erstellt,Foo
während der andere aufruftnewFoo
.Kommentare können die gleiche Rolle spielen wie eine Folge von Leerzeichen, zB
new/**/Foo()
wienew Foo()
. Dies kann natürlich komplexer sein, znew /**/ /**/ Foo()
. B. oder so.Technisch sollte es möglich sein, Kommentare innerhalb von Bezeichnern zuzulassen, aber ich bezweifle, dass dies besonders praktisch ist.
Was ist nun mit weißraumsensiblen Sprachen?
Python fällt mir ein und hat eine sehr einfache Antwort: Keine Blockkommentare. Sie beginnen einen Kommentar mit
#
und dann funktioniert der Parser genau so, als ob der Rest der Zeile nicht existiert hätte, sondern nur eine neue Zeile wäre.Im Gegensatz dazu erlaubt Jade Blockkommentare , bei denen der Block endet, wenn Sie zur gleichen Einrückungsstufe zurückkehren. Beispiel:
In diesem Bereich würde ich nicht sagen, dass man sagen kann, wie die Dinge normalerweise gehandhabt werden. Es scheint eine Gemeinsamkeit zu sein, dass ein Kommentar immer mit einem Zeilenende endet, dh, alle Kommentare verhalten sich genauso wie neue Zeilen.
quelle
In der Vergangenheit habe ich Kommentare als Teil der lexikalischen Analyse zu einem einzigen Token gemacht. Gleiches gilt für Streicher. Von dort aus ist das Leben einfach.
Im speziellen Fall des letzten von mir erstellten Parsers wird eine Escape-Regel an die Analyseroutine der obersten Ebene übergeben. Die Escape-Regel wird verwendet, um Token wie Kommentartoken in Übereinstimmung mit der Kerngrammatik zu verarbeiten. Im Allgemeinen wurden diese Token verworfen.
Dies hat zur Folge, dass in dem Beispiel, das Sie mit einem Kommentar in der Mitte eines Bezeichners gepostet haben, der Bezeichner kein einzelner Bezeichner ist - dies ist das erwartete Verhalten in allen Sprachen (aus dem Speicher), mit denen ich gearbeitet habe .
Der Fall eines Kommentars innerhalb eines Strings sollte implizit von der lexikalischen Analyse behandelt werden. Die Regeln für den Umgang mit einer Zeichenfolge haben kein Interesse an Kommentaren. Daher wird der Kommentar als Inhalt der Zeichenfolge behandelt. Dasselbe gilt für eine Zeichenfolge (oder ein Literal in Anführungszeichen) innerhalb eines Kommentars. Die Zeichenfolge ist Teil eines Kommentars, bei dem es sich explizit um ein einzelnes Token handelt. Die Regeln für die Bearbeitung eines Kommentars haben kein Interesse an Strings.
Ich hoffe das macht Sinn / hilft.
quelle
console.log(/*a comment containing "quotes" is possible*/ "and a string containing /*slash-star, star-slash*/ is possible")
Anführungszeichen in einem Kommentar und Kommentarsyntax in einer Zeichenfolge, woher sollte der Lexer wissen, ob er den Code korrekt token kann? Können Sie bitte Ihre Antwort mit einer allgemeinen Beschreibung dieser Fälle bearbeiten?Es hängt davon ab, welchen Zweck Ihr Parser hat. Wenn Sie einen Parser schreiben, um einen Analysebaum zum Kompilieren zu erstellen, hat ein Kommentar keinen semantischen Wert neben den potenziellen Trennzeichen (z. B. method / comment / (/ comment /)). In diesem Fall werden sie wie Leerzeichen behandelt.
Wenn Ihr Parser Teil eines Transpilers ist, der eine Quellensprache in eine andere Quellensprache übersetzt, oder wenn Ihr Parser ein Präprozessor ist, der eine Kompilierungseinheit in einer Quellensprache analysiert, sie modifiziert und die modifizierte Version in dieselbe Quellensprache zurückschreibt, kommentiert wie alles andere wird sehr wichtig.
Auch wenn Sie Metainformationen in Kommentaren haben und sich besonders für Kommentare interessieren, wie dies bei der Erstellung von API-Dokumentationen wie in JavaDoc der Fall ist, sind Kommentare plötzlich sehr wichtig.
Hier werden Kommentare häufig an die Tokens selbst angehängt. Wenn Sie einen Kommentar finden, fügen Sie ihn als Kommentar eines Tokens hinzu. Da ein Token davor und danach mehrere Token haben kann, ist es wiederum zweckabhängig, wie mit diesen Kommentaren umgegangen wird.
Die Idee, Nichtkommentar-Token mit Kommentaren zu versehen, besteht darin, Kommentare vollständig aus der Grammatik zu entfernen.
Sobald Sie den Analysebaum haben, beginnen einige AST, Kommentare zu entpacken, die jedes Token durch ein eigenes AST-Element darstellen, aber an ein anderes AST-Element neben der üblichen Contain-Beziehung angehängt werden. Eine gute Idee ist es, alle Parser / AST-Implementierungen auf Quellsprachen zu überprüfen, die in Open-Source-IDE verfügbar sind.
Eine sehr gute Implementierung ist die Eclipse-Compiler-Infrastruktur für die Java-Sprache. Sie behalten Kommentare während der Tokenisierung bei und repräsentieren Kommentare innerhalb des AST - soweit ich mich erinnere. Diese Parser / AST-Implementierung behält auch die Formatierung bei.
quelle