#include "tippe.h" static const struct { String abgekuerzt, ausgeschrieben; } Schluesselwort [] = { "lb","linksbuendig", "rb","rechtsbuendig", "as","ausgeglichen", "a", "auf", "d", "die", "i", "in", "b", "bei", "m", "mit", "o", "ohne", "S", "Seiten", "d", "der", "L", "Laenge", "Sp","Spalten", "zw","dazwischen", "P", "Papierbreite", "R", "Rand", "l", "links", "r", "rechts", "o", "oben", "u", "unten", "D", "Datei", "W", "Warnungen" }; /* Vorsicht bei Aenderungen: - die Reihenfolge der enum Schluesselwort muss stets mit der Schluesselworttabelle uebereinstimmen, - saemtliche Woerter, die direkt nach tippe erscheinen duerfen, (linksbuendig bis ohne) muessen zusammenstehen, - Die Richtungen links bis unten sollten in der Ordnung bleiben, so dass sie mit linkerRand bis untererRand korrespondieren. */ Funktion Praedikat ist (Wort zupruefen) /* Die Funktion ist(zupruefen) ueberprueft, ob das aktuelle Token, das zu pruefende Schluesselwort ist, ausgeschrieben oder abgekuerzt. */ { register R; R = strcmp (Token, Schluesselwort[zupruefen].abgekuerzt) && strcmp (Token, Schluesselwort[zupruefen].ausgeschrieben); if (! R) Fehlermeldung (Schluesselwort[zupruefen].ausgeschrieben); return !R; } Variable Wort Fund; Funktion Praedikat zu_finden_unter (von, bis) Wort von, bis; /* Untersuche alle Schalter des Aufzaehlungstyps in [von,bis]. Fund enthaelt erstes gefundenes Schluesselwort, sofern vorhanden Returnwert: vorhanden? ja/nein */ { while (von <= bis) if (ist (von)) { Fund = von; return ja; } else ++ von; return nein; } Variable int Wert; Funktion Praedikat Zahl () /* Zahl () ist wahr, wenn das aktuelle Token nur aus Ziffern besteht. Wert ist dann der Zahlenwert. */ { register char Ziffer, * Quelle; for (Wert = 0, Quelle = Token; Ziffer = * Quelle ++; Wert = 10 * Wert + Ziffer) if (((Ziffer -= '0') < 0) || (Ziffer > 9)) return nein; printf ("%d\n", Wert); return ja; } Funktion Praedikat weiter () /* wahr, wenn noch ein weiteres Token existiert, als Nebeneffekt ist der Zeiger weitergeschoben */ { return ((-- Argumente > 0) && (Token = * ++ Kommandozeile)); } Funktion Praedikat zurueck () /* schiebt Zeiger zurueck, wenn ein Token betrachtet wurde, das erst spaeter behandelt werden soll */ { ++ Argumente; Token = * -- Kommandozeile; return nein; } Funktion void stelle (Groesse G, long Wert) /* Parameter [Groesse] wird auf den Wert gesetzt und Flag gehisst */ { if (gestellt [G]) Wiederholung (); Parameter [G] = Wert; gestellt [G] = ja; } void Parameterzerlegung() { while (weiter()) if (! zu_finden_unter (linksbuendig, ohne)) { Syntaxfehler(); } else switch (Fund) { case linksbuendig: case rechtsbuendig: case ausgeglichen: /* Blocksatz */ stelle (Satz, Fund); continue; case auf: /* auf [n] Seiten ... | auf /dev/ttyp2 */ if (! weiter()) Syntaxfehler(); if (ist (Seiten)) stelle (Seitenzahl, 10); else if (Zahl() && weiter() && (ist (Seiten) || zurueck())) stelle (Seitenzahl, Wert); else { stelle (Ausgabedateiname, (long) Token); continue; } if (weiter() && (ist (der) || zurueck()) && weiter() && (ist (Laenge) || zurueck() || zurueck())) if (weiter() && Zahl()) stelle (Seitenlaenge, Wert); else Syntaxfehler(); continue; case die: /* tippe die Datei eingabe.txt */ if (weiter() && ist (Datei) && weiter()) stelle (Eingabedateiname, (long) Token); else Syntaxfehler(); continue; case in: /* in [n] Spalten */ if (! weiter()) Syntaxfehler(); if (ist (Spalten)) stelle (Spaltenzahl, 2); else if (Zahl() && weiter() && ist (Spalten)) stelle (Spaltenzahl, Wert); else Syntaxfehler(); if (weiter() && (ist (dazwischen) || zurueck())) if (weiter() && Zahl()) stelle (Zwischenraum, Wert); else Syntaxfehler(); else Parameter [Zwischenraum] = 4; continue; case bei: /* bei Papierbreite n */ if (weiter() && ist (Papierbreite) && weiter() && Zahl()) stelle (Gesamtbreite, Wert); else Syntaxfehler(); continue; case mit: case ohne: { Variable Praedikat war_mit; war_mit = Fund == mit; if (! weiter()) Syntaxfehler(); if (ist (Warnungen)) { stelle (Warnungsanzeige, war_mit); continue; } if (! ist (Rand)) Syntaxfehler(); while (ja) { Variable Groesse R; Variable Praedikat Angaben; Angaben = nein; while (weiter() && (zu_finden_unter (links, unten) || zurueck())) { Angaben = ja; stelle (Fund - links + linkerRand, -1); } if (war_mit) if (weiter() && (Zahl() || zurueck())) Wert = Wert; else Wert = 4; else Wert = 0; if (Angaben) for (R = linkerRand; R <= untererRand; ++ R) Parameter [R] == -1 ? Parameter [R] = Wert : 0; else for (R = linkerRand; R <= untererRand; ++ R) stelle (R, Wert); if (war_mit && Angaben && weiter() && (zu_finden_unter (links, unten) || zurueck())) { zurueck(); continue; } else break; } continue; } default: Fehlermeldung ("Programmierfehler"); Syntaxfehler(); } }