2014-01-15 Pattern Matching: Alte Schriften und Programmcode ------------------------------------------------- markus schnalke [Basierend auf einer Email. Leicht angepasst.] Ich bin vom Kurs Schriftgeschichte ja ganz gross begeistert! [...] Als Nicht-Historiker und Nicht-Lateiner tue ich mir natuerlich etwas schwerer mit den Leseuebungen. Aber nach einiger Gewoehnungzeit ging's doch ganz gut. Da ist mir bewusst geworden, dass diese Schrift fuer mich nicht anders ist als Programmcode fuer euch. Anfangs ist es nur eine Masse von unverstaendlicher Information (Hacker nennen sowas gerne ``blob''), irgendwelche Striche halt. Was den Unterschied macht zwischen denjenigen, die den InformationsGEHALT erkennen, und denjenigen, die nur die InformationsGESTALT erkennen, ist, dass die ersten (neben ein bisschen Faktenwissen) wissen auf was sie achten muessen. Schoene Beispiele sind die N-oder-R-Frage und das cc-A, oder der Worttrenn-Mittelpunkt bei der Capitalis(?). Anfangs sieht das nur seltsam und irritierend aus oder man nimmt es gar nicht wahr, bald aber erkennt man den Informationsgehalt in der Informationsgestalt, weil man weiss worauf man achten muss. Das schnelle Erfassen der relevanten Information, das macht den Unterschied zwischen Neuling und Kenner. Mit Programmcode ist das nicht anders. Wo ihr nur eine scheinbar beliebige Menge von Zeichen seht, da sehe ich ihre Bedeutung ... weil ich eben weiss worauf ich achten muss, selbst wenn ich diese konkrete Programmiersprache nicht wirklich kenne. Ich habe ein ``Pattern Matching'' dafuer erlernt. Nicht anders ist es bei euch (inzwischen nun bei uns allen) was alte Schriften angeht, oder z.B. bei jemandem mit Musiknoten, und ueberhaupt bei jedem von uns in unserem eigenen Fachgebiet. Hat man erst mal diesen ``Blick'' erworben, dann kann man nie mehr ohne ihn sehen. Man wird beim Anblick der Information ganz automatisch den strukturellen Informationsgehalt sehen und die diesen definierende Informationsgestalt unbewusst gar nicht mehr wahrnehmen. Die Leseuebungen heute waren fuer mich eine wertvolle Erfahrung, weil sie mich daran erinnert haben, wie es ist, diesen ``Blick'' noch nicht zu haben. Eben noch nicht die relevanten Patterns matchen zu koennen. Darauf wollte ich euch aufmerksam machen. Und weil ich heute ein kleines Programm geschrieben habe, das zufaellig wunderbar hierzu passt, will ich euch nun auf eine kleine Erfahrungsreise einladen. Ich hatte eine Textdatei in der Zeilen der Form waren: 05 FIL PIC X(110) VALUE ' ******** 8 .@@@ - '@@@ 8 8 *********************************** - '****************'. 05 FIL PIC X(110) VALUE ' ******* 88 .@@@@@ - '@@@@ 8 88 ************************************** - '****************'. Die Zeilen, die mit einem Minus beginnen sind Fortsetzungen, die ich an die Anfangszeile anfuegen wollte ... automatisiert natuerlich, denn wer will schon tausende Zeilen von Hand bearbeiten? Dafuer gibt es schliesslich Computer. Die zwei mal drei Beispielzeilen sollten also zusammengehaengt und etwas zurecht gestutzt werden zu folgenden zwei Zeilen: ******** 8 .@@@@@@ 8 8 *************************************************** ******* 88 .@@@@@@@@@ 8 88 ****************************************************** Hier ist nun ein Programm fuer den Stream Editor `sed', der Text liest, umbaut und wieder ausgibt. Es erledigt die Aufgabe fuer beliebig viele Zeilen: /^-/!h;/^-/{s,^-.....,,;H;};/\. *$/{x;s,\n,,g;s,.\. *$,,;s,^.*VALUE..,,;s, *$,,;p;}; Ist euch das kryptisch genug? Traenen euch schon die Augen? ;-D Aber keine Sorge, es gibt nicht allzu viele Programmierer, die mit sowas etwas anfangen koennen. Das ist schon eine spezielle Nischenkunst, fuer die ich mich nun eben begeistere. Aber ich will nicht nur damit angeben, sondern euch schrittweise zeigen wie mein Pattern Matching hier funktioniert. Ich werde den Programmcode nun schrittweise in logische Einheiten zerlegen. 1) Ein sed-Programm besteht aus einer Folge von Suchmuster-Aktion- Paaren. Diese suche ich als erstes. Suchmuster sind durch Slashes (/) eingefasst. Aktionen sind entweder ein Einzelkommando oder eine in geschweifte Klammern eingefasste Liste von Kommandos. Als Schlusszeichen steht der Strichpunkt. Diese Zeichen wuerde ich also als erstes Suchen. Die zu findenden Patterns waeren damit: /.../ {...} ; und /.../ X ; (Die Punkte sind Platzhalter fuer Beliebiges; das X steht fuer einen Buchstaben.) Und siehe da: /^-/! h ; /^-/ {s,^-.....,,;H;} ; /\. *$/ {x;s,\n,,g;s,.\. *$,,;s,^.*VALUE..,,;s, *$,,;p;} ; 2) Kommandos in sed bestehen aus einem Buchstaben, wie z.B. das `h' in der ersten der drei Gruppen. Aktionen werden durch Strichpunkte abgeschlossen. Ich suche also folgendes Pattern in den Aktionsbloecken: X... ; Und wiederum werde ich fuendig: /^-/! h ; /^-/ { s,^-.....,, ; H ; } ; /\. *$/ { x ; s,\n,,g ; s,.\. *$,, ; s,^.*VALUE..,, ; s, *$,, ; p ; } ; (btw: Durch die optische Trennung koennte ich mir nun all die Strichpunkte sparen, sie bieten nun ja keinen Mehrwert mehr, der nicht auch durch die optische Anordnung schon gegeben waere.) 3) Nun gibt es einfache Kommandos, auf die das Pattern X ; passt und komplexere Kommandos, auf die X ... ; passt. Einfach sind `h', `H', `x', und `p'. Komplex ist `s'. Das `s'-Kommando hat wiederum ein Schema auf das eines dieser Patterns passt: s , ... , ... , ; oder s , ... , ... , g ; Das fuehrt zu: /^-/! h ; /^-/ { s , ^-..... , , ; H ; } ; /\. *$/ { x ; s , \n , , g ; s , .\. *$ , , ; s , ^.*VALUE.. , , ; s , *$ , , ; p ; } ; (Es ist Zufall, dass hier in allen Vorkommen des `s'-Kommandos der erste Komma-begrenzte Teil gefuellt ist, der zweite aber leer.) Hier koennte man euch nun erklaeren, dass das was ich fuer euch schrittweise sichtbar gemacht habe, das ist was der Computer (genauer: der Compiler/Interpreter; noch genauer: dessen Parser) auch macht: Aus einer linearen Abfolge von Zeichen wird ein Syntaxbaum erzeugt. Dieser beschreibt welcher Art die einzelnen Teile sind, ob es also Kommandos, Trennzeichen, oder Werte sind. Trennzeichen kann man dabei wegwerfen, denn sie waren nur noetig um den Syntaxbaum aufbauen zu koennen (vgl. Kommentar oben). (Uups, das war jetzt wohl eine Lektion Compilerbau in fuenf Minuten ...) Jedenfalls, was der Computer macht, um den Code ausfuehren zu koennen, das macht der Programmierer im Kopf (oder versucht es zumindest), um nachvollziehen zu koennen was der Computer machen wird. Klar oder? ;-) Und weil es fuer einen Programmiererkopf und seine Augen viel zu anstrengend ist dies hier /^-/!h;/^-/{s,^-.....,,;H;};/\. *$/{x;s,\n,,g;s,.\. *$,,;s,^.*VALUE..,,;s, *$,,;p;}; in einen Baum zu konvertieren (ganz im Gegenteil zum Computer uebrigens), schreibt der Programmierer es sich in einer einfacher erfassbareren Form auf. Je nach den eigenen Pattern Matching- Faehigkeiten und der Komplexitaet des Programmes wird das eine unterschiedlich ausgeformte Zwischenform der linearen und der voll hierarchisierten Darstellung sein. Hier ist nun der Code, den ich heute tatsaechlich erzeugt habe (in ca. 20min): sed -n ' /^-/! h; /^-/ { s,^-.....,,; H; }; /\. *$/ { x; s,\n,,g; s,.\. *$,,; s,^.*VALUE..,,; s, *$,,; p; }; ' "$@" Er hat allerdings in einer sehr linearen Form begonnen. Seine optische Darstellung ist erst mit wachsendem Umfang und Komplexitaet strukturierter geworden. So! Geschafft! Erwarte ich, dass ihr bis hier her lest, versteht und nicht verwirrt seid? Ich weiss nicht. Der Text ist einfach so gewachsen. Irgendwie scheine ich dann auch etwas vom Thema abgekommen zu sein. Diese Erklaerung koennte ich ebenso gut im Debianforum posten um dort den geschaetzt 40% Normalonutzern etwas zu erzaehlen, das sie nicht interessiert oder sie nicht verstehen, und weiteren 50% der dort mitlesenden erfahreneren Linux-Nutzer und Programmierern etwas fuer sie ziemlich Neues zu erklaeren, und den 10% Kennern wirklich nuetzlich zu sein, von denen fuenf aktiv beitragen koennten. Macht euch also keine Sorgen, wenn ihr zwischendurch ausgestiegen seid. ;-) Ich hatte einfach grosse Lust zu schreiben und vielleicht nimmt der eine oder andere davon ja doch etwas mit. Ich habe jedenfalls durch das Erklaeren mein Wissen gefestigt; alleine dafuer hat es sich gelohnt. :-) Und damit wuensche ich euch einen geruhsamen Abend. markus