Commit 8f177a17 authored by POTTIER Francois's avatar POTTIER Francois

Introduce and document [endrule] and [midrule].

parent 9d90b054
# Changes # Changes
## 2018/06/08
* Add two new parameterized nonterminal symbols, `endrule(X)` and `midrule(X)`,
to the standard library. These symbols have been available since 2015/02/11
under the names `anonymous(X)` and `embedded(X)`, but were not yet documented.
`endrule(X)` and `midrule(X)` are now documented,
while `anonymous(X)` and `embedded(X)` remain present but are deprecated.
## 2018/05/30 ## 2018/05/30
* In `--coq` mode, Menhir now produces references to `MenhirLib.Grammar` * In `--coq` mode, Menhir now produces references to `MenhirLib.Grammar`
......
...@@ -134,9 +134,6 @@ ...@@ -134,9 +134,6 @@
* Produce well-chosen (predictable) names for anonymous rules? * Produce well-chosen (predictable) names for anonymous rules?
* In the standard library, possibly rename "anonymous" and "embedded" and
document them. Document WHEN they were added.
* Add standard library support for specifying arithmetic-expression-levels? * Add standard library support for specifying arithmetic-expression-levels?
Check connection with parsec (chainl1). Check connection with parsec (chainl1).
More generally, find inspiration in parsec combinators. More generally, find inspiration in parsec combinators.
......
...@@ -1039,6 +1039,9 @@ recognized. ...@@ -1039,6 +1039,9 @@ recognized.
\begin{tabular}{lp{51mm}l@{}l} \begin{tabular}{lp{51mm}l@{}l}
Name & Recognizes & Produces & Comment \\ Name & Recognizes & Produces & Comment \\
\hline\\ \hline\\
\nt{endrule}(\nt{X}) & \nt{X} & $\alpha$, if \nt{X} : $\alpha$ & (inlined) \\
\nt{midrule}(\nt{X}) & \nt{X} & $\alpha$, if \nt{X} : $\alpha$ \\
\\
\nt{option}(\nt{X}) & $\epsilon$ \barre \nt{X} & $\alpha$ \basic{option}, if \nt{X} : $\alpha$ \\ \nt{option}(\nt{X}) & $\epsilon$ \barre \nt{X} & $\alpha$ \basic{option}, if \nt{X} : $\alpha$ \\
\nt{ioption}(\nt{X}) & $\epsilon$ \barre \nt{X} & $\alpha$ \basic{option}, if \nt{X} : $\alpha$ & (inlined) \\ \nt{ioption}(\nt{X}) & $\epsilon$ \barre \nt{X} & $\alpha$ \basic{option}, if \nt{X} : $\alpha$ & (inlined) \\
\nt{boption}(\nt{X}) & $\epsilon$ \barre \nt{X} & \basic{bool} \\ \nt{boption}(\nt{X}) & $\epsilon$ \barre \nt{X} & \basic{bool} \\
...@@ -1062,7 +1065,7 @@ Name & Recognizes & Produces & Comment \\ ...@@ -1062,7 +1065,7 @@ Name & Recognizes & Produces & Comment \\
& a possibly empty sequence of \nt{X}'s separated with \nt{sep}'s & a possibly empty sequence of \nt{X}'s separated with \nt{sep}'s
& $\alpha$ \basic{list}, if \nt{X} : $\alpha$ \\ & $\alpha$ \basic{list}, if \nt{X} : $\alpha$ \\
\nt{separated\_nonempty\_list}(\nt{sep}, \nt{X}) \nt{separated\_nonempty\_list}(\nt{sep}, \nt{X})
& a nonempty sequence of \nt{X}'s separated with \nt{sep}'s & a nonempty sequence of \nt{X}'s \hspace{2mm} separated with \nt{sep}'s
& $\alpha$ \basic{list}, if \nt{X} : $\alpha$ \\ & $\alpha$ \basic{list}, if \nt{X} : $\alpha$ \\
\end{tabular} \end{tabular}
...@@ -1114,6 +1117,85 @@ command line switch \ostdlib. ...@@ -1114,6 +1117,85 @@ command line switch \ostdlib.
The command line switch \onostdlib instructs \menhir to \emph{not} load the The command line switch \onostdlib instructs \menhir to \emph{not} load the
standard library. standard library.
The meaning of the symbols defined in the standard library
(\fref{fig:standard}) should be clear in most cases. Yet, the
symbols \nt{endrule}(\nt{X}) and \nt{midrule}(\nt{X}) deserve an explanation.
Both take an argument \nt{X}, which typically will be instantiated with an
anonymous rule (\sref{sec:actual}). Both are defined as a synonym
for \nt{X}. In both cases, this allows placing an anonymous subrule in the
middle of a rule.
\newcommand{\AAA}{\nt{cat}}
\newcommand{\BBB}{\nt{dog}}
\newcommand{\CCC}{\nt{cow}}
\newcommand{\XXX}{\nt{xxx}}
For instance, the following is a well-formed production:
%
\[\begin{array}{l}
\AAA \quad
\nt{endrule}(\BBB \quad \dpaction{\nt{\ocaml code$_1$}}) \quad
\CCC \quad
\dpaction{\nt{\ocaml code$_2$}}
\end{array}\]
%
This production consists of three producers, namely
\AAA{} and
\nt{endrule}(\BBB$\;$\dpaction{\nt{\ocaml code$_1$}}) and
\CCC,
and a semantic action \dpaction{\nt{\ocaml code$_2$}}.
%
Because \nt{endrule}(\nt{X}) is declared as an \dinline synonym for \nt{X},
the expansion of anonymous rules (\sref{sec:actual}), followed with the
expansion of \dinline symbols (\sref{sec:inline}), transforms the above
production into the following:
%
\[\begin{array}{l}
\AAA \quad
\BBB \quad
\CCC \quad
\dpaction{\nt{\ocaml code$_1$; \ocaml code$_2$}}
\end{array}\]
%
Note that \nt{\ocaml code$_1$} moves to the end of the rule, which means that
this code is executed only after \AAA, \BBB{} and \CCC{} have
been recognized. In this example, the use of \nt{endrule} is rather pointless,
as the expanded code is more concise and clearer than the original code. Still,
\nt{endrule} can be useful when its actual argument is an anonymous rule with
multiple branches.
% Let me *not* show an example. See the comments in standard.mly.
\nt{midrule} is used in exactly the same way as \nt{endrule}, but its expansion
is different. For instance, the following is a well-formed production:
%
\[\begin{array}{l}
\AAA \quad
\nt{midrule}(\dpaction{\nt{\ocaml code$_1$}}) \quad
\CCC \quad
\dpaction{\nt{\ocaml code$_2$}}
\end{array}\]
%
(There is no \BBB{} in this example; this is intentional.)
Because \nt{midrule}(\nt{X}) is a synonym for \nt{X}, but is not declared
\dinline, the expansion of anonymous rules (\sref{sec:actual}), followed
with the expansion of \dinline symbols (\sref{sec:inline}), transforms the
above production into the following:
%
\[\begin{array}{l}
\AAA \quad
\XXX \quad
\CCC \quad
\dpaction{\nt{\ocaml code$_2$}}
\end{array}\]
%
where the fresh nonterminal symbol $\XXX$ is separately defined by the
rule $\XXX: \dpaction{\nt{\ocaml code$_1$}}$. Thus, $\XXX$ recognizes
the empty string, and as soon as it is recognized, \nt{\ocaml code$_1$}
is executed. This is known as a ``mid-rule action''.
% https://www.gnu.org/software/bison/manual/html_node/Mid_002dRule-Actions.html
% ------------------------------------------------------------------------------ % ------------------------------------------------------------------------------
\section{Conflicts} \section{Conflicts}
...@@ -4121,6 +4203,9 @@ in \sref{sec:positions}. In short, the solution is to use \verb+$symbolstartpos+ ...@@ -4121,6 +4203,9 @@ in \sref{sec:positions}. In short, the solution is to use \verb+$symbolstartpos+
\question{Can I pretty-print a grammar in ASCII, HTML, or \LaTeX{} format?} \question{Can I pretty-print a grammar in ASCII, HTML, or \LaTeX{} format?}
Yes. Have a look at \texttt{obelisk} \cite{obelisk}. Yes. Have a look at \texttt{obelisk} \cite{obelisk}.
\question{Does \menhir support mid-rule actions?} Yes.
See \nt{midrule} and its explanation in \sref{sec:library}.
% ------------------------------------------------------------------------------ % ------------------------------------------------------------------------------
\section{Technical background} \section{Technical background}
......
...@@ -20,64 +20,71 @@ ...@@ -20,64 +20,71 @@
(* ------------------------------------------------------------------------- *) (* ------------------------------------------------------------------------- *)
(* The identity. *) (* The identity. *)
(* [anonymous(X)] is the same as [X]. *) (* [endrule(X)] is the same as [X]. *)
(* This allows placing an anonymous sub-rule in the middle of a rule, as in: (* This allows placing an anonymous subrule in the middle of a rule, as in:
foo cat
anonymous(baz { action1 }) endrule(dog { action1 })
bar cow
{ action2 } { action2 }
Because anonymous is marked %inline, everything is expanded away. So, Because [endrule] is marked %inline, everything is expanded away. So,
this is equivalent to: this is equivalent to:
foo baz bar { action1; action2 } cat dog cow { action1; action2 }
Note that [action1] moves to the end of the rule. The anonymous sub-rule Note that [action1] moves to the end of the rule. The anonymous subrule
can even have several branches, as in: can even have several branches, as in:
foo cat
anonymous(baz { action1a } | quux { action1b }) endrule(dog { action1a } | fox { action1b })
bar cow
{ action2 } { action2 }
This is expanded to: This is expanded to:
foo baz bar { action1a; action2 } cat dog cow { action1a; action2 }
| foo quux bar { action1b; action2 } | cat fox cow { action1b; action2 }
*) *)
%public %inline endrule(X):
x = X
{ x }
(* [anonymous(X)] is a deprecated synonym for [endrule(X)].
It was never documented. *)
%public %inline anonymous(X): %public %inline anonymous(X):
x = X x = X
{ x } { x }
(* [embedded(X)] is the same as [X]. *) (* [midrule(X)] is the same as [X]. *)
(* This allows placing an anonymous sub-rule in the middle of a rule, as in: (* This allows placing an anonymous subrule in the middle of a rule, as in:
foo cat
embedded(baz { action1 }) midrule(dog { action1 })
bar cow
{ action2 } { action2 }
Because [embedded] is not marked %inline, this is equivalent to: Because [midrule] is not marked %inline, this is equivalent to:
foo xxx bar { action2 } cat xxx cow { action2 }
where the fresh non-terminal symbol [xxx] is separately defined by: where the fresh nonterminal symbol [xxx] is separately defined by:
xxx: baz { action1 } xxx: dog { action1 }
In particular, if there is no [baz], what we get is a semantic action In particular, if there is no [dog], what we get is a semantic action
embedded in the middle of a rule. For instance, embedded in the middle of a rule. For instance,
foo embedded({ action1 }) bar { action2 } cat midrule({ action1 }) cow { action2 }
is equivalent to: is equivalent to:
foo xxx bar { action2 } cat xxx cow { action2 }
where [xxx] is separately defined by the rule: where [xxx] is separately defined by the rule:
...@@ -85,6 +92,13 @@ x = X ...@@ -85,6 +92,13 @@ x = X
*) *)
%public midrule(X):
x = X
{ x }
(* [embedded(X)] is a deprecated synonym for [midrule(X)].
It was never documented. *)
%public embedded(X): %public embedded(X):
x = X x = X
{ x } { x }
...@@ -217,4 +231,3 @@ x = X ...@@ -217,4 +231,3 @@ x = X
{ x :: xs } { x :: xs }
%% %%
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment