6

I hope you can help me again.

I want to use the syntax package to build syntax diagrams, but I want to enclose non-terminal symbols in boxes and terminal symbols in circles or well-formed oval boxes (or rounded boxes). Here is my MWE built using \ovalbox from the package fancybox:

\documentclass[letterpaper, 12pt]{report}

\usepackage[rounded, nounderscore]{syntax}
\usepackage{fancybox}

\begin{document}

\begin{syntdiag}
\fbox{ident} \ovalbox{(}
\begin{rep} \begin{stack} \\
\fbox{type} \begin{stack} \\ \fbox{ident} \end{stack}
\end{stack} \\ \ovalbox{,} \end{rep}
\begin{stack} \\ \ovalbox{...} \end{stack} \ovalbox{)}
\end{syntdiag}

\end{document}

Yes, it looks awful. I know it can be improved, but I don't know how. Do you know what commands I should use to enclose terminal symbols in circles or oval boxes? I have not found a solution in the documentation of syntax.sty and, since I am using pdflatex, I would not like to use pstricks and dvi2ps because my figures might mess up.

3

It's really hard to achieve a beautiful design when boxing the expressions; in the following code I used TikZ to define two kinds of frames (a circular one and a rectangular one); the code exhibits a comparison between a diagram drawn as suggested in the syntax documentation, the same diagram using \fbox and \ovalbox, and the same diagram using the frames defined with TikZ; in the last diagram the lengths \sdtokskip and\sdmidskip` were redefined in an effort to improve the visual appearance:

\documentclass[letterpaper, 12pt]{report}
\usepackage[rounded, nounderscore]{syntax}
\usepackage{fancybox}
\usepackage{tikz}

\newcommand\MyOval[1]{\tikz[baseline=-3pt]%
  \node[draw,circle,inner sep=2pt,minimum size=15pt] {#1};}
\newcommand\MyRect[1]{\tikz[baseline=-3pt]%
  \node[draw,rectangle,inner sep=2pt,minimum size=10pt] {#1};}

\begin{document}

\begin{syntdiag}
<ident> ‘(’
\begin{rep} \begin{stack} \\
<type> \begin{stack} \\ <ident> \end{stack}
\end{stack} \\ ‘,’ \end{rep}
\begin{stack} \\ ‘...’ \end{stack} ‘)’
\end{syntdiag}

\begin{syntdiag}
\fbox{ident} \ovalbox{(}
\begin{rep} \begin{stack} \\
\fbox{type} \begin{stack} \\ \fbox{ident} \end{stack}
\end{stack} \\ \ovalbox{,} \end{rep}
\begin{stack} \\ \ovalbox{...} \end{stack} \ovalbox{)}
\end{syntdiag}

\begin{syntdiag}[\setlength\sdtokskip{12pt},\setlength\sdmidskip{12pt}]
\MyRect{ident} \MyOval{(}
\begin{rep} \begin{stack} \\
\MyRect{type} \begin{stack} \\ \MyRect{ident} \end{stack}
\end{stack} \\ \MyOval{,} \end{rep}
\begin{stack} \\ \MyOval{...} \end{stack} \MyOval{)}
\end{syntdiag}

\end{document}

enter image description here

In my opinion, all three look ugly; perhaps you could consider using TikZ to draw the diagrams from scratch?

Here's a very basic design using TikZ and the result is better:

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{arrows,calc}

\pgfarrowsdeclarecombine[-4\pgflinewidth]
{dou}{dou}{latex reversed}{latex}{latex}{latex reversed}

\begin{document}

\noindent\begin{tikzpicture}[
  terminal/.style={draw,fill=white,circle,inner sep=2pt,
    minimum size=18pt},
  nonterminal/.style={draw,fill=white,rectangle,inner sep=2pt,
    minimum size=10pt},
  y=0.5cm]

\draw[dou-dou] (0,0) -- node[nonterminal] (id1) {ident} (2,0) -- node[terminal] (ob) {(} (2.5,0) 
  -- (10.5,0) -- node[terminal] (cb) {)}  (\textwidth,0) ;

\node[nonterminal] at (4.5,-1) (ty) {type};
\node[terminal] at (9.7,-1) (ell) {...};
\node[nonterminal] at (6.5,-2) (id2) {ident};
\node[terminal] at (6,1) (co) {,};

\draw (3.5,0) |- (ty) -| (8,0);
\draw (5.5,-1) |- (id2) -| (7.5,-1);
\draw (9,0) |- (ell) -| (10.4,0);
\draw (3,0) |- (co) -| (8.5,0);
\end{tikzpicture}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.