it-swarm.com.de

Wie werden Kommentare normalerweise analysiert?

Wie werden Kommentare in Programmiersprachen und Markups allgemein 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.

Sollte 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, noch suche ich nach Meinungen, aber ich suche, ob: Gibt es einen allgemeinen Konsens darüber, was ein Markup in Bezug auf Token und neue Zeilen im Allgemeinen erwartet?


Mein besonderer Kontext ist ein Wiki-ähnliches Markup.

31
Sled

Normalerweise werden Kommentare im Rahmen des Tokenisierungsprozesses gescannt (und verworfen), jedoch vor dem Parsen. Ein Kommentar funktioniert wie ein Token-Trennzeichen, auch wenn kein Leerzeichen um ihn herum vorhanden ist.

Wie Sie hervorheben, heißt es in der C-Spezifikation ausdrücklich, dass Kommentare durch ein einzelnes Leerzeichen ersetzt werden. Es ist jedoch nur eine Spezifikationssprache, da ein realer Parser eigentlich nichts ersetzt, sondern nur einen Kommentar auf die gleiche Weise scannt und verwirft, wie er Leerzeichen 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 Auswirkung haben. Sprachen, die empfindlich auf Zeilenumbrüche reagieren (Python und Visual Basic), haben normalerweise keine mehrzeiligen Kommentare, aber JavaScript ist eine Ausnahme. Zum Beispiel:

return /*
       */ 17

Ist äquivalent zu

return 17

nicht

return
17

Einzeilige Kommentare behalten den Zeilenumbruch bei, d.h.

return // single line comment
    17

ist äquivalent zu

return
17

nicht

return 17

Da Kommentare gescannt, aber nicht analysiert werden, neigen sie dazu, nicht zu verschachteln. Damit

 /*  /* nested comment */ */

ist ein Syntaxfehler, da der Kommentar vom ersten /* geöffnet und vom ersten */ geschlossen wird.

40
JacquesB

Um die Frage zu beantworten:

gibt es einen allgemeinen Konsens darüber, was ein Aufschlag allgemein erwartet?

Ich würde sagen, niemand würde erwarten, dass ein in ein Token eingebetteter Kommentar legal ist.

Als Faustregel gilt, dass Kommentare genauso behandelt werden wie Leerzeichen. Jeder Ort, an dem überflüssige Leerzeichen vorhanden sind, sollte auch einen eingebetteten Kommentar enthalten. Die einzige Ausnahme wären Zeichenfolgen:

trace("Hello /*world*/") // should print Hello /*world*/

Es wäre ziemlich seltsam, Kommentare in Strings zu unterstützen, und würde es mühsam machen, ihnen zu entkommen!

9
Connor Clark

In Leerzeichen-unempfindlichen Sprachen begrenzen ignorierte Zeichen (d. H. Leerzeichen oder solche, die Teil eines Kommentars sind) Token.

So sind zum Beispiel Sys tem Zwei Token, während System eins ist. Die Nützlichkeit davon könnte offensichtlicher sein, wenn Sie new Foo() und newFoo() vergleichen, von denen eine eine Instanz von Foo erstellt, während die andere newFoo aufruft .

Kommentare können dieselbe Rolle spielen wie eine Reihe von Leerzeichen, z. new/**/Foo() funktioniert genauso wie new Foo(). Natürlich kann dies komplexer sein, z. new /**/ /**/ Foo() oder so weiter.

Technisch sollte es möglich sein, Kommentare innerhalb von Bezeichnern zuzulassen, aber ich bezweifle, dass dies besonders praktisch ist.

Was ist nun mit weißraumempfindlichen Sprachen?

Python fällt mir ein und es gibt 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 vorhanden wäre, sondern nur eine neue Zeile.

Im Gegensatz dazu Jade erlaubt Blockkommentare , wobei der Block endet, wenn Sie zur gleichen Einrückungsstufe zurückkehren. Beispiel:

body
  //-
    As much text as you want
    can go here.
  p this is no longer part of the comment

In diesem Bereich würde ich nicht sagen, dass man sagen könnte, wie Dinge normalerweise gehandhabt werden. Was eine Gemeinsamkeit zu sein scheint, ist, dass ein Kommentar immer mit einem Zeilenende endet, was bedeutet, dass alle Kommentare genau so wirken wie neue Zeilen.

7
back2dos

In der Vergangenheit habe ich Kommentare als Teil der lexikalischen Analyse in ein einziges Token umgewandelt. Gleiches gilt für Saiten. Von dort 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 behandeln. 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 einer Zeichenfolge sollte implizit von der lexikalischen Analyse behandelt werden. Die Regeln zum Behandeln einer Zeichenfolge haben kein Interesse an Kommentaren. Daher wird der Kommentar als Inhalt der Zeichenfolge behandelt. Gleiches gilt für eine Zeichenfolge (oder ein in Anführungszeichen gesetztes Literal) innerhalb eines Kommentars. Die Zeichenfolge ist Teil eines Kommentars, bei dem es sich explizit um ein einzelnes Token handelt. Die Regeln für die Verarbeitung eines Kommentars haben kein Interesse an Zeichenfolgen.

Ich hoffe das macht Sinn/hilft.

3
user202190

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 potenziell trennenden Token (z. B. Methode/Kommentar/(/ Kommentar /)). In diesem Fall wird es wie Leerzeichen behandelt.

Wenn Ihr Parser Teil eines Transpilers ist, der eine Ausgangssprache in eine andere Ausgangssprache übersetzt, oder wenn Ihr Parser ein Präprozessor ist, der eine Kompilierungseinheit in einer Ausgangssprache verwendet, sie analysiert, ändert und die geänderte Version in derselben Ausgangssprache zurückschreibt, kommentiert wie alles andere wird sehr wichtig.

Auch wenn Sie Metainformationen in Kommentaren haben und sich besonders für Kommentare interessieren, wie beim Generieren von API-Dokumentation wie JavaDoc, sind Kommentare plötzlich sehr wichtig.

Hier werden häufig Kommentare an die Token selbst angehängt. Wenn Sie einen Kommentar finden, fügen Sie ihn als Kommentar eines Tokens hinzu. Da ein Token vorher und nachher mehrere Token haben kann, hängt es wiederum vom Zweck ab, wie mit diesen Kommentaren umgegangen wird.

Die Idee, Nicht-Kommentar-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 sein eigenes AST-Element darstellen, aber neben der üblichen Include-Beziehung an ein anderes AST-Element angehängt werden. Eine gute Idee ist es Überprüfen Sie alle Parser/AST-Implementierungen auf Quellsprachen, die in der Open-Source-IDE verfügbar sind.

Eine sehr gute Implementierung ist die Eclipse-Compiler-Infrastruktur für die Sprache Java. Sie behält Kommentare während der Tokenisierung bei und repräsentiert Kommentare innerhalb der AST - soweit ich mich erinnere. Außerdem behält diese Parser/AST-Implementierung die Formatierung bei.

1
Martin Kersten