Dienstag, 9. Oktober 2012

Syntax von Reni. Teil 1: Die Zerschnippelung in Tokens

Heute werde ich mal einige Grundlagen der Programmiersprache Reni vorstellen.
Was man braucht, um zu programmieren, ist ein Text, den man "Das Programm" nennt. Der Text muss bestimmten Regeln gehorchen, sonst meckert der Compiler. Oder aber er meckert nicht, aber wenn das Programm dann laufen soll, tut es nicht das, was es soll oder stürzt gar ab.
Die erste Sorte von Regeln nennt man, grob gesprochen, Syntaxregeln. Die zweite Sorte betrifft die sogenannte Semantik. Da komme ich später dazu.
Die simpelste, grundlegendste Regel: Ein Programm besteht aus eine Folge von Zeichen, die durch bestimmte Regeln in Tokens, das sind so etwas wie Worte, zergliedert werden. Das ist eigentlich keine grosse Sache, aber es ist gut, das wenigstens einmal hin zu schreiben.
Um diese Regeln zu erklären, müssen wir zunächst über Zeichentypen sprechen. Das sind:

  • Leerzeichen, Tabulator, Zeilenumbruch heissen Whitespaces
  • Alle Klammern, Komma, Semikolon und Ausrufezeichen heissen Syntaxzeichen
  • Buchstaben, Zahlen und der Unterstrich heissen alphanumerische Zeichen
  • Einfaches und doppeltes Hochkomma sind Stringbegrenzer (kommen wir noch dazu)
  • Das Doppelkreuz, auch Hashzeichen oder auch Gartenzaun ist das Kommentarzeichen (kommen wir auch noch dazu)
  • Alle anderen Zeichen (Hier mal eine Auswahl der wichtigsten: ^°§$%&/=?\+*@~<.->|) heissen Symbolzeichen

Jetzt können wir die Tokenbildungsregeln angeben:

  • Whitespaces trennen Token, sind aber selbst keine Token.
  • Syntaxzeichen trennen Token und sind auch selbst Token
  • Alphanumerische Zeichen bilden Token, wenn sie eine ununterbrochene Folge bilden
  • Auch Symbolzeichen bilden Token, wenn sie eine ununterbrochene Folge bilden
  • Ein Wechsel von alphanumerischen Zeichen zu Symbolzeichen oder umgekehrt trennt Token
Da kommt noch mehr, aber erstmal will ich diese Regeln durch ein paar Beispiele verdeutlichen:

Hello world123   123
dump_print
Die Token sind hier: "Hello", "world123", "123" und "dump_print". 


(Hello[world123,123;dump_print
Die Token sind hier: Runde Klammer auf, "Hello", eckige Klammer auf, "world123", Komma, "123", Semikolon und wieder "dump_print". 

Hello<<world123*123=:=dump_print
Die Token sind hier: "Hello", "<<", "world123", "*", "123", "=:=" und schließlich wieder "dump_print". 

Was jetzt noch fehlt, sich Strings und Kommentare. 
Beide trennen Tokens und Strings sind selbst auch Tokens. 
Strings sind fast beliebige Zeichenfolgen, die durch jeweils einen Stringbegrenzer vorne und hinten  begrenzt werden. Nomen est omen! Der Stringbegrenzer muß vorne und hinten der gleiche sein. Also gibt es somit zwei Arten von Strings: die die mit einfachem Hochkomma begrenzt werden und die mit einem doppelten. Aber keine Panik, das macht keinen Unterschied. 
Naja, fast keinen.   
"Fast beliebige Zeichenfolgen" bedeutet, dass natürlich der jeweils benutzte Stringbegrenzer nicht so einfach vorkommen kann. Aber er kann vorkommen - dann muss man ihn aber doppelt schreiben. Auch ist es verboten, einen Zeilenumbruch mitten im String vorkommen zu lassen. Wenn man das mal braucht, muss man sich anders helfen. Aber das kommt später (viel später). 
Ok, jetzt wieder ein paar Beispiele:

"Hello world"dump_print
Die Token sind hier: der String "Hello world" und schließlich wieder unser gutes altes "dump_print". 

'Hello world'dump_print
Dasselbe. Ist hier egal ob einfache oder doppelte Hochkommas. 

"it's cool man"dump_print
Die Token sind hier: der String "it's cool man" und wieder "dump_print".

'it''s cool man'dump_print
Dasselbe. Jedoch mussten wir hier das Hochkomma verdoppeln, weil der Begrenzer schon das einfache Hochkomma ist. Aber Achtung: es zählt trotzdem nur als eines.

Wenn man mal ein kompliziertes, schwer lesbares oder schwer verständliches Programm vorfinden sollte, kann man das durch sogenanntes Refactoring in ein weniger kompliziertes, besser lesbares oder leichter verständliches Programm verwandeln.
Oder man verwendet Kommentare, um das Spaghettimonster irgendwie zu beschreiben.
Ich empfehle die erste Methode, aber die geht nicht immer. Deshalb gibts auch in Reni Kommentare.
Kommentare beginnen mit einem Kommentarzeichen (#). Es gibt gleich zwei Sorten von Kommentaren: Zeilenkommentare reichen bis zum Ende der Zeile. Blockkommentare reichen bis zum Kommentarende-Zeichen. Die Blockkommentare erkennt man daran, dass nach dem Kommentarzeichen eine öffnende Klammer steht und dann noch ein Kommentarbezeicher folgt. Der wird verwendet, um das Ende des Kommentars zu finden. Das ist am einfachsten mit Beispielen zu illustrieren:
"Hello world" #(* Das ist ein Kommentar *)#dump_print  
Der  Kommentarbezeicher ist hier der Stern. Man kann jedes Symbol hier verwenden aber auch Namen, also Folgen von Buchstaben. Beispiel:
"Hello world" #(ignorieren Das ist ein Kommentar ignorieren)#dump_print  
Der  Kommentarbezeicher ist hier das Wort "ignorieren". 
Wozu man das braucht? Na Ihr werdet schon sehen...

Zum Schluß noch ein Beispiel für Zeilenkommentare, der Vollständigkeit halber:
"Hello world" # Das ist der auszugebende String
dump_print # ... und damit wird er ausgegeben   

Für den Compiler sind Kommentare nichts anderes als Leerzeichen. Er verwendet sie, wenn nötig als Trenner zweier Tokens, aber ansonsten werden sie ignoriert.

Den Einstieg haben wir jetzt. Das war vielleicht etwas "urschleimig". Und nix mit richtig programmieren. Aber es musste mal gesagt werden. 
Denn...
Ich hatte da mal so ein traumatisches Erlebnis. Es war Ende der Neunziger. Die "Programmiersprache" hieß "Base SAS". Und die hat großzügig auf solche schnöden Beschreibungen verzichtet. Das Ende vom Lied war, dass man in etwas kniffligeren Fällen (und die kommen bei echten Anwendungen garantiert) nie so richtig wusste, wie die Syntax genau definiert war. Ich habe mir damals geschworen, so etwas nie niemals zu tun.

Keine Kommentare:

Kommentar veröffentlichen