%\filename{SynChart-description.tex}
%\edited{by stolfi on Fri Oct 10 00:28:11 1986}

% Description and user manual for SynChart.tex 
% (Mike Plass's syntax chart macros).
% Extensively modified by J. Stolfi

\input SynChart

\font\NonTerminalFont=amti10 \relax
\font\TerminalFont=amtt10 \relax
\font\KeywordFont=amtt10 \relax

\newdimen\Em
\rm \Em=1em

\def\syn#1{\hbox{\SyntaxChart#1}}
\def\yields{\hbox{$\Rightarrow$}}

\def\NTF{\NonTerminalFont}

\def\sox#1{\setbox#1\hbox}

\input QuoteTeX

\def\zero{\NonTerminal{zero\/\Strut}}
\def\one{\NonTerminal{one\/\Strut}}
\def\two{\NonTerminal{two\/\Strut}}
\def\three{\NonTerminal{three\/\Strut}}
\def\four{\NonTerminal{four\/\Strut}}

% This macro will put an example on one line if it fits, or on two if not.

% The next macro puts #1 and #2 on same line with \hfill in the middle if
% they fit; otherwise put each on a separate line, left-aligned

\def\wideexample#1#2{\relax
  \begingroup
    \setbox0=\hbox{$\vcenter{#1}$}
    \setbox2=\hbox{$\vcenter{#2}$}
    \dimen0=\wd0 \advance\dimen0 by \wd2
    \advance\dimen0 by 3.1\Em
    \ifdim \dimen0>\hsize \relax
      $$\vbox{\lineskip=5pt
          \hbox to \hsize{\quad\box0\hss}
          \hbox to \hsize{\quad\box2\hss}
         }
      $$
    \else
      $$\hbox to \hsize{\quad\box0\hss\box2\quad}$$
    \fi
  \endgroup
  }
\def\title#1{\par\centerline{\bf#1}\null}

\def\section#1{\medskip\noindent{\bf #1\ }\ignorespaces}

\parindent=1\Em

\dimen0=\hsize
\hsize=78mm
\advance\dimen0 by -\hsize
\advance\hoffset by 0.5\dimen0

\def\TeX{\hbox{T\hskip-.125em\lower.5ex\hbox{E}\hskip-.075em X}}

\title{CHARTING YOUR GRAMMAR WITH \TeX}
\centerline{\it Michael F. Plass}
\centerline{Xerox Corporation}
\vskip 10pt
\centerline{Adapted for \TeX{} 80 by \it J. Stolfi}
\centerline{DEC Systems Research Center}
\null

Are you one of those people who would rather look at a syntax chart
than a BNF grammar?  Do you avoid making a syntax chart for your
language because it is too hard to draw or too hard to typeset?  If
so, this is the article for you. Pay attention, and you will learn how
to use the macros below to create your own syntax charts with {\TeX}.

First some basics.  Every component of the syntax chart is enclosed
in a {\TeX} box, with the entry and exit points on the left and right
sides of the box, aligned with the baseline.  Usually the entry point
is on the left end and the exit is on the right, but not always, as
we shall see.

\section{Symbol boxes.} The simplest components are the boxes that
represent the terminals 
and the nonterminals of the language.  Terminals are the lowest
level pieces of the language that the description deals with, such
as keywords, special characters, letters, digits, and so forth.
Nonterminals are the names for the building blocks of the language.
Some examples of nonterminal symbols might be {\NTF number}, 
{\NTF identifier}, {\NTF expression}, {\NTF statement\/},
{\NTF program}.  If you are familiar with BNF, the
nonterminals are the things in the angle brackets.

The terminals in a syntax chart are enclosed in boxes with rounded
ends, and nonterminals are enclosed in rectangular boxes. This is
how you use the syntax chart macros to make both kinds of elementary
boxes:
  \sox4{|\Terminal{+}|}              \sox5{\syn{\Terminal{+}}}
  \sox6{|\NonTerminal{statement}|}   \sox7{\syn{\NonTerminal{statement}}}
  \sox8{|\Keyword{procedure}|}       \sox9{\syn{\Keyword{procedure}}}
\wideexample{\box4}{\hbox to \wd9{\hss\box5\hss}}
\wideexample{\box6}{\hbox to \wd9{\hss\box7\hss}}
\wideexample{\box8}{\box9}
(Keep in mind that the case of letters in a {\TeX} control sequence is
significant.) You can control what fonts are used inside these boxes by
declaring the macros |\TerminalFont|,
|\NonTerminalFont|, and |\KeywordFont| to be the appropriate font selectors.
Notice each of these basic boxes has `stems' on the left and right sides,
one of them being an arrow and the other one just a line.  {\TeX} will
determine which direction to point the arrow in on the basis of how the box
is nested inside of other constructions.  

\section{Definitions} of nonterminals are written like this:
\sox8{|\Define{Letter A}\Terminal{A}\EndDef|}
\sox9{\syn{\vbox{\advance\hsize by -3\Em\parindent0pt
    \Define{Letter A}\Terminal{A}\EndDef
  }}}
\wideexample{\box8}{\box9}

More complicated charts are built up by means of {\sl sequencing}, {\sl
alternation}, and {\sl repetition} of simpler charts.  To illustrate the
way these work, we will assume that the control sequence {|\one|} has been
defined to be {|\NonTerminal{one}|}, and so forth.  

\section{Sequencing} is easy to do; just put the subcharts together:
\sox8{|\one\two\three|}   \sox9{\syn{\one\two\three}}
\wideexample{\box8}{\vbox{\null\kern10pt\box9\kern10pt\null}}

\section{Alternation} is a bit more complicated to specify. Here is an example:
\sox8{|\Alternatives{
  \Upper{\one}
  \Middle{\two}
  \Lower{\three}
  \Lower{\four}}|}
\sox9{\syn{\Alternatives{
  \Upper{\one}
  \Middle{\two}
  \Lower{\three}
  \Lower{\four}
}}}
\wideexample{\box8}{\box9}

There may be any positive number of choices listed as the argument to
{|\Alternatives|}, and each choice is marked by enclosing it in braces and
preceding it with {|\Upper|}, {|\Middle|}, or {|\Lower|}.  Things marked
with {|\Upper|} go above the baseline, things marked with {|\Lower|} go
below the baseline, and something marked with {|\Middle|} goes on the
baseline.  It is permitted to omit any one of these three kinds of tags:
\sox8{|\Alternatives{
  \Middle{\one}
  \Lower{\two}
  \Lower{\three}}|}
\sox9{\syn{\Alternatives{
  \Middle{\one}
  \Lower{\two}
  \Lower{\three}
}}}
\wideexample{\box8}{\box9}
\sox8{|\Alternatives{
  \Upper{\one}
  \Upper{\two}
  \Lower{\three}}|}
\sox9{\syn{\Alternatives{
  \Upper{\one}
  \Upper{\two}
  \Lower{\three}
}}}
\wideexample{\box8}{\box9}
\sox8{|\Alternatives{
  \Upper{\one}
  \Upper{\two}
  \Middle{\three}}|}
\sox9{\syn{\Alternatives{
  \Upper{\one}
  \Upper{\two}
  \Middle{\three}
}}}
\wideexample{\box8}{\box9}

Sometimes a stack of alternatives can get very tall; in this case it
might be better to spread them out horizontally:
\sox8{|\HorzAlternatives{
  \Alternative{\one}
  \Alternative{\two}
  \Alternative{\three}}|}
\sox9{\syn{\HorzAlternatives{
  \Alternative{\one}
  \Alternative{\two}
  \Alternative{\three}
}}}
\wideexample{\box8}{\box9}
This one is especially appropriate for a long list of short choices.

\section{Repetition} is specified in almost exactly the same way as
alternatives: 
\sox8{|\Repeat{
  \Upper{\one}
  \Middle{\two}
  \Lower{\three}}|}
\sox9{\syn{\Repeat{
  \Upper{\one}
  \Middle{\two}
  \Lower{\three}
}}}
\wideexample{\box8}{\box9}

The same rules apply as before, except that you are not allowed to leave
out the {|\Middle|}.  This is not the same as specifing an
empty middle, which you might often want to do:
\sox8{|\Repeat{
  \Upper{\one}
  \Middle{}}|}
\sox9{\syn{\Repeat{\Upper{\one}\Middle{}}}}
\wideexample{\box8}{\box9}
\sox8{|\Repeat{
  \Middle{\one}
  \Lower{}}|}
\sox9{\syn{\Repeat{\Middle{\one}\Lower{}}}}
\wideexample{\box8}{\box9}

Now you know all the essential constructions.  They can be nested in any way
you please, up to any depth (subject only to TeX's memory limitations).

\section{To use the macros,} say |\input SynChart| near the
beginning of your file.  When you actually want to make a chart, say
{|\SyntaxChart|} to set up the baselineskip, lineskip, and some
other stuff.  If you are mixing syntax charts with other text, you will
want to enclose the {|\SyntaxChart|} along with the chart
definition in braces, so all the funny definitions go away at the end of
the group and don't mess up the rest of your document.  You will probably
also want to say {|\parindent 0pt|} to eliminate the paragraph
indentation.

The call on {|\SyntaxChart|}  also tells {\TeX} to ignore
tabs and carriage returns so you can format your input more easily.
Just be careful where you add spaces---after a control sequence is OK,
but not between or after the parameters to a macro.  The reason for not
ignoring spaces is so terminals and nonterminals can have embedded
spaces; if you prefer, you can say {|\IgnoreWhiteSpace|} to
cause spaces to be ignored too, and then put in a control-space
where you really want a space.

Now would be a good time to go try making your own simple syntax chart,
using the macro definitions in Appendix A.  When defining a complex
diagram, it is often helpful to first define pieces of it as {\TeX} macros.
This makes the source much easier to read, and keeps the nesting of braces
down to a reasonable level.  This device is used extensively in the example
in Appendix B.  You may also consider saving away a frequently 
used subchart in a box register, and copy it when building more
complex charts. 

\centerline{\hbox{*}}

Now that you have a firm grasp of the essentials, here are some fine points
you may like to know:

\section{Horizontal spacing.} The horizontal lines are actually composed of
fixed-width rules and leaders filled with rules.  The control sequence
{|\ULine|} defines a fairly short fixed-width line, and {|\UULine|} defines
one twice as long.  In general, |\HLine |$\langle$dimen$\rangle$ gives an
horizontal line of the specified length.  {|\Fil|} defines a line that
stretches like glue, with a normal length of zero and the same
stretchability as {|\hfil|}; {|\Fill|} is similar, but with the
stretchability of an {|\hfill|}.  

The macro |\DefaultFil| gives a line line with stretchabilility
|1000pt|. It is implicitly inserted on both sides of every branch of a
repetition or (vertical) alternation.  Therefore, if the
branches are not all the same width, the shorter ones will be
horizontally centered.  A |\DefaultFil|
is also implicitly inserted at the
end of the |\Define| (and of each line of a multi-line chart).
Note that any |\Fil| or |\Fill| you insert will override all the
|\DefaultFil|s.  By using these macros in various combinations, you can get
any kind of horizontal spacing you want.  

\section{Vertical spacing.}
The register {|\AltSpacing|} specifies how many `units of
space' should be inserted between adjacent branches of
{|\Alternatives|} or {|\Repeat|}.  The `unit of space'
here is the radius of the circular arcs used as joints.  The default
setting is {|\AltSpacing=2|}, which gives space equal to the 
height of a symbol box. You can change this default by typing,
for example,
\sox8{|\Alternatives{
  \AltSpacing=1
  \Upper{\one}
  \Middle{\two}
  \Lower{}
  \Lower{\three}}|}
\sox9{\syn{\Alternatives{
  \AltSpacing=1
  \Upper{\one}
  \Middle{\two}
  \Lower{}
  \Lower{\three}
}}}
\wideexample{\box8}{\box9}
or
\sox8{|\Alternatives{
  \AltSpacing=3
  \Upper{\one}
  \Middle{\two}
  \Lower{}
  \Lower{\three}}|}
\sox9{\syn{\Alternatives{
  \AltSpacing=3
  \Upper{\one}
  \Middle{\two}
  \Lower{}
  \Lower{\three}
}}}
\wideexample{\box8}{\box9}

\section{Symbol alignment.}
The macros |\NonTerminal|, |\Terminal|, and |\Keyword| will raise or lower
their argument until its \TeX{} bounding box is centered with respect to
the enclosing frame. This looks fine if the symbols include only digits
and upper-case leters.  However, if the same thing is done for lower case
letters, the baselines of the words in different boxes may not line up due
to the pattern of ascenders and descenders.  This problem is solved by the
macro |\Strut|, which produces a zero-width box whose height and depth
match the extremes of the font.  If the keywords in your language are in
lower case, say {|\Strut|} after the arguments to |\Keyword| --- better
yet, define a macro that does this, as in Appendix B.  The same applies to
|\NonTerminal|. Compare the examples
\sox4{|\Keyword{go}\Keyword{to}|} 
\sox5{\syn{\Keyword{go}\Keyword{to}}}
\wideexample{\box4}{\box5}
\sox6{|\Keyword{\Strut go}\Keyword{\Strut to}|}
\sox7{\syn{\Keyword{\Strut go}\Keyword{\Strut to}}}
\wideexample{\box6}{\box7}

A similar problem arises when |\Terminal| is used for
mathematical symbols such as
$+$ and $<$, which in most \TeX{} fonts 
are not vertically centered with respect to
their bounding boxes. Moreover, some characters
like `|.|' and `|^|' are hard to recognize when vertically centered.
Those problems are usually fixed by
including in the argument the macro |\OpStrut|, which produces a 
zero-width box with the height and width of an open parenthesis.
Compare
\sox4{|\Terminal{+}|}\sox5{\syn{\Terminal{+}}}
\wideexample{\box4}{\box5}
\sox4{|\Terminal{\OpStrut+}|}\sox5{\syn{\Terminal{\OpStrut+}}}
\wideexample{\box4}{\box5}
\sox6{|\Terminal{.}|}\sox7{\syn{\Terminal{.}}}
\wideexample{\box6}{\box7}
\sox6{|\Terminal{\OpStrut.}|}\sox7{\syn{\Terminal{\OpStrut.}}}
\wideexample{\box6}{\box7}

\section{Bigger circles.}
To get bigger symbol boxes and wider turns, like the ones below,
\sox4{\syn{\BigCircles 
    \one\Alternatives{\Upper{\Terminal{+}}\Middle{\two}\Lower{\Keyword{plus}}}
    \three
}}
\wideexample{\box4}{\null}
say |\BigCircles| right after |\SyntaxChart|.

\section{Multi-line charts.}
If a chart gets too wide to fit in the page, you can break it in two (or more)
lines by using |\NewLine|, as shown below:
\sox4{|\Define{Test}
  \one\two
  \NewLine
  \three
\EndDef|}
\sox5{\syn{\vbox{\advance\hsize by -3\Em\parindent0pt
  \Define{Test}
    \one\two
    \NewLine
    \three
  \EndDef}}}
\wideexample{\box4}{\box5}

The macro |\OptionalLines| is useful when you want to construct
a sequence several items, where each item can be omitted:
\sox4{|\Define{Test}
  \zero
  \OptionalLines{
    \Line{\one}
    \Line{\two}
  }
  \three
\EndDef|}
\sox5{\syn{\vbox{\advance\hsize by -3\Em\parindent0pt
\Define{Test}
  \zero
  \OptionalLines{\Line{\one}\Line{\two}}
  \three
\EndDef}}}
\wideexample{\box4}{\box5}
Note that |\NewLine| and |\OptionalLines| can only
appear at the top level of a |\Define|; they cannot be used inside 
alternations or repetitions.

The length of lines produced by |\NewLine| and |\OptionalLines|
is determined by the parameter |\MinLineWidth|.
Every line but the last is stretched until its width (including 
the connectors on the sides) is greater than |\MinLineWidth|
(the last line is always stretched to |\hsize|).
The default is zero, which 
means that those lines will be typeset with their natural width, so
that |\Fil| and |\Fill| will not work in those lines.  

\section{Omitting arrows.}
Instead of breaking a chart into lines, you may try saying
|\OmitRightArrows| after |\SyntaxChart|, as is done in appendix B.
This removes all right-going arrows on the input side of symbol boxes.
As a last resort, |\OmitAllArrows| will remove also the
left-going ones.  In that case, you may wish to explicitly insert
|\Arrow|s and/or |\BigArrow|s in a few key places: 
\sox8{|\OmitRightArrows 
\Alternatives{ 
  \Upper{\one}
  \Middle{\Arrow}
  \Lower{\two}}|}
\sox9{\syn{\OmitRightArrows
    \Alternatives{\Upper{\one}\Middle{\Arrow}\Lower{\two}}
  }}
\wideexample{\box8}{\box9}

\vfill\bye

