Frage

Wie löst ein Lexer diese Mehrdeutigkeit?

/*/*/

Wie kommt es, dass es nicht nur sagt, oh ja, das ist der Beginn eines mehrzeiligen Kommentars, gefolgt von einem weiteren multi-line-Kommentar.

Würde ein gieriger Lexer nicht nur die folgenden Token zurückgeben?

  • /*
  • /*
  • /

Ich bin gerade dabei, einen Shift-Reduce-Parser für CSS zu schreiben, und doch ist mir diese einfache Kommentarsache im Weg. Du kannst lesen diese Frage Wenn Sie keine weiteren Hintergrundinformationen haben.

AKTUALISIEREN

Tut mir leid, dass ich das überhaupt ausgelassen habe. Ich plane, der CSS -Sprache in dieser Form Erweiterungen zu erweitern /* @ func ( args, ... ) */ Aber ich möchte keinen Redakteur verwirren, der CSS versteht, aber nicht diese Erweiterungskommentar von mir. Deshalb kann der Lexer Kommentare einfach nicht ignorieren.

War es hilfreich?

Lösung

Eine Möglichkeit, dies zu tun /*. Zum Beispiel, flex Ruft diese an "Startbedingungen" (Übereinstimmende Kommentare im C-Stil sind eines der Beispiele auf dieser Seite).

Andere Tipps

Der einfachste Weg wäre wahrscheinlich, den Kommentar als ein einzelnes Token zu Lex - dh ein "Start -Kommentar" -Token aus, sondern lesen Sie stattdessen weiter in Eingaben, bis Sie einen "Kommentarblock" ausgeben können, der das gesamte enthält /*(anything)*/ bisschen.

Da Kommentare für die tatsächliche Parsen von ausführbarem Code nicht relevant sind, ist es in Ordnung, im Grunde genommen vom Lexer auszuziehen (oder zumindest in ein einzelnes Token verklumft). Innerhalb eines Kommentars ist es Ihnen egal, Token -Matches zu machen.

In den meisten Sprachen ist dies nicht mehrdeutig: Der erste Schrägstrich und der Asterix sind verbraucht zum Erstellen des "Beginns des mehrzeiligen Kommentars" -Token. Es folgt ein Schrägstrich, der einfach "Inhalt" im Kommentar ist, und schließlich sind die letzten beiden Zeichen das "Ende des Multi-Line-Kommentars" -Token.

Da die ersten 2 Zeichen konsumiert werden, kann der erste Asterix nicht auch verwendet werden, um ein Ende des Kommentars zu erstellen. Ich habe gerade festgestellt, dass es einen zweiten "Start of Comment" -Token erzeugen könnte ... oops, das könnte ein Problem sein, abhängig vom Kontext ist für den Parser verfügbar.

Ich spreche hier von Tokens, unter der Annahme einer Parser-Ebene der Kommentare. Das Gleiche gilt jedoch für einen Lexer, wobei die zugrunde liegende Regel mit beginnen soll '/*' und dann nicht bis zur Tille '*/' gefunden. Effektiv würde eine Handhabung des gesamten Kommentars auf Lexerebene durch den zweiten "Start des Kommentars" nicht verwechselt.

Verwenden Sie den Algorithmus des Regexp und suchen Sie vom Beginn der Zeichenfolge zurück zum aktuellen Standort.

if (chars[currentLocation] == '/' and chars[currentLocation - 1] == '*') {
  for (int i = currentLocation - 2; i >= 0; i --) {
    if (chars[i] == '/' && chars[i + 1] == '*') {
      // .......
    }
  }
}

Es ist, als würde man den Regexp anwenden /\*([^\*]|\*[^\/])\*/ gierig und boden.

Eine Möglichkeit, dies zu lösen, besteht darin, dass Ihre Lexer -Rückkehr:

/
*
/
*
/

Und lassen Sie Ihren Parser von dort aus damit umgehen. Das würde ich wahrscheinlich tun Für die meisten Programmiersprachen, wie die /'s *' s können auch für die Multiplikation und andere solche Dinge verwendet werden, die nur zu kompliziert sind, als dass der Lexer sich Sorgen machen kann. Der Lexer sollte wirklich nur zurückkehren elementare Symbole.

Wenn das Token zu sehr vom Kontext abhängt, ist das, was Sie suchen, möglicherweise ein einfacheres Token.

Davon abgesehen ist CSS keine Programmiersprache. Wirklich Afaik, sie können nicht für etwas anderes als Kommentare verwendet werden. Ich wäre also sehr versucht, das Ganze nur als Kommentar -Token zu bestehen, es sei denn, Sie haben einen guten Grund, nicht: /\*.*\*/

Da CSS keine verschachtelten Kommentare unterstützt, würde Ihr Beispiel normalerweise zu einem einzigen Token analysiert, COMMENT. Das heißt, der Lexer würde sehen /* als Start-Coment-Marker und dann alles bis einschließlich a */ Reihenfolge.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top