2. Beispiel: Reguläre Definition

  • Angabe
  • Lösung
  • Erklärung
  • Angabe

    Ein URL (Uniform Resource Locator) gibt die Adresse eines Objekts im World Wide Web an. Er besteht aus der Zugriffsart (hp, ftp, gopher, mailto, news) gefolgt von einem Doppelpunkt ":" und einer genaueren Beschreibung des Objekts, abhängig von der Zugriffsart.

    Bei http, ftp und gopher folgen zwei Schrägstriche "//", ein Hostname und ein Zugriffspfad.

    Ein Hostname besteht entweder aus vier Zahlen mit maximal drei Ziffern, getrennt durch einen Punkt (z.B. 128.130.173.8) oder aus einer beliebigen Anzahl von Buchstabengruppen (Groß- und Kleinbuchstaben und "-") getrennt durch einen Punkt (der Hostname muß in diesem Fall mit einem Buchstaben beginnen, z.B. ftp.uni-paderborn.de).

    Ein Zugriffspfad ist vom Hostname durch einen Schrägstrich getrennt. Er besteht aus beliebig vielen (nicht leeren) Filenamen, die durch Schrägstriche getrennt sind und darf auch mit einem Schrägstrich enden.

    Ein Filename besteht aus beliebig vielen Groß- und Kleinbuchstaben, "-" und ".".

    Bei der Zugriffsart news folgt nach dem Doppelpunkt nur ein Hostname. Bei mailto folgt nach dem Doppelpunkt ein Name, ein "@" und ein Hostname. Ein Name besteht aus beliebig vielen Groß- und Kleinbuchstaben.

    Lösung

    ziff = [0-9]
    zahl = ziff ziff? ziff?
    bst = [a-z]|[A-Z]
    ip = zahl "." zahl "." zahl "." zahl
    hn = bst (bst|"-")* ("." (bst|"-")+)*
    host = ip|hn
    file = (bst|"-"|".")+
    pfad = file ("/" file)* "/"?
    art = "http"|"ftp"|"gopher"
    URL = (art "://" host ("/" pfad)|("/"?)) | ("news:" host) | ("mailto:" bst+ "@" host)

    Erklärung

    Bei einer regulären Definition ist es wichtig, innen anzufangen und sich langsam nach außen vorzuarbeiten. Die dabei entstehenden Bausteine werden dann für die weiteren Definitionen verwendet.

    Die erste ins Auge fallenden Bausteine sind der Hostname der entweder aus Zahlen- oder aus Buchstabengruppen bestehen kann:

    Ein Hostname besteht entweder aus vier Zahlen mit maximal drei Ziffern, getrennt durch einen Punkt (z.B. 128.130.173.8) oder aus einer beliebigen Anzahl von Buchstabengruppen (Groß- und Kleinbuchstaben und "-") getrennt durch einen Punkt (der Hostname muß in diesem Fall mit einem Buchstaben beginnen, z.B. ftp.uni-paderborn.de).

    Eine Zahl besteht also aus maximal drei Ziffern. Da die vier Zahlen ihrerseits durch einen Punkt getrennt sind bedeutet das, daß eine Zahl aus mindestens einer Ziffer bestehen muß. Eine Trennung hätte ja sonst keinen Sinn. Daraus ergeben sich die Definitionen ziff = [0-9] und zahl = ziff ziff? ziff?. Eine Zahl besteht also aus einer Ziffer gefolgt von zwei optionalen Ziffern. Über den Wertebereich einer Zahl wird keine Aussage gemacht. Das "Metawissen", daß eine IP-Adresse (derzeit) nur mit Zahlen im Bereich von 0 bis 255 arbeitet ist hier ohne Belang. Die gesamte IP-Adresse ist eine Aneinanderreihung von Zahlen, getrennt durch einen Punkt: ip = zahl "." zahl "." zahl "." zahl

    Die zweite Alternative für den Hostname ist ein Name bestehend aus Buchstabengruppen die durch Punkt getrennt sind. Die Buchstabengruppen dürfen zwar auch einen Bindestrich enthalten, der ganze Hostname muß jedoch mit einem Buchstaben beginnen. Wir definieren daher zuerst einen Einzelbuchstaben durch bst = [a-z]|[A-Z]. Der ganze Name hn beginnt also mit einem bst und erst dann dürfen Buchstaben und Bindestriche in beliebiger Kombination vorkommen: (bst|"-")*. Weitere Buchstabengruppen sind durch Punkt getrennt: ("." (bst|"-")+)*

    Anmerkung: Die Aneinanderreihung von Termen und Trennzeichen kommt sehr häfig vor. Eine übliche Konstruktion ist term (trenn term)*, also mindestens ein Term und beliebig viele Wiederholungen von Trennzeichen und weiteren Termen.

    Der ganze Hostname ist durch host = ip|hn definiert.

    Die Zugriffsarten news und mailto lassen sich mit den vorangegangenen Bausteinen direkt aus der Textbeschreibung ableiten:

    Bei der Zugriffsart news folgt nach dem Doppelpunkt nur ein Hostname. Bei mailto folgt nach dem Doppelpunkt ein Name, ein "@" und ein Hostname. Ein Name besteht aus beliebig vielen Groß- und Kleinbuchstaben.

    Daraus ergeben sich "news:" host bzw. "mailto:" bst* "@" host

    Anmerkung: Natürlich kann man auch argumentieren, daß der Name in einer Mailadresse immer mindestens einen Buchstaben haben muß, also bst+ statt bst*. Beide Varianten sind richtig, da keine weiteren Einschränkungen bezüglich des Namens gemacht wurden.

    Die Beschreibung des Zugriffspfades muß man sehr genau lesen, um sie richtig zu übersetzen:

    Ein Zugriffspfad ist vom Hostname durch einen Schrägstrich getrennt. Er besteht aus beliebig vielen (nicht leeren) Filenamen, die durch Schrägstriche getrennt sind und darf auch mit einem Schrägstrich enden.

    Die Filenamen sind noch das Einfachste. Sie bestehen aus beliebig vielen Buchstaben, "-" und ".", sind aber nicht leer also file = (bst|"-"|".")+. Der ganze Zugriffspfad besteht jedoch aus beliebig vielen, durch "/" getrennten Filenamen und darf mit einem "/" enden. D.h., der ganze Pfad kann auch leer sein. Daraus ergibt sich pfad = file ("/" file)* "/"?

    Beim Zusammensetzen der vollständigen Definition müssen wir noch eine Ungereimtheit beseitigen:

    Ein Zugriffspfad ist vom Hostname durch einen Schrägstrich getrennt.

    Wie wir gesehen haben, kann der Zugriffspfad auch leer sein. Eine Trennung von etwas Leerem macht jedoch keinen Sinn. Gleichzeitig darf der Pfad nur mit einem "/" enden. Eine Definition die beide Fälle berücksichtigt ist in der Lösung gegeben. Sie lautet: host ("/" pfad)|("/"?) und vermeidet damit zwei Schrägstriche direkt nebeneinander.

    Die Aneinanderreihung der alternativen Zugriffsarten ergibt schließlich die endgültige Lösung.

    Von Wolfgang Faber kommt der Hinweis an alle, die nach diesem Beispiel laut aufstöhnen, einmal einen Blick in die Originalspezifikation zu werfen. :-)


    Alex's University Page / Alex's Home Page / alex@complang.tuwien.ac.at
    TEL +43 1 58801-4463, FAX +43 1 5057838