% % SYNTAX.STY % % % LATEX-Documentstyle-Option zum einfachen Setzen von Syntax-Diagrammen % Version 0.1a vom 21.7.1989 % % Author : Jens Franzen % Laboratorium fuer Informationstechnologie % Universitaet Hannover % Schneiderberg 32 % D-3000 Hannover 1 % Tel. 0511 / 762 - 5039 % FAX 0511 / 762 - 5051 % % \typeout{Syntax-Diagramme Version 0.1a} \typeout{Vorlaeufige Version zum Test } % % % Mit dieser Style-Option koennen Syntax-Diagramme mit Hilfe von % Makros gesetzt werden, deren Struktur an die erweiterte % Backus-Naur-Form angelehnt ist. % % Die wesentlichen Elemente des Diagramms sind Terminale und Nonterminale % Symbole. Terminale werden einfach mit '\t{xxx}', Nonterminale mit % '\nt{xxx}' gesetzt. 'xxx' ist dabei der Inhalt des Ovals bzw. des % Rechtecks und kann bis auf die Hoehe beliebig % sein ( inc. Makros .... ). Die Laenge wird automatisch richtig gesetzt, die % Hoehe haengt von dem 'Zeilenabstand' im Diagramm ab und muss im Environment % spezifiziert werden. % % Der gesamte Inhalt des Diagramms wird in ein Environment 'syntax' % gesetzt : % % \begin{syntax}{Name}{Zeilenabstand} % ... Inhalt ... % \end{syntax} % % Das Ergebnis ist eine horizontale Box, die das Diagramm enthaelt. % ( analog zu einem 'picture' ) und ein neues Makro '\Name', das als % Abkuerzung fuer das Setzen des Nonterminals '\nt{Name}' verwendet werden % kann. % das Argument 'Name' darf keine Makros, Sonderzeichen etc. enthalten. % Sollen Makros vwerwendet werden, muss der Name des zu definierenden % neuen Makros als optionales Argument angegeben werden : % % \begin{syntax}[Name]{ \wilde \makrosequenz }{Zeilenabstand} % ... Inhalt ... % \end{syntax} % % Der Zeilenabstand ist eine bei TeX uebliche Laenge. % % % Als Konstrukte stehen zur Verfuegung : % % 1. Symbole % Terminale : \t{ ... } % Nonterminale : \nt{ ... } % Leersymbol : \empty % % % 2. Alternative : % % \alt 'Alternative 1' % \o 'Alternative 2' % \o ..... % .... % \o 'Alternative n' % \endalt % % % 3. Alternative mit leerem Pfad % % \emptyalt 'Alternative 1' % \o 'Alternative 2' % \o ..... % .... % \o 'Alternative n' % \endemptyalt % % % 4. Schleife % % \loopa ... Inhalt ... \endloopa % % 5. optionale Schleife % % \optloop ... Inhalt ... \endoptloop % % 6. ueber mehrere Zeilen verteilte Ketten von Elementen % % \multiline 'Zeile 1' % \oml 'Zeile 2' % \oml ..... % .... % \oml 'Zeile n' % \endmultiline % % % Alle diese Schleifen, Alternativen etc. koennen nahezu beliebig % ineinander verschachtelt werden ( Nur begrenzt vom maximalen % Nesting-Level in TeX ) ! % % % %########################################################################## % % % Hier geht's ins Eingemachte ! % % % Definierte 'versteckte' Makros : % % \syn@adh#1 \syn@adw#1 \syn@adx#1 % \syn@ady#1 \syn@downline#1 \syn@horline#1 % \syn@max(#1,#2) \syn@put#1 \syn@putat(#1,#2)#3 % \syn@rightline#1 \syn@saveh \syn@savew % \syn@savex \syn@savey \syn@taxn#1 % \syn@taxm[#1]#2#3 \syn@unithalfvec \syn@unithalfline % \syn@unitline \syn@unitvector \syn@upvector#1 % \syn@upline#1 % % Definierte 'sichtbare' Makros : % % \alt \emptyalt \endalt % \endemptyalt \endloopa \endmultiline % \endoptloop \empty \loopa % \multiline \nt#1 \o % \oml \optloop \t#1 % % Das Environment definierende Makros : % % \syntax % \endsyntax % % Zaehler fuer % \newcount\x % Koordinaten \newcount\y \newcount\bw % Blockgroessen \newcount\bh \newcount\cw % Blockgroessen ( Speicher zum Transfer ueber \newcount\ch % Grouplevel ) \newcount\cx % Koordinatenspeicher z. Transfer ueber Grouplevel \newcount\cy \newcount\altnum % Anzahl der Alternativen \newcount\altx % Groesster x-Wert der Alternativen \newcount\alty % f. Alternativen \newcount\altw % f. Alternativen \newcount\alth % f. Alternativen \newcount\ntwidth % Zur Berechnung der Breite eines ( Non-)Terminals \newcount\ntwidtha % Zur Berechnung der Breite eines ( Non-)Terminals \newcount\ntwidthb % Zur Berechnung der Breite eines ( Non-)Terminals \newcount\ntdimen % Zur Berechnung der Breite eines ( Non-)Terminals \newdimen\ntwidthdim % % % Boxen % \newbox\syn@ntstorage % zum Berechnen der Groesse des Textes in einem % ( Non)Terminal \newbox\syn@storage % Enthaelt das gesamte Diagramm ! % % Hilfsmakros aus Faulheit % \def\syn@adx#1{\advance\x by #1} \def\syn@ady#1{\advance\y by #1} \def\syn@adw#1{\advance\bw by #1} \def\syn@adh#1{\advance\bh by #1} % \def\syn@savex{\global\cx=\number\x} \def\syn@savey{\global\cy=\number\y} \def\syn@savew{\global\cw=\number\bw} \def\syn@saveh{\global\ch=\number\bh} % % Plazierung der Elemente % \long\def\syn@put#1{\@killglue\raise-\y\unitlength\hbox to \z@{\hskip \x\unitlength #1\hss}\ignorespaces} % \long\def\syn@putat(#1,#2)#3{\@killglue\raise-#2\unitlength\hbox to \z@{\hskip #1\unitlength #3\hss}\ignorespaces} % % Graphische Hilfselemente % Bequemlichkeit siegt ! ( in Version 0.2 nicht mehr ! ) % \def\syn@horline#1{\@linelen = #1\unitlength\@hline}% \def\syn@unithalfvec{\@picture(1,1)(0,0)\put(0,0.5){\vector(1,0){0.5}}% \put(0.5,0.5){\syn@horline{0.5}}\endpicture} % \def\syn@unithalfline{\@picture(1,1)(0,0)\put(0.5,0.5){\syn@horline{0.5}}% \put(0.5,0.5){\syn@horline{0.5}}\endpicture} % \def\syn@unitvector{\@picture(1,1)(0,0)\put(0,0.5){\vector(1,0){1}}\endpicture} % \def\syn@unitline{\@picture(1,1)(0,0)% \put(0,0.5){\syn@horline{1}}\endpicture} % \def\syn@downline#1{\@picture(1,1)(0,0)% \put(0.5,0.5){\line(0,-1){#1}}\endpicture} % \def\syn@rightline#1{\@picture(1,1)(0,0)% \put(0.5,0.5){\syn@horline{#1}}\endpicture} % \def\syn@upvector#1{\@picture(1,1)(0,0)% \put(0.5,0.5){\vector(0,1){#1}}\endpicture} % \def\syn@upline#1{\@picture(1,1)(0,0)% \put(0.5,0.5){\line(0,1){#1}}\endpicture} % %--------------------------------------------------------------------------- % % Das Environment : % % syntax := BEGIN % IF nextchar = [ THEN % \syn@taxm % ELSE % \syn@taxn % ENDIF % END % % syn@taxn #1 := BEGIN % \syn@taxm[#1]#1 % END % % Weitere Documentation folgt spaeter ! % ( da z.T. wuesteste Programmierung ! ) % \def\syntax{\@ifnextchar [{\syn@taxm}{\syn@taxn}} % \def\syn@taxn#1{\syn@taxm[#1]{#1}} % \def\syn@taxm[#1]#2#3{\typeout{Syntaxdiagramm #1}\setlength{\unitlength}{#3}% \expandafter\gdef\csname#1\endcsname{\nt{#2}}% \setbox\syn@storage=\hbox\bgroup% \x=0 \y=0 \bh=0 \bw=0 \ntdimen = \unitlength% \@picture(0,0)(0,1)\syn@put{\syn@unitline}\syn@adx 1 \syn@adw 1}% % \def\endsyntax{\syn@put{\syn@unitvector}\syn@adw 1\syn@savew\syn@saveh\endpicture\egroup% \begin{picture}(\number\cw,\number\ch)(0,0) \put(0,\number\ch){\box\syn@storage}\end{picture}}% % % Mathematik : % Bequemlichkeit siegt ! ( in Version 0.2 nicht mehr ! ) % \def\syn@max(#1,#2){\ifnum #2 > #1 #1 = #2 \fi} % % Terminals und Nonterminals % \def\t#1{\setbox\syn@ntstorage = \hbox{#1}\ntwidthdim = \wd\syn@ntstorage% \advance\ntwidthdim by 0.5em \ntwidth = \ntwidthdim% \divide\ntwidth by \ntdimen% \ntwidtha = \ntwidth \advance\ntwidtha by 1% \ntwidthb = \ntwidtha \divide\ntwidthb by 2% \syn@put{\@picture(\number\ntwidtha,1)(0,0)% \ifodd\ntwidtha % \put(\number\ntwidthb .5,0.5){\oval(\number\ntwidth .75,0.75){}}% \else % \put(\number\ntwidthb,0.5){\oval(\number\ntwidth .75,0.75){}}% \fi% \put(0.125,0.125){\makebox(\number\ntwidth .75,0.75){\box\syn@ntstorage}}% \put(0,0.5){\vector(1,0){0.125}}% \put(\number\ntwidth .875,0.5){\syn@horline{0.125}}\endpicture}% \syn@adx \ntwidtha \syn@adw \ntwidtha \syn@max(\bh,1)}% % \def\nt#1{\setbox\syn@ntstorage = \hbox{#1}\ntwidthdim = \wd\syn@ntstorage% \advance\ntwidthdim by 0.5em \ntwidth = \ntwidthdim% \divide\ntwidth by \ntdimen % \ntwidtha = \ntwidth \advance\ntwidtha by 1% \syn@put{\@picture(\number\ntwidtha,1)(0,0)% \put(0.125,0.125){\framebox(\number\ntwidth .75,0.75){\box\syn@ntstorage}}% \put(0,0.5){\vector(1,0){0.125}}% \put(\number\ntwidth .875,0.5){\syn@horline{0.125}}\endpicture}% \syn@adx \ntwidtha \syn@adw \ntwidtha \syn@max(\bh,1)}% % % Leere Menge % \def\empty{\syn@put{\@picture(1,1)(0,0)\put(0,0.5){\syn@horline{1}}\endpicture}% \syn@adx 1 \syn@adw 1 \syn@max(\bh,1)} % % % Schleifen % % Der Trick bei den Schleifen und Alternativen ist die exzessive % Nutzung des Block-Nesting von TeX ( '\bgroup .... \egroup', % '\bgroup' in einem Struktur oeffnenden Kommando ('\alt' ), % '\egroup' in einem Struktur schliessenden Kommando ('\endalt' ) ). % Damit sind alle neu zugewiesenen Zaehler nur lokal im Block % geaendert, der Transfer ueber die Blockgrenze erfolgt mit % '\syn@savex',... und den Zaehlern '\cx',... . % % \def\loopa{\bgroup\syn@put{\syn@unithalfvec}% \syn@adx 1 \bw=0 \bh = 0} % \def\endloopa{\syn@put{\syn@unitline}\syn@adx 1 \syn@savex \syn@adx -1% \syn@put{\syn@downline{\number\bh}} \syn@ady \number\bh \syn@adx -\number\bw \syn@adx -1 \syn@adw 1% \syn@put{\syn@rightline{\number\bw}} \syn@adw 1 \syn@savew% \syn@put{\syn@upvector{\number\bh}} \syn@adh 1 \syn@saveh% \egroup% \x = \cx \syn@max(\bh,\number\ch) \syn@adw \number\cw}% % % % Alternativen % % \def\alt{\bgroup\alth=0\altw=0\altnum=0\altx=0% \bw=0\bh=0\global\ch=0\global\cw=0% \syn@put{\syn@unitline}\syn@adx 1\bgroup\bw=0\bh=0% \global\ch=0\global\cw=0}% % \def\o{\syn@savex\syn@savey\syn@saveh\syn@savew\egroup% \advance\altnum by 1% \edef\otto{\number\cx}% \expandafter\edef\csname altex\romannumeral\altnum\endcsname{\number\cx}% \expandafter\edef\csname altey\romannumeral\altnum\endcsname{\number\cy}% \syn@ady\ch\syn@max(\altw,\number\cw)\advance\alth by\ch\syn@max(\altx,\number\cx)% \bgroup%\syn@ady\ch \syn@adx -1\syn@put{\syn@unithalfline}\syn@put{\syn@upline{\number\ch}} \syn@adx 1} % \def\endalt{\syn@savex\syn@savey\syn@saveh\syn@savew\egroup% \advance\altnum by 1% \edef\otto{\number\cx}% \expandafter\edef\csname altex\romannumeral\altnum\endcsname{\number\cx}% \expandafter\edef\csname altey\romannumeral\altnum\endcsname{\number\cy}% \syn@max(\altw,\number\cw)\advance\alth by\ch\syn@max(\altx,\number\cx)% %\advance\alth by -1% \cx=\cy\advance\cx by -\alteyi% \syn@putat(\number\altx,\number\cy){\syn@upvector{\number\cx}}% %\advance\alth by 1% \loop\ifnum\altnum > 0 \cx=\altx% \advance\cx by -\csname altex\romannumeral\altnum\endcsname% \syn@putat(\csname altex\romannumeral\altnum\endcsname,% \csname altey\romannumeral\altnum\endcsname){% \@picture(1,1)(0,0)\put(0,0.5){\syn@horline{\number\cx}}\endpicture}% \syn@putat(\number\altx,% \csname altey\romannumeral\altnum\endcsname){% \@picture(1,1)(0,0)\put(0,0.5){\vector(1,0){0.5}}\endpicture}% \advance\altnum by -1% \repeat% \bw=\altw\syn@adw 2\bh=\alth\syn@savew\syn@saveh\egroup% \syn@adx\cw\syn@max(\bh,\ch)\syn@adw\cw% \syn@put{\@picture(1,1)(0,0)\put(0,0.5){\line(-1,0){0.5}}\endpicture}}% % %--------------------------------------------------------------------------- % % Alternativen mit Nichts % \def\emptyalt{\alt\empty\o}% \def\endemptyalt{\endalt}% % %--------------------------------------------------------------------------- % % Optionale Schleife % \def\optloop{\alt\empty\o\loopa}% \def\endoptloop{\endloopa\endalt}% % % %--------------------------------------------------------------------------- % % Ueber mehrere Zeilen Verteilte Ketten % % \def\multiline{\bgroup\alth=0\altw=0\altnum=0\altx=0% \bw=0\bh=0\global\ch=0\global\cw=0% \syn@put{\syn@unitline}\syn@adx 1\bgroup\bw=0\bh=0% \global\ch=0\global\cw=0}% % \def\oml{\syn@savex\syn@savey\syn@saveh\syn@savew% \syn@put{\begin{picture}(1,1)\put(0,0.5){\line(1,0){0.5}}% \put(0.5,0.5){{\advance\ch by -1\line(0,-1){\number\ch .5}}}\end{picture}}% \syn@ady\ch\syn@adx -\cw\syn@adx -1 \syn@put{\begin{picture}(1,1)% \put(1.5,1){\line(1,0){\number\cw}}% \put(0.5,1){\line(1,0){1}}% \put(0.5,1){\line(0,-1){0.5}}% \put(0.5,0.5){\line(1,0){0.5}}% \end{picture}}% \egroup% \syn@ady\ch\syn@max(\altw,\number\cw)% \advance\alth by\ch\syn@max(\altx,\number\cx)% \bgroup} % \def\endmultiline{\syn@savex\syn@savey\syn@saveh\syn@savew\egroup% \syn@max(\altw,\number\cw)\advance\altw by 1% \advance\alth by\ch\syn@max(\altx,\number\cx)% \advance\cy by -1% \syn@putat(\number\cx,\number\cy .5){\advance\altx by 1% % \altx hier nur lokal geaendert ! \advance\altx by -\cx\line(1,0){\number\altx}}% {\advance\altx by 1\syn@putat(\number\altx,\number\cy .5){\advance\alth by -\ch% \line(0,1){\number\alth}}}% \bw=\altw\syn@adw 1\bh=\alth\syn@savew\syn@saveh\egroup% \syn@adx\cw\syn@max(\bh,\ch)\syn@adw\cw% }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%