aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorherbelin2003-12-23 19:48:07 +0000
committerherbelin2003-12-23 19:48:07 +0000
commitd12e53d085ce7cb2c186bf9ee7eae4bee3b32a03 (patch)
tree3fb5b53a80693df8381faa860b3066569ad2e3ca
parentb1e245f77b931f0340739878b0eb886796082798 (diff)
Qques avancees sur la doc des scopes
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@8446 85f007b7-540e-0410-9357-904b9bb8a0f7
-rwxr-xr-xdoc/RefMan-syn.tex2029
1 files changed, 151 insertions, 1878 deletions
diff --git a/doc/RefMan-syn.tex b/doc/RefMan-syn.tex
index 9439d202fe..65210bc3ba 100755
--- a/doc/RefMan-syn.tex
+++ b/doc/RefMan-syn.tex
@@ -62,8 +62,8 @@ Notation "'IF' c1 'then' c2 'else' c3" := (IF_then_else c1 c2 c3).
Mixing different symbolic notations in a same text may cause serious
parsing ambiguity. To deal with the ambiguity of notations, {\Coq}
-uses precedence levels ranging from 0 to 100 (plus two extra levels
-numbered 200 and 250) and associativity rules.
+uses precedence levels ranging from 0 to 100 (plus one extra level
+numbered 200) and associativity rules.
Consider for example the new notation
@@ -114,57 +114,7 @@ By default, a notation is considered non associative, but the
precedence level is mandatory (except for special cases whose level is
canonical). The level is either a number or the mention {\tt next
level} whose meaning is obvious. The list of levels already assigned
-is on figure~\ref{coq-symbols}. Notice that notations at level 250 are
-necessarily parsed surrounded by parentheses.
-
-\begin{figure}
-\label{coq-symbols}
-\begin{center}
-\begin{tabular}{|l|l|}
-\hline
-notation & precedence/associativity \\
-\hline
-\verb$"_ , _"$ & 250 \\
-\verb$exists _ : _, _$ & 200 \\
-\verb$exists _, _$ & 200 \\
-\verb$exists2 _ : _, _ & _$ & 200 \\
-\verb$exists2 _, _ & _$ & 200 \\
-\verb$"_ <-> _"$ & 95 \\
-\verb$"_ -> _"$ & 90\, R (primitive) \\
-\verb$"_ \/ _"$ & 85\, R \\
-\verb$"_ /\ _"$ & 80\, R \\
-\verb$"~ _"$ & 75\, R \\
-\verb$"_ = _"$ & 70 \\
-\verb$"_ = _ :> _"$ & 70 \\
-\verb$"_ = _ = _"$ & 70 \\
-\verb$"_ <> _"$ & 70 \\
-\verb$"_ <> _ :> _"$ & 70 \\
-\verb$"_ <= _"$ & 70 \\
-\verb$"_ < _"$ & 70 \\
-\verb$"_ > _"$ & 70 \\
-\verb$"_ >= _"$ & 70 \\
-\verb$"_ <= _ <= _"$ & 70 \\
-\verb$"_ <= _ < _"$ & 70 \\
-\verb$"_ < _ <= _"$ & 70 \\
-\verb$"_ < _ < _"$ & 70 \\
-\verb$"_ + _"$ & 50\, L \\
-\verb$"_ - _"$ & 50\, L \\
-\verb$"_ * _"$ & 40\, L \\
-\verb$"_ / _"$ & 40\, L \\
-\verb$"- _"$ & 35\, R \\
-\verb$"/ _"$ & 35\, R \\
-\verb$"_ ^ _"$ & 30\, R \\
-\verb$"{ _ } + { _ }"$ & 0 \\
-\verb$"_ + { _ }"$ & 50\, L \\
-\verb$"{ _ : _ | _ }"$ & 0 \\
-\verb$"{ _ : _ | _ & _ }"$ & 0 \\
-\verb$"{ _ : _ & _ }"$ & 0 \\
-\verb$"{ _ : _ & _ & _ }"$ & 0 \\
-\hline
-\end{tabular}
-\end{center}
-\caption{Notations defined in the initial state of {\Coq}}
-\end{figure}
+is on Figure~\ref{init-notations}.
\subsection{Complex notations}
@@ -223,8 +173,7 @@ Notation "x < y < z" := (x < y /\ y < z) (at level 70, y at next level).
For the sake of factorisation with {\Coq} predefined rules, simple
rules have to be observed for notations starting with a symbol:
e.g. rules starting with ``\{'' or ``('' should be put at level 0. The
-list of {\Coq} predefined notations is given on
-figure~\ref{coq-symbols}.
+list of {\Coq} predefined notations can be found in chapter \ref{Theories}.
\subsection{Displaying symbolic notations}
@@ -328,7 +277,7 @@ infix symbols. Its syntax is
\medskip
-\noindent\texttt{Infix} "{\em symbolentry}" {\qualid} {\tt (} \nelist{\em modifier}{,} {\tt )}.
+\noindent\texttt{Infix} "{\symbolentry}" {\qualid} {\tt (} \nelist{\em modifier}{,} {\tt )}.
\medskip
@@ -336,14 +285,14 @@ and it is equivalent to
\medskip
-\noindent\texttt{Notation "x {\em symbolentry} y" := {\qualid} x y ( \nelist{\em modifier}{,} )}.
+\noindent\texttt{Notation "x {\symbolentry} y" := {\qualid} x y ( \nelist{\em modifier}{,} )}.
\medskip
where {\tt x} and {\tt y} are fresh names distinct from {\qualid}. Here is an example.
\begin{coq_example*}
-Infix "/\\" and (at level 6, right associativity).
+Infix "/\" and (at level 80, right associativity).
\end{coq_example*}
\subsection{Reserving notations}
@@ -362,7 +311,7 @@ Reserved Notation "x = y" (at level 70, no associativity).
Reserving a notation is also useful for simultaneously defined an
inductive type or a recursive constant and a notation for it.
-\Rem The notations mentionned on table~\ref{coq-symbols} are
+\Rem The notations mentioned on Figure~\ref{init-notations} are
reserved. Hence their precedence and associativity cannot be changed.
\subsection{Simultaneous definition of terms and notations}
@@ -398,6 +347,33 @@ Locate "'exists' _ , _".
\label{scopes}
% Introduction
+An {\em interpretation scope} is a set of notations for terms with
+their interpretation. Interpretation scopes provides with a weak,
+purely syntactical form of notations overloading: a same notation, for
+instance the infix symbol \verb=+= can be used to denote distinct
+definitions of an additive operator. Depending on which interpretation
+scopes is currently open, the interpretation is different.
+
+\subsection{Interpretation rules for notations}
+
+At any time, the interpretation of a notation for term is done within
+a {\em stack} of interpretation scopes and lonely notations. In case a
+notation has several interpretations, the actual interpretation is the
+one defined by (or in) the more recently declared (or open) lonely
+notation (or interpretation scope) which defines this notation.
+Typically if a given notation is defined in some scope {\scope} but
+has also an interpretation not assigned to a scope, then, if {\scope}
+is open before the lonely interpretation is declared, then the lonely
+interpretation is used (and this is the case even if the
+interpretation of the notation in {\scope} is given after the lonely
+interpretation: otherwise said, only the order of lonely
+interpretations and opening of scopes matters, and not the declaration
+of interpretations within a scope).
+
+The initial state of {\Coq} declares three interpretation scopes and
+no lonely notations. These scopes, in opening order, are {\tt
+core\_scope}, {\tt type\_scope} and {\tt nat\_scope}.
+
\subsection{Notations in scope}
\subsection{Activation of interpretation scopes}
@@ -411,20 +387,93 @@ Locate "'exists' _ , _".
\subsection{Interpretation scopes of arguments}
+
+
+\subsection{The type interpretation scope}
+
+The scope {\tt type\_scope} has a special status. It is a primitive
+interpretation scope which is temporarily activated each time a
+subterm of an expression is expected to be a type. This includes goals
+and statements, types of binders, domain and codomain of implication,
+codomain of products, and more generally any type argument of a
+declared or defined constant.
+
\subsection{Interpretation scopes used in the standard library of {\Coq}}
-% nat_scope
-% N_scope
-% Z_scope
-% positive_scope
-% bool_scope
-% list_scope
+We give an overview of the scopes used in the standard library of
+{\Coq}. For a complete list of notations in each scope, use the
+commands {\tt Print Scopes} or {\tt Print Scopes {\scope}}.
+
+\subsubsection{\tt type\_scope}
+
+This includes infix {\tt *} for product types and infix {\tt +} for
+sum types. It is delimited by key {\tt type}.
+
+\subsubsection{\tt nat\_scope}
+
+This includes the standard arithmetical operators and relations on
+type {\tt nat}. Positive numerals in this scope are mapped to their
+canonical representent built from {\tt O} and {\tt S}. The scope is
+delimited by key {\tt nat}.
+
+\subsubsection{\tt N\_scope}
+
+This includes the standard arithmetical operators and relations on
+type {\tt N} (binary natural numbers). It is delimited by key {\tt N}.
+
+\subsubsection{\tt Z\_scope}
+
+This includes the standard arithmetical operators and relations on
+type {\tt Z} (binary integer numbers). It is delimited by key {\tt Z}.
+
+\subsubsection{\tt Z\_scope}
+
+This includes the standard arithmetical operators and relations on
+type {\tt positive} (binary strictly positive numbers). It is
+delimited by key {\tt positive}.
+
+\subsubsection{\tt bool\_scope}
+
+This includes notations for the boolean operators.
+
+\subsubsection{\tt list\_scope}
+
+This includes notations for the list operators.
+
+\subsubsection{\tt core\_scope}
+
+This includes the notation for pairs. It is delimited by key {\tt core}.
\subsection{Displaying informations about scopes}
-% Print Visibility name_opt
-% Print Scope name
-% Print Scopes
+\subsubsection{\tt Print Visibility}
+
+This displays the current stack of notations in scopes and lonely
+notations that is used to interpret a notation. The top of the stack
+is displayed last. Notations in scopes whose interpretation is hidden
+by the same notation in a more recently open scope are not
+displayed. Hence each notation is displayed only once.
+
+\variant
+
+{\tt Print Visibility {\scope}}\\
+
+This displays the current stack of notations in scopes and lonely
+notations assuming that {\scope} is pushed on top of the stack. This
+is useful to know how a subterm locally occurring in the scope of
+{\scope} is interpreted.
+
+\subsubsection{\tt Print Scope {\scope}}
+
+This displays all the notations defined in interpretation scope
+{\scope}. It also displays the delimiting key if any and the class to
+which the scope is bound, if any.
+
+\subsubsection{\tt Print Scopes}
+
+This displays all the notations, delimiting keys and corresponding
+class of all the existing interpretation scopes.
+It also displays the lonely notations.
\section{Abbreviations}
\index{Abbreviations}
@@ -486,1825 +535,49 @@ Notation}.
\paragraph{Syntax of notations}
The different syntactic variants of the command \texttt{Notation} are
-the following
-
-\begin{itemize}
-
-\item \texttt{Notation} {\str} \texttt{:=} {\term}.
-
-\item \texttt{Notation} {\ident} \texttt{:=} {\term}.
-
-\item \texttt{Notation} {\str} \texttt{:=} {\term} {\tt (} \nelist{\em modifier}{,} {\tt )}.
-
-\end{itemize}
-
-where a {\em modifier} is one of \texttt{at level $n$},
-\texttt{ at next level},
-\texttt{ no associativity}, \texttt{ right
-associativity}, \texttt{ left associativity},
-\texttt{ \nelist{\ident}{,} at level $n$},
-\texttt{ \nelist{\ident}{,} at next level}, \texttt{ only parsing} or
-\texttt{ format {\str}}.
-
-\Rem No typing of the denoted expression is performed at definition
-time. Type-checking is done only at the time of use of the notation.
-
-\Rem Many examples of {\tt Notation} may be found in the files
-composing the initial state of {\Coq} (see directory {\tt
-\$COQLIB/theories/Init}).
-
-%\section{Symbolic interpretation scopes}
-%
-%TODO
-
-\iffalse
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\chapter{syntax extensions}
-\label{Addoc-syntax}
-
-In this chapter, we introduce advanced commands to modify the way
-{\Coq} parses and prints objects, i.e. the translations between the
-concrete and internal representations of terms and commands. As in
-most compilers, there is an intermediate structure called {\em Abstract
-Syntax Tree} (AST). Parsing a term is done in two steps\footnote{
- We omit the lexing step, which simply translates a character stream
- into a token stream. If this translation fails, this is a
- \emph{Lexical error}.
-}:
-\begin{enumerate}
-\item An AST is build from the input (a stream of tokens), following
- grammar rules. This step consists in deciding whether the input
- belongs to the language or not. If it is, the parser transforms the
- expression into an AST. If not, this is a syntax error. An expression
- belongs to the language if there exists a sequence of grammar rules
- that recognizes it. This task is delegated to {\camlpppp}. See the
- Reference Manual~\cite{ddr98} for details on the parsing
- technology. The transformation to AST is performed by executing
- successively the {\sl actions} bound to these rules.
-
-\item The AST is translated into the internal representation of
- commands and terms. At this point, we detect unbound variables and
- determine the exact section-path of every global value. Then, the term
- may be typed, computed,~\ldots
-\end{enumerate}
-The printing process is the reverse: commands or terms are first
-translated into AST's, and then the pretty-printer translates this AST
-into a printing orders stream, according to printing rules.
-
-In {\Coq}, only the translations between AST's and the concrete
-representation are extendable. One can modify the set of grammar and
-printing rules, but one cannot change the way AST's are interpreted in
-the internal level.
-
-In the following section, we describe the syntax of AST expressions,
-involved in both parsing and printing. The next two sections deal with
-extendable grammars and pretty-printers.
-
-\section{Abstract syntax trees (AST)}
-\index{AST}
-\index{Abstract syntax tree}
-
-\label{astsyntax}
-
-The AST expressions are conceptually divided into two classes:
-\emph{constructive expressions} (those that can be used in parsing
-rules) and \emph{destructive expressions} (those that can be used in
-pretty printing rules). In the following we give the concrete syntax
-of expressions and some examples of their usage.
-
-The BNF grammar {\sl ast} in Fig.~\ref{astexpr} defines the syntax
-of both constructive and destructive expressions. The lexical
-conventions are the same as in section~\ref{lexical}. Let us first
-describe the features common to constructive and destructive
-expressions.
-
-\begin{figure}
-\begin{center}
-\begin{tabular}{|rclr|}
-\hline
-{\sl ast} & ::= & {\sl meta} & (metavariable) \\
-& $|$ & {\ident} & (variable)\\
-& $|$ & {\integer} & (positive integer)\\
-& $|$ & {\sl string} & (quoted string) \\
-& $|$ & {\sl path} & (section-path) \\
-& $|$ & \verb+{+ {\ident} \verb+}+ & (identifier) \\
-& $|$ & \verb+[+ {\sl name} \verb+]+ {\sl ast} & (abstraction) \\
-& $|$ & \verb+(+ {\ident}~~\sequence{{\sl ast}}{} \verb+)+
- & (application node)\\
-& $|$ & \verb+(+ {\sl special-tok}~~{\sl meta} \verb+)+
- & (special-operator) \\
-& $|$ & \verb+'+ {\sl ast} & (quoted ast) \\
-& $|$ & {\sl quotation} & \\
-
-{\sl meta} & ::= & \verb+$+{\ident} & \\
-%$
-{\sl path} & ::= & \nelist{{\tt\#}{\ident}}{} \verb+.+ {\sl kind} & \\
-{\sl kind} & ::= & \verb+cci+ $~|~$\verb+fw+ $~|~$ \verb+obj+ & \\
-{\sl name} & ::= & \verb+<>+ ~$|$~ {\ident} ~$\mid$~ {\sl meta} & \\
-
-{\sl special-tok} & ::= &
- \verb+$LIST+~$|$~\verb+$VAR+~$|$~\verb+$NUM+~$|$~%
- \verb+$STR+~$|$~\verb+$PATH+~$|$~\verb+$ID+ & \\
-
-{\sl quotation}& ::= &
- \verb+<<+ ~{\sl meta-constr}~ \verb+>>+ & \\
-& $|$ & \verb+<:constr:<+ ~{\sl meta-constr}~ \verb+>>+ & \\
-& $|$ & \verb+<:vernac:<+ ~{\sl meta-vernac}~ \verb+>>+ & \\
-& $|$ & \verb+<:tactic:<+ ~{\sl meta-tactic}~ \verb+>>+ & \\
-\hline
-\end{tabular}
-\end{center}
-\caption{Syntax of AST expressions}\label{astexpr}
-\end{figure}
-
-\subsubsection{Atomic AST}
-
-An atomic AST can be either a variable, a natural number, a quoted
-string, a section path or an identifier. They are the basic components
-of an AST.
-
-\subsubsection{Metavariable}
-\index{Metavariable}
-
-Metavariables are used to perform substitutions in constructive
-expressions: they are replaced by their value in a given
-environment. They are also involved in the pattern matching operation:
-metavariables in destructive patterns create new bindings in the
-environment.
-
-As we will see later, metavariables may denote an AST or an AST list
-(when used with the \verb+$LIST+ special token).
-%$
-So, we introduce two types of variables: \verb+ast+ and
-\verb+ast list+. The type of variables is checked statically: an
-expression referring to undefined metavariables, or using metavariables
-with an inappropriate type, will be rejected.
-
-\subsubsection{Application node}
-
-Note that the AST syntax is rather general, since application nodes
-may be labelled by an arbitrary identifier (but not a metavariable),
-and operators have no fixed arity. This enables the extensibility of
-the system.
-
-Nevertheless there are some application nodes that have some special
-meaning for the system. They are build on \verb+(+{\sl
-special-tok}~{\sl meta}\verb+)+, and cannot be confused with regular
-nodes since {\sl special-tok} begins with a \verb+$+.
-%$
-There is a description of these nodes below.
-
-\subsubsection{Abstraction}
-
-The equality on AST's is the $\alpha$-conversion, i.e. two AST's are
-equal if only they are the same up to renaming of bound variables
-(thus, \verb+[x]x+ is equal to \verb+[y]y+). This makes the difference
-between variables and identifiers clear: the former may be bound by
-abstractions, whereas identifiers cannot be bound. To illustrate this,
-\verb+[x]x+ and \verb+[y]y+ are equal and \verb+[x]{x}+ is equal to
-\verb+[y]{x}+, but not to \verb+[y]{y}+.
-
-The binding structure of AST is used to represent the binders in the
-terms of {\Coq}: the product \verb+(x:$A)$B+ is mapped to the AST
-\verb+(PROD $A [x]$B)+, whereas the non dependent product
-\verb+$A->$B+ is mapped to \verb+(PROD $A [<>]$B)+ (\verb+[<>]t+ is an
-anonymous abstraction).
-
-Metavariables can appear in abstractions. In that case, the value of
-the metavariable must be a variable (or a list of variables). If not,
-a run-time error is raised.
-
-\subsubsection{Quoted AST}
-\index{Quoted AST}
-
-The \verb+'+$t$ construction means that the AST $t$ should not be
-interpreted at all. The main effect is that metavariables occurring in
-it cannot be substituted or considered as binding in patterns.
-
-\subsubsection{Quotations}
-\index{Quotations}
-
-The non terminal symbols {\sl meta-constr}, {\sl meta-vernac} and
-{\sl meta-tactic} stand, respectively, for the syntax of CIC terms,
-vernacular phrases and tactics. The prefix {\sl meta-} is just to
-emphasize that the expression may refer to metavariables.
-
-Indeed, if the AST to generate corresponds to a term that already has
-a syntax, one can call a grammar to parse it and to return the AST
-result. For instance, \verb+<<(eq ? $f $g)>>+ denotes the AST which is
-the application (in the sense of CIC) of the constant {\tt eq} to
-three arguments. It is coded as an AST node labelled {\tt APPLIST}
-with four arguments.
-
-This term is parsable by \verb+constr:constr+ grammar. This grammar
-is invoked on this term to generate an AST by putting the term between
-``\verb+<<+'' and ``\verb+>>+''.
-
-We can also invoke the initial grammars of several other predefined
-entries (see section~\ref{predefined-grammars} for a description of
-these grammars).
-
-\begin{itemize}
-\item \verb|<:constr:< t >>| parses {\tt t} with {\tt constr:constr}
- grammar(terms of CIC).
-\item \verb|<:vernac:< t >>| parses {\tt t} with {\tt vernac:vernac}
- grammar (vernacular commands).
-\item \verb|<:tactic:< t >>| parses {\tt t} with {\tt tactic:tactic}
- grammar (tactic expressions).
-\item \verb|<< t >>| parses {\tt t} with the default quotation (that
- is, {\tt constr:constr}). It is the same as \verb|<:constr:< t >>|.
-\end{itemize}
+given on Figure \ref{Grammar-Notation}.
-\Warning
-One cannot invoke other grammars than those described.
-
-\subsubsection{Special operators in constructive expressions}
-
-The expressions \verb+($LIST $x)+ injects the AST list variable
-{\tt\$x} in an AST position. For example, an application node is
-composed of an identifier followed by a list of AST's that are glued
-together. Each of these expressions must denote an AST. If we want to
-insert an AST list, one has to use the \verb+$LIST+ operator. Assume
-the variable \verb+$idl+ is bound to the list \verb+[x y z]+, the
-expression \verb+(Intros ($LIST $idl) a b c)+ will build the AST
-\verb+(Intros x y z a b c)+. Note that \verb+$LIST+ does not occur in
-the result.
-%$
-
-% Ameliorer le style!
-Since we know the type of variables, the \verb+$LIST+
-%$
-is not really
-necessary. We enforce this annotation to stress on the fact that the
-variable will be substituted by an arbitrary number of AST's.
-
-The other special operators ({\tt\$VAR}, {\tt\$NUM}, {\tt\$STR},
-{\tt\$PATH} and {\tt\$ID}) are forbidden.
-
-\subsubsection{Special operators in destructive expressions (AST patterns)}
-\label{patternsyntax}
-\index{AST patterns}
-
-% pas encore implante (serait utile pour afficher les LAMBDALIST et
-% PRODLIST).
-%\item \verb+($SLAM $l body)+ is used to denote an abstraction where
-% the elements of the list variable \verb+$l+ are the variables
-%%$
-% simultaneously abstracted in \verb+body+.
-% The production to recognize a lambda abstraction of the form
-% $[x_1,\ldots,x_n:T]body$ use the operator \verb+$SLAM+:
-
-A pattern is an AST expression, in which some metavariables can
-appear. In a given environment a pattern matches any AST which is
-equal (w.r.t $\alpha$-conversion) to the value of the pattern in an
-extension of the current environment. The result of the matching is
-precisely this extended environment. This definition allows
-non-linear patterns (i.e. patterns in which a variable occurs several
-times).
-
-For instance, the pattern \verb+(PAIR $x $x)+ matches any AST which is
-a node labelled {\tt PAIR} applied to two identical arguments, and
-binds this argument to {\tt\$x}. If {\tt\$x} was already bound, the
-arguments must also be equal to the current value of {\tt\$x}.
-
-The ``wildcard pattern'' \verb+$_+ is not a regular metavariable: it
-matches any term, but does not bind any variable. The pattern
-\verb+(PAIR $_ $_)+ matches any {\tt PAIR} node applied to two
-arguments.
-
-The {\tt\$LIST} operator still introduces list variables. Typically,
-when a metavariable appears as argument of an application, one has to
-say if it must match \emph{one} argument (binding an AST variable), or
-\emph{all} the arguments (binding a list variable). Let us consider
-the patterns \verb+(Intros $id)+ and \verb+(Intros ($LIST $idl))+. The
-former matches nodes with \emph{exactly} one argument, which is bound
-in the AST variable {\tt\$id}. On the other hand, the latter pattern
-matches any AST node labelled {\tt Intros}, and it binds the
-\emph{list} of its arguments to the list variable {\tt\$idl}. The
-{\tt\$LIST} pattern must be the last item of a list pattern, because
-it would make the pattern matching operation more complicated and less
-efficient. The pattern \verb+(Intros ($LIST $idl) $lastid)+ is not
-accepted.
-
-The other special operators allows checking what kind of leaf we
-are destructing:
-\begin{itemize}
-\item{\tt\$VAR} matches only variables
-\item{\tt\$NUM} matches natural numbers
-\item{\tt\$STR} matches quoted strings
-\item{\tt\$PATH} matches section-paths
-\item{\tt\$ID} matches identifiers
-\end{itemize}
-\noindent For instance, the pattern \verb+(DO ($NUM $n) $tc)+ matches
-\verb+(DO 5 (Intro))+, and creates the bindings ({\tt\$n},5) and
-({\tt\$tc},\verb+(Intro)+). The pattern matching would fail on
-\verb+(DO "5" (Intro))+.
-
-\section{Extendable grammars}
-\label{Grammar}
-\index{Extendable Grammars}
-\comindex{Grammar}
-
-Grammar rules can be added with the {\tt Grammar} command. This
-command is just an interface towards {\camlpppp}, providing the
-semantic actions so that they build the expected AST. A simple grammar
-command has the following syntax: \index{Grammar@{\tt Grammar}}
-
-\begin{center}
-\texttt{Grammar}~\textsl{entry}~\textsl{nonterminal}~\texttt{:=}~%
-\textsl{rule-name}~\textsl{LMP}~\verb+->+~\textsl{action}~\texttt{.}
-\end{center}
-
-The components have the following meaning:
-\begin{itemize}
-\item a grammar name: defined by a parser entry and a non-terminal.
- Non-terminals are packed in an \emph{entry} (also called
- universe). One can have two non-terminals of the same name if they
- are in different entries. A non-terminal can have the same name as
- its entry.
-\item a rule (sometimes called production), formed by a name, a left
- member of production and an action, which generalizes constructive
- expressions.
-\end{itemize}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
-\begin{center}
-\begin{tabular}{|rcl|}
+\begin{tabular}{|lcl|}
\hline
-{\sl grammar} & ::= &
- \verb+Grammar+~{\sl entry}~\nelist{{\sl gram-entry}}{with} \\
-{\sl entry}& ::= & {\ident} \\
-{\sl gram-entry} & ::= &
- {\sl rule-name}~\zeroone{{\tt :}~{\sl entry-type}}~\verb+:=+~%
-% [{\sl assoc}]~
-\sequence{{\sl production}}{|} \\
-{\sl entry-type} & ::= &
- \verb+ast+~$|$~\verb+ast list+~$|$~\verb+constr+
- ~$|$~\verb+tactic+~$|$~\verb+vernac+ \\
-%{\sl assoc} & ::= & \verb+LEFTA+~$|$~\verb+RIGHTA+~$|$~\verb+NONA+ \\
-% parler de l'associativite ?
-% Cela n'a pas vraiment de sens si toutes les re`gles sont dans un
-% meme niveau pour Camlp4.
-{\sl production} & ::= &
- {\sl rule-name}~\verb+[+~\sequence{{\sl prod-item}}{}~\verb+] ->+
- ~{\sl action}\\
-{\sl rule-name} & ::= & {\sl ident} \\
-{\sl prod-item} & ::= & {\sl string} \\
-& | & \zeroone{{\sl entry}~{\tt :}}~{\sl entry-name}~%
- \zeroone{{\tt (}~{\sl meta}~{\tt )}} \\
-{\sl action} & ::= &
- \verb+[+~\sequence{{\sl ast-quote}}{}~\verb+]+ \\
-& | & \verb+let+~{\sl pattern}~\verb+=+~{\sl action}~%
- \verb+in+~{\sl action} \\
-& | & {\tt case}~{\sl action}~\zeroone{{\tt :}~{\sl entry-type}}~{\tt of}~%
- \sequence{{\sl case}}{|}~{\tt esac} \\
-{\sl case} & ::= & \sequence{{\sl pattern}}{}~\verb+->+~{\sl action} \\
-{\sl pattern} & ::= & {\sl ast} \\
+{\sentence} & ::= &
+ \texttt{Notation} \zeroone{\tt Local} {\str} \texttt{:=} {\term}
+ \zeroone{\modifiers} \zeroone{:{\scope}} \verb=.=\\
+ & $|$ &
+ \texttt{Infix} \zeroone{\tt Local} {\str} \texttt{:=} {\qualid}
+ \zeroone{\modifiers} \zeroone{:{\scope}} \verb=.=\\
+ & $|$ &
+ \texttt{Notation} \zeroone{\tt Local} {\ident} \texttt{:=} {\term}
+ \zeroone{\tt (only parsing)} \verb=.=\\
+ & $|$ &
+ \texttt{Reserved Notation} \zeroone{\tt Local} {\str}
+ \zeroone{\modifiers} \verb=.=\\
+\\
+{\modifiers}
+ & ::= & \nelist{\ident}{,} {\tt at level} {\naturalnumber} \\
+ & $|$ & \nelist{\ident}{,} {\tt at next level} \\
+ & $|$ & {\tt at level} {\naturalnumber} \\
+ & $|$ & {\tt left associativity} \\
+ & $|$ & {\tt right associativity} \\
+ & $|$ & {\tt no associativity} \\
+ & $|$ & {\ident} {\tt ident} \\
+ & $|$ & {\ident} {\tt global} \\
+ & $|$ & {\ident} {\tt bigint} \\
+ & $|$ & {\tt only parsing} \\
+ & $|$ & {\tt format} {\str} \\
\hline
\end{tabular}
-\end{center}
-\caption{Syntax of the grammar extension command}\label{grammarsyntax}
+\caption{Syntax of the variants of {\tt Notation}}
+\label{record-syntax}
\end{figure}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-The exact syntax of the {\tt Grammar} command is defined
-in Fig.~\ref{grammarsyntax} where non terminal {\sl ast-quote} is one
-of {\tt ast}, {\tt constr}, {\tt tactic} or {\tt vernac}, depending on
-the entry type.
-
-It is possible to extend a grammar with several rules at once.
-$$
-\begin{array}{rcc}
-\verb+Grammar+~~entry~~nonterminal
- & \verb+:=+ & production_1 \\
- & \verb+|+ & \vdots \\
- & \verb+|+ & production_n \verb+.+ \\
-\end{array}
-$$
-Productions are entered in reverse order (i.e. $production_n$ before
-$production_1$), so that the first rules have priority over the last
-ones. The set of rules can be read as an usual pattern matching.
-
-\noindent Also, we can extend several grammars of a given universe at
-the same time. The order of non-terminals does not matter since they
-extend different grammars.
-$$
-\begin{array}{rcccc}
-\verb+Grammar+ & entry & nonterminal_1
- & \verb+:=+ & production_1^1 \\
- && & \verb+|+ & \vdots \\
- && & \verb+|+ & production_{n_1}^1 \\
- & \verb+with+ & \vdots && \\
- & \verb+with+ & nonterminal_p
- & \verb+:=+ & production_1^p \\
- && & \verb+|+ & \vdots \\
- && & \verb+|+ & production_{n_p}^p \verb+.+ \\
-\end{array}
-$$
-
-
-\subsection{Grammar entries}
-\index{Grammar entries}
-\label{predefined-grammars}
-
-Let us describe the four predefined entries. Each of them (except {\tt
-prim}) possesses an initial grammar for starting the parsing process.
-
-\begin{itemize}
-\item \verb+prim+ : it is the entry of the primitive grammars. Most of
- them cannot be defined by the extendable grammar mechanism. They are
- encoded inside the system. The entry contains the following
- non-terminals:
-
-\begin{itemize}
-\item \verb+var+ : variable grammar. Parses an identifier and builds
-an AST which is a variable.
-\item \verb+ident+ : identifier grammar. Parses an identifier and
-builds an AST which is an identifier such as \verb+{x}+.
-\item \verb+number+ : number grammar. Parses a positive integer.
-\item \verb+string+ : string grammar. Parses a quoted string.
-\item \verb+path+ : section path grammar.
-\item \verb+ast+ : AST grammar.
-\item \verb+astpat+ : AST pattern grammar.
-\item \verb+astact+ : action grammar.
-\end{itemize}
-
-The primitive grammars are used as the other grammars; for instance
-the variables of terms are parsed by \verb+prim:var($id)+.
-
-\item \verb+constr+ : it is the term entry. It allows to have a pretty
-syntax for terms. Its initial grammar is {\tt constr:constr}. This
-entry contains several non-terminals, among them {\tt constr0} to
-{\tt constr10} which stratify the terms according to priority levels
-(\verb+0+ to \verb+10+). These priority levels allow us also to
-specify the order of associativity of operators.
-
-% Ce serait bien si on etait capables de donner une table avec les
-% niveaux de priorite de chaque operateur...
-
-\item \verb+vernac+ : it is the vernacular command entry, with {\tt
- vernac vernac} as initial grammar. Thanks to it, the developers can
- define the syntax of new commands they add to the system. As to
- users, they can change the syntax of the predefined vernacular
- commands.
-
-\item \verb+tactic+ : it is the tactic entry with {\tt tactics:tactic}
- as initial grammar. This entry allows to define the syntax of new
- tactics or redefine the syntax of existing tactics.
-% See chapter~\ref{WritingTactics} about user-defined tactics
-% for more details.
-
-\end{itemize}
-
-The user can define new entries and new non-terminals, using the
-grammar extension command. A grammar does not have to be explicitly
-defined. But the grammars in the left member of rules must all be
-defined, possibly by the current grammar command. It may be convenient
-to define an empty grammar, just so that it may be called by other
-grammars, and extend this empty grammar later. Assume that the {\tt
-constr:constr13} does not exist. The next command defines it with
-zero productions.
-
-\begin{coq_example*}
-Grammar constr constr13 := .
-\end{coq_example*}
-
-The grammars of new entries do not have an initial grammar. To use
-them, they must be called (directly or indirectly) by grammars of
-predefined entries. We give an example of a (direct) call of the
-grammar {\tt newentry:nonterm} by {\tt constr:constr}. This following
-rule allows to use the syntax \verb+a&b+ for the conjunction
-\verb+a/\b+. Note that since we extend a rule of universe
-\verb+constr+, the command quotation is used on the right-hand side of
-the second rule.
-
-\begin{coq_example}
-Grammar newentry nonterm :=
- ampersand [ "&" constr:constr($c) ] -> [$c].
-Grammar constr constr :=
- new_and [ constr8($a) newentry:nonterm($b) ] -> [$a/\$b].
-\end{coq_example}
-
-
-\subsection{Left member of productions (LMP)}
-
-A LMP is composed of a combination of terminals (enclosed between
-double quotes) and grammar calls specifying the entry. It is enclosed
-between ``\verb+[+'' and ``\verb+]+''. The empty LMP, represented by
-\verb+[ ]+, corresponds to $\epsilon$ in formal language theory.
-
-A grammar call is done by \verb+entry:nonterminal($id)+ where:
-\begin{itemize}
-\item \verb+entry+ and \verb+nonterminal+
- specifies the entry of the grammar, and the non-terminal.
-\item \verb+$id+ is a metavariable that will receive the AST or AST
- list resulting from the call to the grammar.
-\end{itemize}
-
-The elements \verb+entry+ and \verb+$id+ are optional. The grammar
-entry can be omitted if it is the same as the entry of the
-non-terminal we are extending. Also, \verb+$id+ is omitted if we do
-not want to get back the AST result. Thus a grammar call can be
-reduced to a non-terminal.
-
-Each terminal must contain exactly one token. This token does not need
-to be already defined. If not, it will be automatically
-added. Nevertheless, any string cannot be a token (e.g. blanks should
-not appear in tokens since parsing would then depend on
-indentation). We introduce the notion of \emph{valid token}, as a
-sequence, without blanks, of characters taken from the following list:
-\begin{center}
-\verb"< > / \ - + = ; , | ! @ # % ^ & * ( ) ? : ~ $ _ ` ' a..z A..Z 0..9"
-\end{center}
-that do not start with a character from
-\begin{center}
-\verb!$ _ a..z A..Z ' 0..9!
-\end{center}
-
-When an LMP is used in the parsing process of an expression, it is
-analyzed from left to right. Every token met in the LMP should
-correspond to the current token of the expression. As for the grammars
-calls, they are performed in order to recognize parts of the initial
-expression.
-
-\Warning
-Unlike destructive expressions, if a variable appears several times in
-the LMP, the last binding hides the previous ones. Comparison can be
-performed only in the actions.
-
-
-\firstexample
-\example{Defining a syntax for inequality}
-
-The rule below allows us to use the syntax \verb+t1#t2+ for the term
-\verb+~t1=t2+.
-
-\begin{coq_example}
-Grammar constr constr1 :=
- not_eq [ constr0($a) "#" constr0($b) ] -> [ ~$a=$b ].
-\end{coq_example}
-
-The level $1$ of the grammar of terms is extended with one rule named
-\texttt{not\_eq}. When this rule is selected, its LMP calls the
-grammar \verb+constr:constr0+. This grammar recognizes a term that it
-binds to the metavariable \verb+$a+. Then it meets the token
-``\verb+#+'' and finally it calls the grammar
-\verb+constr:constr0+. This grammar returns the recognized term in
-\verb+$b+. The action constructs the term \verb+~$a=$b+.
-
-For instance, let us give the statement of the symmetry of \verb+#+:
-
-\begin{coq_example}
-Goal (A:Set)(a,b:A) a#b -> b#a.
-\end{coq_example}
-
-This shows that the system understood the grammar
-extension. Nonetheless, since no special printing command was given,
-the goal is displayed using the usual syntax for negation and
-equality. One can force \verb+~a=b+ to be printed \verb=a#b= by giving
-pretty-printing rules. This is explained in section~\ref{Syntax}.
-
-\Warning
-Metavariables are identifiers preceded by the ``\verb+$+'' symbol.
-They cannot be replaced by identifiers. For instance, if we enter a
-rule with identifiers and not metavariables, the identifiers are
-assumed to be global names (what raises a warning if no global name is
-denoted by these identifiers).
-
-% Test failure
-\begin{coq_example}
-Grammar constr constr1 :=
- not_eq [ constr0($a) "#" constr0($b) ] -> [~(a=b)].
-\end{coq_example}
-
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\example{Redefining vernac commands}
-
-Thanks to the following rule, ``{\tt |- term.}'' will have the same
-effect as ``{\tt Goal term.}''.
-
-\begin{coq_example}
-Grammar vernac vernac :=
- thesis [ "|" "-" constr:constr($term) "." ]
- -> [Goal $term.].
-\end{coq_example}
-
-\noindent This rule allows putting blanks between the bar and the
-dash, as in
-
-\begin{coq_example}
-| - (A:Prop)A->A.
-\end{coq_example}
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-
-\noindent Assuming the previous rule has not been entered, we can
-forbid blanks with a rule that declares ``\verb+|-+'' as a single
-token:
-
-\begin{coq_eval}
-(********** The following is not correct and should produce **********)
-(*************** Syntax error: illegal begin of vernac ***************)
-(* Just to adjust the prompt: *) Set Printing Depth 50.
-\end{coq_eval}
-\begin{coq_example}
-Grammar vernac vernac :=
- thesis [ "|-" constr:constr($term) "." ]
- -> [Goal $term.].
-| - (A:Prop)A->A.
-\end{coq_example}
-
-\noindent If both rules were entered, we would have three tokens
-\verb+|+, \verb+-+ and \verb+|-+. The lexical ambiguity on the string
-\verb+|-+ is solved according to the longest match rule (see lexical
-conventions page~\pageref{lexical}), i.e. \verb+|-+ would be one
-single token. To enforce the use of the first rule, a blank must be
-inserted between the bar and the dash\footnote{It turns out that "|-"
-is already a token defined for other purposes, then the first rule
-cannot parse "|- (A:Prop)A->A" and indeed requires the insertion of a blank}.
-
-
-\Rem
-The vernac commands should always be terminated by a period. When a
-syntax error is detected, the top-level discards its input until it
-reaches a period token, and then resumes parsing.
-
-\example{Redefining tactics}
-
-We can give names to repetitive tactic sequences. Thus in this example
-``{\tt IntSp}'' will correspond to the tactic {\tt Intros} followed by
-{\tt Split}.
-
-\begin{coq_example}
-Grammar tactic simple_tactic :=
- intros_split [ "IntSp" ] -> [Intros; Split].
-\end{coq_example}
-
-Let us check that this works.
-
-\begin{coq_example}
-Goal (A,B:Prop)A/\B -> B/\A.
-IntSp.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-Note that the same result can be obtained in a simpler way with {\tt
-Tactic Definition} (see chapter~\ref{TacticLanguage}).
-
-\example{Priority, left and right associativity of operators}
-
-The disjunction has a higher priority than conjunction. Thus
-\verb+A/\B\/C+ will be parsed as \verb+(A/\B)\/C+ and not as
-\verb+A/\(B\/C)+. The priority is done by putting the rule for the
-disjunction in a higher level than that of conjunction: conjunction is
-defined in the non-terminal {\tt constr6} and disjunction in {\tt
-constr7} (see file {\tt Logic.v} in the library). Notice that
-the character ``\verb+\+'' must be doubled (see lexical conventions
-for quoted strings on page~\pageref{lexical}).
-
-\begin{coq_example*}
-Grammar constr constr6 :=
- and [ constr5($c1) "/\\" constr6($c2) ] -> [(and $c1 $c2)].
-Grammar constr constr7 :=
- or [ constr6($c1) "\\/" constr7($c2) ] -> [(or $c1 $c2)].
-\end{coq_example*}
-
-Thus conjunction and disjunction associate to the right since in both
-cases the priority of the right term (resp. {\tt constr6} and {\tt
-constr7}) is higher than the priority of the left term (resp. {\tt
-constr5} and {\tt constr6}). The left member of a conjunction cannot
-be itself a conjunction, unless you enclose it inside parenthesis.
-
-The left associativity is done by calling recursively the
-non-terminal. {\camlpppp} deals with this recursion by first trying
-the non-left-recursive rules. Here is an example taken from the
-standard library, defining a syntax for the addition on integers:
-
-\begin{coq_example*}
-Grammar znatural expr :=
- expr_plus [ expr($p) "+" expr($c) ] -> [(Zplus $p $c)].
-\end{coq_example*}
-
-
-
-\subsection{Actions}
-\label{GramAction}
-\index{Grammar Actions}
-
-Every rule should generate an AST corresponding to the syntactic
-construction that it recognizes. This generation is done by an
-action. Thus every rule is associated to an action. The syntax has
-been defined in Fig.~\ref{grammarsyntax}. We give some examples.
-
-\subsubsection{Simple actions}
-
-A simple action is an AST enclosed between ``\verb+[+'' and
-``\verb+]+''. It simply builds the AST by interpreting it as a
-constructive expression in the environment defined by the LMP. This
-case has been illustrated in all the previous examples. We will later
-see that grammars can also return AST lists.
-
-
-\subsubsection{Local definitions}
-
-When an action should generate a big term, we can use
-\texttt{let}~\textsl{pattern}~\texttt{=}~\textsl{action}$_1$~%
-\texttt{in}~\textsl{action}$_2$\index{let@{\tt let}} expressions to
-construct it progressively. The action \textsl{action}$_1$ is first
-computed, then it is matched against \textsl{pattern} which may bind
-metavariables, and the result is the evaluation of \textsl{action}$_2$
-in this new context.
-
-\example{}
-
-\noindent From the syntax \verb|t1*+t2|, we generate the term
-{\tt (plus (plus t1 t2) (mult t1 t2))}.
-
-\begin{coq_example}
-Grammar constr constr1 :=
- mult_plus [ constr0($a) "*" "+" constr0($b) ]
- -> let $p1=[(plus $a $b)] in
- let $p2=[(mult $a $b)] in
- [(plus $p1 $p2)].
-\end{coq_example}
-
-Let us give an example with this syntax:
-
-\begin{coq_example}
-Goal (O*+O)=O.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsubsection{Conditional actions}
-
-We recall the syntax of conditional actions:
-
-\begin{center}
-\texttt{case}~\textsl{action}~\texttt{of}~%
-\textsl{pattern}$_1$~\verb+->+~\textsl{action}$_1$~%
-\texttt{|}~$\cdots$~\texttt{|}~%
-\textsl{pattern}$_n$~\verb+->+~\textsl{action}$_n$~%
-\texttt{esac}
-\end{center}\index{case@@{\tt case}}
-
-The action to execute is chosen according to the value of
-\textsl{action}. The matching is performed from left to right. The
-selected action is the one associated to the first pattern that
-matches the value of \textsl{action}. This matching operation will
-bind the metavariables appearing in the selected pattern. The pattern
-matching does need being exhaustive, and no warning is emitted. When the
-pattern matching fails a message reports in which grammar rule the
-failure happened.
-
-\example{Overloading the ``$+$'' operator}
-
-The internal representation of an expression such as {\tt A+B} depends
-on the shape of {\tt A} and {\tt B}:
-\begin{itemize}
-\item \verb/{P}+{Q}/ uses {\tt sumbool}
-\item otherwise, \verb/A+{Q}/ uses {\tt sumor}
-\item otherwise, \verb/A+B/ uses {\tt sum}.
-\end{itemize}
-The trick is to build a temporary AST: \verb/{A}/ generates the node
-\verb/(SQUASH A)/. When we parse \verb/A+B/, we remove the {\tt
-SQUASH} in {\tt A} and {\tt B}:
-
-\begin{coq_example*}
-Grammar constr constr1: ast :=
- squash [ "{" lconstr($lc) "}" ] -> [(SQUASH $lc)].
-Grammar constr lassoc_constr4 :=
- squash_sum
- [ lassoc_constr4($c1) "+" lassoc_constr4($c2) ] ->
- case [$c2] of
- (SQUASH $T2) ->
- case [$c1] of
- (SQUASH $T1) -> [(sumbool $T1 $T2)]
- | $_ -> [(sumor $c1 $T2)]
- esac
- | $_ -> [(sum $c1 $c2)]
- esac.
-\end{coq_example*}
-
-The first rule is casted with type ast, because the produced term
-cannot be reached by the input syntax. On the other hand, the second
-command has (implicit) type \verb+constr+, so the right hand side is
-parsed with the term parser.
-
-\noindent The problem is that sometimes, the intermediate {\tt SQUASH}
-node cannot re-shaped, then we have a very specific error:
-
-\begin{coq_eval}
-(********** The following is not correct and should produce **********)
-(************** Error: Ill-formed specification **********************)
-(* Just to adjust the prompt: *) Set Printing Depth 50.
-\end{coq_eval}
-\begin{coq_example}
-Check {True}.
-\end{coq_example}
-
-
-\example{Comparisons and non-linear patterns}
-
-The patterns may be non-linear: when an already bound metavariable
-appears in a pattern, the value yielded by the pattern matching must
-be equal, up to renaming of bound variables, to the current
-value. Note that this does not apply to the wildcard \verb+$_+. For
-example, we can compare two arguments:
-
-\begin{coq_example}
-Grammar constr constr10 :=
- refl_equals [ constr9($c1) "||" constr9($c2) ] ->
- case [$c1] of $c2 -> [(refl_equal ? $c2)] esac.
-Check ([x:nat]x || [y:nat]y).
-\end{coq_example}
-
-\noindent The metavariable \verb+$c1+ is bound to \verb+[x:nat]x+ and
-\verb+$c2+ to \verb+[y:nat]y+. Since these two values are equal, the
-pattern matching succeeds. It fails when the two terms are not equal:
-
-% Test failure
-\begin{coq_eval}
-(********** The following is not correct and should produce **********)
-(************* Error: ... Grammar case failure ... ******************)
-(* Just to adjust the prompt: *) Set Printing Depth 50.
-\end{coq_eval}
-\begin{coq_example}
-Check ([x:nat]x || [z:bool]z).
-\end{coq_example}
-
-
-
-\subsection{Grammars of type {\tt ast list}}
-
-Assume we want to define an non-terminal {\tt ne\_identarg\_list} that
-parses an non-empty list of identifiers. If the grammars could only
-return AST's, we would have to define it this way:
-
-\begin{coq_example*}
-Grammar tactic my_ne_ident_list : ast :=
- ident_list_cons [ identarg($id) my_ne_ident_list($l) ] ->
- case [$l] of
- (IDENTS ($LIST $idl)) -> [(IDENTS $id ($LIST $idl))]
- esac
-| ident_list_single [ identarg($id) ] -> [(IDENTS $id)].
-\end{coq_example*}
-
-But it would be inefficient: every time an identifier is read, we
-remove the ``boxing'' operator {\tt IDENTS}, and put it back once the
-identifier is inserted in the list.
-
-To avoid these awkward trick, we allow grammars to return AST
-lists. Hence grammars have a type ({\tt ast} or {\tt ast list}), just like
-AST's do. Type-checking can be done statically.
-
-The simple actions can produce lists by putting a list of constructive
-expressions one beside the other. As usual, the {\tt\$LIST} operator
-allows to inject AST list variables.
-
-\begin{coq_example*}
-Grammar tactic ne_identarg_list : ast list :=
- ne_idl_cons [ identarg($id) ne_identarg_list($idl) ]
- -> [ $id ($LIST $idl) ]
-| ne_idl_single [ identarg($id) ] -> [ $id ].
-\end{coq_example*}
-%$
-
-Note that the grammar type must be recalled in every extension
-command, or else the system could not discriminate between a single
-AST and an AST list with only one item. If omitted, the default type
-depends on the universe name. The following command fails because the non-terminal {\tt
-ne\_identarg\_list} is already defined with type {\tt ast list} but the
-{\tt Grammar} command header assumes its type is {\tt ast}.
-
-\begin{coq_eval}
-(********** The following is not correct and should produce **********)
-(****** Error: ne_identarg_list already exists with another type *****)
-(* Just to adjust the prompt: *) Set Printing Depth 50.
-\end{coq_eval}
-% Test failure
-\begin{coq_example}
-Grammar tactic ne_identarg_list :=
- list_two [ identarg($id1) identarg($id2) ] -> [ $id1 ; $id2 ].
-\end{coq_example}
-
-All rules of a same grammar must have the same type. For instance, the
-following rule is refused because the \verb+constr:constr1+ grammar
-has been already defined with type {\tt Ast}, and cannot be extended
-with a rule returning AST lists.
-
-% Test failure
-\begin{coq_eval}
-(********** The following is not correct and should produce **********)
-(********* Error: ']' expected after [default_action_parser] *********)
-(* Just to adjust the prompt: *) Set Printing Depth 50.
-\end{coq_eval}
-\begin{coq_example}
-Grammar constr constr1 :=
- carret_list [ constr0($c1) "^" constr0($c2)] -> [ $c1 $c2 ].
-\end{coq_example}
-
-
-\subsection{Limitations}
-
-The extendable grammar mechanism have four serious limitations. The
-first two are inherited from {\camlpppp}.
-\begin{itemize}
-\item Grammar rules are factorized syntactically: {\camlpppp} does not
- try to expand non-terminals to detect further factorizations. The
- user must perform the factorization himself.
-\item The grammar is not checked to be \emph{LL(1)}\index{LL(1)} when
- adding a rule. If it is not LL(1), the parsing may fail on an input
- recognized by the grammar, because selecting the appropriate rule
- may require looking several tokens ahead. {\camlpppp} always selects
- the most recent rule (and all those that factorize with it)
- accepting the current token.
-\item There is no command to remove a grammar rule. However there is a
- trick to do it. It is sufficient to execute the ``{\tt Reset}''
- command on a constant defined before the rule we want to remove.
- Thus we retrieve the state before the definition of the constant,
- then without the grammar rule. This trick does not apply to grammar
- extensions done in {\ocaml}.
-\item Grammar rules defined inside a section are automatically removed
- after the end of this section: they are available only inside it.
-\end{itemize}
-
-The command {\tt Print Grammar} prints the rules of a grammar. It is
-displayed by {\camlpppp}. So, the actions are not printed, and the
-recursive calls are printed \verb+SELF+\index{SELF@{\tt SELF}}. It is
-sometimes useful if the user wants to understand why parsing fails, or
-why a factorization was not done as expected.\index{Print Grammar@{\tt
-Print Grammar}}
-
-\begin{coq_example}
-Print Grammar constr constr8.
-\end{coq_example}
-
-\subsubsection{Getting round the lack of factorization}
-The first limitation may require a non-trivial work, and may lead to
-ugly grammars, hardly extendable. Sometimes, we can use a trick to
-avoid these troubles. The problem arises in the {\gallina} syntax, to
-make {\camlpppp} factorize the rules for application and product. The
-natural grammar would be:
-
-% Test failure
-\begin{coq_eval}
-(********** The following is not correct and should produce **********)
-(******** Syntax error: ')' expected after [Constr.constr10] *********)
-\end{coq_eval}
-\begin{coq_example}
-Grammar constr constr0 : ast :=
- parenthesis [ "(" constr10($c) ")" ] -> [$c]
-| product [ "(" prim:var($id) ":" constr($c1) ")" constr0($c2) ] ->
- [(PROD $c1 [$id]$c2)]
-with constr10 : ast :=
- application [ constr9($c1) ne_constr_list($lc) ] ->
- [(APPLIST $c1 ($LIST $lc))]
-| inject_com91 [ constr9($c) ] -> [$c].
-Check (x:nat)nat.
-\end{coq_example}
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-
-But the factorization does not work, thus the product rule is never
-selected since identifiers match the {\tt constr10} grammar. The
-trick is to parse the ident as a {\tt constr10} and check \emph{a
-posteriori} that the term is indeed an identifier:
-
-\begin{coq_example}
-Grammar constr constr0 : ast :=
- product [ "(" constr10($c) ":" constr($c1) ")" constr0($c2) ] ->
- [(PROD $c1 [$c]$c2)].
-Check (x:nat)nat.
-\end{coq_example}
-%$
-
-\noindent We could have checked it explicitly with a {\tt case} in
-the right-hand side of the rule, but the error message in the
-following example would not be as relevant:
-
-% Test failure
-\begin{coq_eval}
-(********** The following is not correct and should produce **********)
-(******* Error: This expression should be a simple identifier ********)
-(* Just to adjust the prompt: *) Set Printing Depth 50.
-\end{coq_eval}
-\begin{coq_example}
-Check (S O:nat)nat.
-\end{coq_example}
-
-\noindent This trick is not similar to the {\tt SQUASH} node in which
-we could not detect the error while parsing. Here, the error pops out
-when trying to build an abstraction of {\tt\$c2} over the value of
-{\tt\$c}. Since it is not bound to a variable, the right-hand side of
-the product grammar rule fails.
-
-\section{Writing your own pretty printing rules}
-\label{Syntax}
-\comindex{Syntax}
-
-There is a mechanism for extending the
-vernacular's printer by adding, in the interactive
-toplevel, new printing rules. The printing rules are stored into a
-table and will be recovered at the moment of the printing by the
-vernacular's printer.
-
-The user can print new constants, tactics and vernacular phrases
-with his desired syntax. The printing rules
-for new constants should be written {\em after} the definition of the
-constants. The rules should be
-outside a section if the user wants them to be exported.
-
-The printing rules corresponding to the heart of the system (primitive
-tactics, terms and the vernacular language) are defined,
-respectively, in the files {\tt PPTactic.v} and {\tt PPConstr.v}
-(in the directory {\tt syntax}). These files are automatically
-loaded in the initial state. The user is not expected to modify these
-files unless he dislikes the way primitive things are printed, in
-which case he will have to compile the system after doing the
-modifications.
-
-When the system fails to find a suitable printing rule, a tag
-\verb+#GENTERM+\index{GENTERM@{\tt\#GENTERM}} appears in the message.
-
-In the following we give some examples showing how to write the
-printing rules for the non-terminal and terminal symbols of a
-grammar. We will test them frequently by inspecting the error
-messages. Then, we give the grammar of printing rules and a
-description of its semantics.
-
-
-\subsection{The Printing Rules}
-\subsubsection{The printing of non terminals}
-
-The printing is the inverse process of parsing. While a grammar rule
-maps an input stream of characters
-into an AST, a printing
-rule maps an AST into an output stream of printing orders.
-So given a certain grammar rule, the printing rule
-is generally obtained by inverting the grammar rule.
-
-Like grammar rules, it is possible to define several rules at the same
-time. The exact syntax for complex rules is described
-in~\ref{syntaxsyntax}. A simple printing rule is of the form:
-
-\begin{center}
-\verb+Syntax+ ~{\sl universe}
-~\verb+level+ ~{\sl precedence}~\verb+:+~{\sl name}
-~\verb+[+~{\sl pattern}~\verb+] -> [+~{\sl printing-orders}~\verb+].+
-\end{center}
-
-where :
-\begin{itemize}
-\item {\it universe} is an identifier denoting the universe of the AST to
- be printed. They have the same meaning as grammar universes.
- The vernac universe has no equivalent in pretty-printing since
- vernac phrases are never printed by the system. Error messages are
- reported by re-displaying what the user typed in.
-
-\item {\it precedence} is positive integer indicating the precedence
- of the rule. In general the precedence for tactics is 0. The
- universe of terms is implicitly stratified by the hierarchy of
- the parsing rules. We have non terminals \textit{constr0},
- \textit{constr1}, \ldots, \textit{constr10}.
- The idea is that objects parsed with the non terminal
- $constr_i$ have precedence $i$. In most of the cases we fix the
- precedence of the printing rules for commands to be the same number
- of the non terminal with which it is parsed.
-
- A precedence may also be a triple of integers. The triples are
- ordered in lexicographic order, and the level $n$ is equal to {\tt
- [$n~0~0$]}.
-
-\item {\it name} is the name of the
- printing rule. A rule is identified by both its universe and name,
- if there are two rules with both the same name and universe, then
- the last one overrides the former.
-
-\item {\it pattern} is a pattern that matches the AST to be
- printed.
-The syntax of patterns is dependent on the universe of the AST to be
-printed (e.g. patterns are parsed as {\tt constr} if the universe is
-{\tt constr}, etc), and a quotation can be used to escape the default
-parser associated to this universe.
-A description of the syntax of patterns is given in section
- \ref{patternsyntax}.
-
-\item {\it printing-orders} is the sequence of orders indicating the
- concrete layout of the printer.
-\end{itemize}
-
-\firstexample
-
-\example{Syntax for user-defined tactics.}
-
-The first usage of the \texttt{Syntax} command might be the printing
-order for a user-defined tactic:
-
-\begin{coq_example*}
-Declare ML Module "eqdecide".
-Syntax tactic level 0:
- Compare_PP [(Compare $com1 $com2)] ->
- ["Compare" [1 2] $com1 [1 2] $com2].
-\end{coq_example*}
-
-% meme pas vrai
-If such a printing rule is not given, a disgraceful \verb+#GENTERM+
-will appear when typing \texttt{Show Script} or \texttt{Save}. For
-a tactic macro defined by a \texttt{Tactic Definition} command, a
-printing rule is automatically generated so the user don't have to
-write one.
-
-\example{Defining the syntax for new constants.}
-
-Let's define the constant \verb+Xor+ in Coq:
-
-\begin{coq_eval}
- Reset Initial.
-\end{coq_eval}
-
-\begin{coq_example*}
-Definition Xor := [A,B:Prop] A/\~B \/ ~A/\B.
-\end{coq_example*}
-
-Given this definition, we want to use the syntax of \verb+A X B+
-to denote \verb+(Xor A B)+. To do that we give the grammar rule:
-
-\begin{coq_example}
-Grammar constr constr7 :=
- Xor [ constr6($c1) "X" constr7($c2) ] -> [(Xor $c1 $c2)].
-\end{coq_example}
-
-Note that the operator is associative to the right.
-Now \verb+True X False+ is well parsed:
-
-\begin{coq_example}
-Goal True X False.
-\end{coq_example}
-
-To have it well printed we extend the printer:
-
-\begin{coq_example}
-Syntax constr level 7:
- Pxor [(Xor $t1 $t2)] -> [ $t1:L " X " $t2:E ].
-\end{coq_example}
-
-and now we have the desired syntax:
-
-\begin{coq_example}
-Show.
-\end{coq_example}
-
-Let's comment the rule:
-\begin{itemize}
-\item \verb+constr+ is the universe of the printing rule.
-
-\item \verb+7+ is the rule's precedence and it is the same one than the
- parsing production (constr7).
-
-\item \verb+Pxor+ is the name of the printing rule.
-\item \verb+(Xor $t1 $t2)+ is the pattern of the term to be
-printed. Between \verb+<< >>+ we are allowed to use the syntax of
-arbitrary AST instead of terms. Metavariables may occur in the pattern
-but preceded by \verb+$+.
-
-\item \verb+$t1:L " X " $t2:E+ are the printing
- orders, it tells to print the value of \verb+$t1+ then the symbol
- \verb+X+ and then the value of \verb+$t2+.
-
- The \verb+L+ in the little box \verb+$t1:L+ indicates not
- to put parentheses around the value of \verb+$t1+ if its precedence
- is {\bf less} than the rule's one. An \verb+E+ instead of the
- \verb+L+ would mean not to put parentheses around the value of
- \verb+$t1+ if its the precedence is {\bf less or equal} than the
- rule's one.
-
- The associativity of the operator can be expressed in the following
- way:
-
- \verb&$t1:L " X " $t2:E& associates the operator to the right.
-
- \verb&$t1:E " X " $t2:L& associates to the left.
-
- \verb&$t1:L " X " $t2:L& is non-associative.
-
-\end{itemize}
-
-Note that while grammar rules are related by the name of non-terminals
-(such as {\tt constr6} and {\tt constr7}) printing rules are
-isolated. The {\tt Pxor} rule tells how to print an {\tt Xor}
-expression but not how to print its subterms. The printer looks up
-recursively the rules for the values of \verb+$t1+ and \verb+$t2+. The
-selection of the printing rules is strictly determined by the
-structure of the AST to be printed.
-
-This could have been defined with the {\tt Infix} command.
-
-
-\example{Forcing to parenthesize a new syntactic construction}
-
-You can force to parenthesize a new syntactic construction by fixing
-the precedence of its printing rule to a number greater than 9. For
-example a possible printing rule for the {\tt Xor} connector in the prefix
-notation would be:
-
-\begin{coq_example*}
-Syntax constr level 10:
- ex_imp [(Xor $t1 $t2)] -> [ "X " $t1:L " " $t2:L ].
-\end{coq_example*}
-
-No explicit parentheses are contained in the rule, nevertheless, when
-using the connector, the parentheses are automatically written:
-
-\begin{coq_example}
-Show.
-\end{coq_example}
-
-A precedence higher than 9 ensures that the AST value will be
-parenthesized by default in either the empty context or if it occurs
-in a context where the instructions are of the form
-\verb+$t:L+ or \verb+$t:E+.
-
-
-\example{Dealing with list patterns in the syntax rules}
-
-The following productions extend the parser to recognize a
-tactic called \verb+MyIntros+ that receives a list of identifiers as
-argument as the primitive \verb+Intros+ tactic does:
-
-\begin{coq_example*}
-Grammar tactic simple_tactic: ast :=
- my_intros [ "MyIntros" ne_identarg_list($idl) ] ->
- [(MyIntrosWith ($LIST $idl))].
-\end{coq_example*}
-
-To define the printing rule for \verb+MyIntros+ it is necessary to
-define the printing rule for the non terminal \verb+ne_identarg_list+.
-In grammar productions the dependency between the non terminals is
-explicit. This is not the case for printing rules, where the
-dependency between the rules is determined by the structure of the
-pattern. So, the way to make explicit the relation between printing
-rules is by adding structure to the patterns.
-
-\begin{coq_example}
-Syntax tactic level 0:
- myintroswith [<<(MyIntrosWith ($LIST $L))>>] ->
- [ "MyIntros " (NEIDENTARGLIST ($LIST $L)) ].
-\end{coq_example}
-
-This rule says to print the string \verb+MyIntros+ and then to print
-the value of \\
-\verb+(NEIDENTARGLIST ($LIST $L))+.
-
-\begin{coq_example}
-Syntax tactic level 0:
- ne_identarg_list_cons [<<(NEIDENTARGLIST $id ($LIST $l))>>]
- -> [ $id " " (NEIDENTARGLIST ($LIST $l)) ]
-| ne_identarg_list_single [<<(NEIDENTARGLIST $id)>>] -> [ $id ].
-\end{coq_example}
-
-
-The first rule says how to print a non-empty list, while the second
-one says how to print the list with exactly one element. Note that the
-pattern structure of the binding in the first rule ensures its use in
-a recursive way.
-
-Like the order of grammar productions, the order of printing rules
-\emph{does matter}. In case of two rules whose patterns superpose
-each other the {\bf last} rule is always chosen. In the example, if
-the last two rules were written in the inverse order the printing will
-not work, because only the rule {\sl ne\_identarg\_list\_cons} would
-be recursively retrieved and there is no rule for the empty list.
-Other possibilities would have been to write a rule for the empty list
-instead of the {\sl ne\_identarg\_list\_single} rule,
-
-\begin{coq_example}
-Syntax tactic level 0:
- ne_identarg_list_nil [<<(NEIDENTARGLIST)>>] -> [ ].
-\end{coq_example}
-
-This rule indicates to do nothing in case of the empty list. In this
-case there is no superposition between patterns (no critical pairs)
-and the order is not relevant. But a useless space would be printed
-after the last identifier.
-
-\example{Defining constants with arbitrary number of arguments}
-
-Sometimes the constants we define may have an arbitrary number of
-arguments, the typical case are polymorphic functions. Let's consider
-for example the functional composition operator. The following rule
-extends the parser:
-
-\begin{coq_example*}
-Definition explicit_comp := [A,B,C:Set][f:A->B][g:B->C][a:A](g (f a)).
-Grammar constr constr6 :=
- expl_comp [constr5($c1) "o" constr6($c2) ] ->
- [(explicit_comp ? ? ? $c1 $c2)].
-\end{coq_example*}
-
-Our first idea is to write the printing rule just by ``inverting'' the
-production:
-
-\begin{coq_example}
-Syntax constr level 6:
- expl_comp [(explicit_comp ? ? ? $f $g)] -> [ $f:L "o" $g:L ].
-\end{coq_example}
-
-This rule is not correct: \verb+?+ is an ordinary AST (indeed, it is
-the AST \verb|(XTRA "ISEVAR")|), and does not behave as the
-``wildcard'' pattern \verb|$_|. Here is a correct version of this
-rule:
-
-\begin{coq_example*}
-Syntax constr level 6:
- expl_comp [(explicit_comp $_ $_ $_ $f $g)] -> [ $f:L "o" $g:L ].
-\end{coq_example*}
-
-Let's test the printing rule:
-
-% 2nd test should fail
-\begin{coq_example}
-Definition Id := [A:Set][x:A]x.
-Check (Id nat) o (Id nat).
-Check ((Id nat)o(Id nat) O).
-\end{coq_example}
-
-In the first case the rule was used, while in the second one the
-system failed to match the pattern of the rule with the AST of
-\verb+((Id nat)o(Id nat) O)+.
-Internally the AST of this term is the same as the AST of the
-term \verb+(explicit_comp nat nat nat (Id nat) (Id nat) O)+.
-When the system retrieves our rule it tries to match an application of
-six arguments with an application of five arguments (the AST of
-\verb+(explicit_comp $_ $_ $_ $f $g)+).
-%$
- Then, the matching fails and
-the term is printed using the rule for application.
-
-Note that the idea of adding a new rule for \verb+explicit_comp+ for
-the case of six arguments does not solve the problem, because of the
-polymorphism, we can always build a term with one argument more. The
-rules for application deal with the problem of having an arbitrary
-number of arguments by using list patterns. Let's see these rules:
-
-\begin{coq_eval}
-Definition foo := O.
-\end{coq_eval}
-\begin{coq_example*}
-Syntax constr level 10:
- app [<<(APPLIST $H ($LIST $T))>>] ->
- [ [<hov 0> $H:E (APPTAIL ($LIST $T)):E ] ]
-
-| apptailcons [<<(APPTAIL $H ($LIST $T))>>] ->
- [ [1 1] $H:L (APPTAIL ($LIST $T)):E ]
-| apptailnil [<<(APPTAIL)>>] -> [ ].
-\end{coq_example*}
-\begin{coq_eval}
-Reset foo.
-\end{coq_eval}
-
-The first rule prints the operator of the application, and the second
-prints the list of its arguments. Then, one solution to our problem is
-to specialize the first rule of the application to the cases where the
-operator is \verb+explicit_comp+ and the list pattern has {\bf at
-least} five arguments:
-
-\begin{coq_example*}
-Syntax constr level 10:
- expl_comp
- [<<(APPLIST <<explicit_comp>> $_ $_ $_ $f $g ($LIST $l))>>]
- -> [ [<hov 0> $f:L "o" $g:L (APPTAIL ($LIST $l)):E ] ].
-\end{coq_example*}
-%$
-
-Now we can see that this rule works for any application of the
-operator:
-
-\begin{coq_example}
-Check ((Id nat) o (Id nat) O).
-Check ((Id nat->nat) o (Id nat->nat) [x:nat]x O).
-\end{coq_example}
-
-In the examples presented by now, the rules have no information about
-how to deal with indentation, break points and spaces, the printer
-will write everything in the same line without spaces. To indicate the
-concrete layout of the patterns, there's a simple language of printing
-instructions that will be described in the following section.
-
-
-\subsubsection{The printing of terminals}
-The user is not expected to write the printing rules for terminals,
-this is done automatically. Primitive printing is done for
-identifiers, strings, paths, numbers. For example :
-
-\begin{coq_example*}
-Grammar vernac vernac: ast :=
- mycd [ "MyCd" prim:string($dir) "." ] -> [(MYCD $dir)].
-Syntax vernac level 0:
- mycd [<<(MYCD $dir)>>] -> [ "MyCd " $dir ].
-\end{coq_example*}
-
-There is no more need to encapsulate the \verb+$dir+ meta-variable
-with the \verb+$PRIM+ or the \verb+$STR+ operator as in the version
-6.1. However, the pattern \verb+(MYCD ($STR $dir))+ would be safer,
-because the rule would not be selected to print an ill-formed AST. The
-name of default primitive printer is the {\ocaml} function {\tt
-print\_token}. If the user wants a particular terminal to be printed
-by another printer, he may specify it in the right part of the
-rule. Example:
-
-% Pas encore possible! $num est un id, pas un entier.
-%Syntax tactic level 0 :
-% do_pp [<<Do $num $tactic>>]
-% -> [ "Do " $num:"my_printer" [1 1] $tactic ].
-\begin{coq_example*}
-Syntax tactic level 0 :
- do_pp [<<(DO ($NUM $num) $tactic)>>]
- -> [ "Do " $num:"my_printer" [1 1] $tactic ].
-\end{coq_example*}
-
-The printer \textit{my\_printer} must have been installed as shown
-below.
-
-\subsubsection{Primitive printers}
-
-Writing and installing primitive pretty-printers requires to have the
-sources of the system like writing tactics.
-
-A primitive pretty-printer is an \ocaml\ function of type
-\begin{verbatim}
- Esyntax.std_printer -> CoqAst.t -> Pp.std_ppcmds
-\end{verbatim}
-The first
-argument is the global printer, it can be called for example by the
-specific printer to print subterms. The second argument is the AST to
-print, and the result is a stream of printing orders like :
-
-\begin{itemize}
-\item \verb+'sTR"+\textit{string}\verb+"+ to print the string
- \textit{string}
-\item \verb+'bRK +\textit{num1 num2} that has the same semantics than
- \verb+[+ \textit{num1 num2} \verb+]+ in the print rules.
-\item \verb+'sPC+ to leave a blank space
-\item \verb+'iNT+ $n$ to print the integer $n$
-\item \ldots
-\end{itemize}
-
-There is also commands to make boxes (\verb+h+ or \verb+hv+, described
-in file {\tt lib/pp.mli}). Once the printer is written, it
-must be registered by the command :
-\begin{verbatim}
- Esyntax.Ppprim.add ("name",my_printer);;
-\end{verbatim}
-\noindent
-Then, in the toplevel, after having loaded the right {\ocaml} module,
-it can be used in the right hand side of printing orders using the
-syntax \verb+$truc:"name"+.
-
-The real name and the registered name of a pretty-printer does not
-need to be the same. However, it can be nice and simple to give the
-same name.
-
-\subsection{Syntax for pretty printing rules}
-\label{syntaxsyntax}
-
-This section describes the syntax for printing rules. The
-metalanguage conventions are the same as those specified for the
-definition of the {\sl pattern}'s syntax in section \ref{patternsyntax}.
-The grammar of printing rules is the following:
-
-\begin{center}
-\begin{tabular}{|rcl|} \hline
-{\sl printing-rule} & ::= &
- \verb+Syntax+~{\ident}~~\nelist{{\sl level}}{;} \\
-{\sl level} & ::= & \verb+level+~{\sl precedence}~\verb+:+
- ~\nelist{{\sl rule}}{|} \\
-{\sl precedence} & ::= &
- {\integer} ~$|$~ \verb+[+~\integer~\integer~\integer~\verb+]+ \\
-{\sl rule} & ::= &
- {\sl ident}~\verb+[+~{\sl pattern}~\verb+] -> [+%
- ~\sequence{{\sl printing-order}}{}~\verb+]+ \\
-{\sl printing-order} & ::= & \verb+FNL+ \\
- &$|$& {\sl string} \\
- &$|$& \verb+[+~\integer~\integer~\verb+]+ \\
- &$|$& \verb+[+~box~\sequence{{\sl printing-order}}{}~\verb+]+ \\
- &$|$& {\sl ast}~\zeroone{{\tt :}~{\sl prim-printer}}~%
- \zeroone{{\tt :}~{\sl paren-rel}}\\
-{\sl box} & ::= & \verb+<+~{\sl box-type}~\integer~\verb+>+\\
-{\sl box-type} & ::= & ~\verb+hov+~$|$~\verb+hv+~$|$~\verb+v+~$|$~\verb+h+\\
-{\sl paren-rel} & ::= & \verb+L+~$|$~\verb+E+ \\
-{\sl prim-printer} & ::= & {\sl string} \\
-{\sl pattern} & ::= & {\sl ast-quot} ~$|$~\verb+<<+ {\sl ast} \verb+>>+ \\
-\hline
-\end{tabular}
-\end{center}
-
-Non-terminal {\sl ast-quot} is the default quotation associated to the
-extended universe. Patterns not belonging to the input syntax can be
-given directly as AST using \verb+<< >>+.
-
-As already stated, the order of rules in a given level is relevant
-(the last ones override the previous ones).
-
-
-\subsubsection{Pretty grammar structures}
-The basic structure is the printing order sequence. Each order has a
-printing effect and they are sequentially executed. The orders can
-be:
-\begin{itemize}
-\item printing orders
-\item printing boxes
-\end{itemize}
-
-\paragraph{Printing orders}
-Printing orders can be of the form:
-\begin{itemize}
-\item \verb+"+{\sl string}\verb+"+ prints the {\sl string}.
-\item \verb+FNL+ force a new line.
-
-\item \texttt{\$t:}\textsl{paren-rel} or
- \texttt{\$t:}\textsl{prim-printer}\texttt{:}\textsl{paren-rel}
-
- {\sl ast} is used to build an AST in current context. The printer
- looks up the adequate printing rule and applies recursively this
- method. The optional field {\it prim-printer} is a string with the
- name primitive pretty-printer to call (The name is not the name of
- the {\ocaml} function, but the name given to {\tt
- Esyntax.Ppprim.add}). Recursion of the printing is determined by
- the pattern's structure. {\it paren-rel} is the following:
-
-\begin{tabular}{cl}
-
-\verb+L+ &
- if $t$ 's precedence is {\bf less} than the rule's one, then no
- parentheses \\
- & around $t$ are written. \\
-\verb+E+ &
- if $t$ 's precedence is {\bf less or equal} than the rule's one
- then no parentheses \\
- & around $t$ are written. \\
-{\it none} & {\bf never} write parentheses around $t$.
-\\\\
-\end{tabular}
-\end{itemize}
-
-\paragraph{Printing boxes}
-The concept of formatting boxes is used to describe the concrete
-layout of patterns: a box may contain many objects which are orders or
-sub\-boxes sequences separated by break\-points; the box wraps around
-them an imaginary rectangle.
-\begin{enumerate}
-\item {\bf Box types}
-
- The type of boxes specifies the way the components of the box will
- be displayed and may be:
-\begin{itemize}
-\item \verb+h+ : to catenate objects horizontally.
-\item \verb+v+ : to catenate objects vertically.
-\item \verb+hv+ : to catenate objects as with an ``h box'' but an
- automatic vertical folding is applied when the horizontal
- composition does not fit into the width of the associated output
- device.
-
-\item \verb+hov+ : to catenate objects horizontally but if the
- horizontal composition does not fit, a vertical composition will be
- applied, trying to catenate horizontally as many objects as possible.
-\end{itemize}
-
-The type of the box can be followed by a {\it n} offset value, which
-is the offset added to the current indentation when breaking lines
-inside the box.
-
-
-\item {\bf Boxes syntax}
-
- A box is described by a sequence surrounded by \verb+[ ]+. The first
- element of the sequence is the box type: this type surrounded by the
- symbols \verb+< >+ is one of the words \verb+hov+, \verb+hv+,
- \verb+v+, \verb+v+ followed by an offset. The default offset is 0
- and the default box type is \verb+h+.
-
-\item {\bf Break\-points}
-
- In order to specify where the pretty-printer is allowed to break,
- one of the following break-points may be used:
-
-\begin{itemize}
-\item \verb+[0 0]+ is a simple break-point, if the line is not broken
- here, no space is included (``Cut'').
-\item \verb+[1 0]+ if the line is not broken then a space is printed
- (``Spc'').
-\item \verb+[i j]+ if the line is broken, the value $j$ is added to the
- current indentation for the following line; otherwise $i$ blank spaces
- are inserted (``Brk'').
-\end{itemize}
-
-\noindent {\bf Examples :}
-It is interesting to test printing rules on ``small'' and ``large''
-expressions in order to see how the break of lines and indentation are
-managed. Let's define two constants and make a \verb+Print+ of them to
-test the rules. Here are some examples of rules for our constant
-\verb+Xor+:
-
-\begin{coq_example*}
-Definition A := True X True.
-Definition B := True X True X True X True X True X True X True
- X True X True X True X True X True X True.
-\end{coq_example*}
-\begin{coq_example*}
-Syntax constr level 6:
- Pxor [(Xor $t1 $t2)] -> [ $t1:L " X " $t2:E ].
-\end{coq_example*}
-
-
-This rule prints everything in the same line exceeding the line's
-width.
-
-% Avec coq-tex, le bord de l'e'cran n'est pas mate'rialise'.
-%\begin{coq_example}
-%Print B.
-%\end{coq_example}
-
-\begin{small}
-\begin{flushleft}
-\verb!Coq < Print B.!\\
-\texttt{\textit{B~=~}}\\
-\texttt{\textit{True~X~True~X~True~X~True~X~True~X~True~X~True~X~True~X~True~X~True~X~Tru}}\\
-\texttt{\textit{e~X~True~X~True}}\\
-\texttt{\textit{~~~~~:~Prop}}\\
-\end{flushleft}
-\end{small}
-
-Let's add some break-points in order to force the printer to break the
-line before the operator:
-
-\begin{coq_example*}
-Syntax constr level 6:
- Pxor [(Xor $t1 $t2)] -> [ $t1:L [0 1] " X " $t2:E ].
-\end{coq_example*}
-
-\begin{coq_example}
-Print B.
-\end{coq_example}
-
-The line was correctly broken but there is no indentation at all. To
-deal with indentation we use a printing box:
-
-\begin{coq_example*}
-Syntax constr level 6:
- Pxor [(Xor $t1 $t2)] ->
- [ [<hov 0> $t1:L [0 1] " X " $t2:E ] ].
-\end{coq_example*}
-
-With this rule the printing of A is correct, an the printing of B is
-indented.
-
-\begin{coq_example}
-Print B.
-\end{coq_example}
-
-If we had chosen the mode \verb+v+ instead of \verb+hov+ :
-
-\begin{coq_example*}
-Syntax constr level 6:
- Pxor [(Xor $t1 $t2)] -> [ [<v 0> $t1:L [0 1] " X " $t2:E ] ].
-\end{coq_example*}
-
-We would have obtained a vertical presentation:
-
-\begin{coq_example}
-Print A.
-\end{coq_example}
-
-The difference between the presentation obtained with the \verb+hv+
-and \verb+hov+ type box is not evident at first glance. Just for
-clarification purposes let's compare the result of this silly rule
-using an \verb+hv+ and a \verb+hov+ box type:
-
-\begin{coq_example*}
-Syntax constr level 6:
- Pxor [(Xor $t1 $t2)] ->
- [ [<hv 0> "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- [0 0] "----------------------------------------"
- [0 0] "ZZZZZZZZZZZZZZZZ" ] ].
-\end{coq_example*}
-\begin{coq_example}
-Print A.
-\end{coq_example}
-\begin{coq_example*}
-Syntax constr level 6:
- Pxor [(Xor $t1 $t2)] ->
- [ [<hov 0> "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- [0 0] "----------------------------------------"
- [0 0] "ZZZZZZZZZZZZZZZZ" ] ].
-\end{coq_example*}
-\begin{coq_example}
-Print A.
-\end{coq_example}
-
-In the first case, as the three strings to be printed do not fit in
-the line's width, a vertical presentation is applied. In the second
-case, a vertical presentation is applied, but as the last two strings
-fit in the line's width, they are printed in the same line.
-
-
-\end{enumerate}
-
-\subsection{Debugging the printing rules}
-
- By now, there is almost no semantic check of printing rules in the
- system. To find out where the problem is, there are two
- possibilities: to analyze the rules looking for the most common
- errors or to work in the toplevel tracing the ml code of the
- printer.
-When the system can't find the proper rule to print an Ast, it prints
-\verb+#GENTERM+ \textit{ast}. If you added no printing rule,
- it's probably a bug and you can send it to the \Coq\ team.
-
-\subsubsection{Most common errors}
-Here are some considerations that may help to get rid of simple
-errors:
-
-\begin{itemize}
-\item make sure that the rule you want to use is not defined in
- previously closed section.
-\item make sure that {\bf all} non-terminals of your grammar have
- their corresponding printing rules.
-
-\item make sure that the set of printing rules for a certain non
- terminal covers all the space of AST values for that non terminal.
-
-\item the order of the rules is important. If there are two rules
- whose patterns superpose (they have common instances) then it is
- always the most recent rule that will be retrieved.
-\item if there are two rules with the same name and universe the last
- one overrides the first one. The system always warns you about
- redefinition of rules.
-\end{itemize}
-
-\subsubsection{Tracing the {\ocaml} code of the printer}
-Some of the conditions presented above are not easy to verify when
-dealing with many rules. In that case tracing the code helps to
-understand what is happening. The printers are in the file {\tt
-src/typing/printer}. There you will find the functions:
-
-\begin{itemize}
-\item {\tt prterm} : the printer of constructions
-\item {\tt gentacpr} : the printer of tactics
-\end{itemize}
-
-These printers are defined in terms of a general printer {\tt
-genprint} (this function is located in {\tt src/parsing/esyntax.ml})
-and by instantiating it with the adequate parameters. {\tt genprint}
-waits for: the universe to which this AST belongs ({\it tactic}, {\it
-constr}), a default printer, the precedence of the AST inherited from
-the caller rule and the AST to print. {\tt genprint} looks for a rule
-whose pattern matches the AST, and executes in order the printing
-orders associated to this rule. Subterms are printed by recursively
-calling the generic printer. If no rule matches the AST, the default
-printer is used.
-
-An AST of a universe may have subterms that belong to another
-universe. For instance, let $v$ be the AST of the tactic
-expression \verb+MyTactic O+. The function {\tt gentacpr} is called
-to print $v$. This function instantiates the general printer {\tt
-genprint} with the universe {\it tactic}. Note that $v$ has a subterm
-$c$ corresponding to the AST of \verb+O+ ($c$ belongs to the universe
-{\it constr}). {\tt genprint} will try recursively to print all
-subterms of $v$ as belonging to the same universe of $v$. If this is
-not possible, because the subterm belongs to another universe, then
-the default printer that was given as argument to {\tt genprint} is
-applied. The default printer is responsible for changing the universe
-in a proper way calling the suitable printer for $c$.
-
-\medskip\noindent {\bf Technical Remark.} In the file
-\verb+PPTactic.v+, there are some rules that do not arise from the
-inversion of a parsing rule. They are strongly related to the way the
-printing is implemented.
+\Rem No typing of the denoted expression is performed at definition
+time. Type-checking is done only at the time of use of the notation.
-\begin{coq_example*}
-Syntax tactic level 8:
- tactic_to_constr [<<(COMMAND $c)>>] -> [ $c:"constr":9 ]
-\end{coq_example*}
+\Rem Many examples of {\tt Notation} may be found in the files
+composing the initial state of {\Coq} (see directory {\tt
+\$COQLIB/theories/Init}).
-As an AST of tactic may have subterms that are commands, these rules
-allow the printer of tactic to change the universe. The primitive printer
-{\tt command} is a special identifier used for this
-purpose. They are used in the code of the default printer that {\tt
-gentacpr} gives to {\tt genprint}.
-\fi
% $Id$