\emph{indicators}. Finally, the consumed flag is non-nil if the parser
consumed any input items.
+\begin{describe}{fun}{combine-parser-failures @<failures> @> @<list>}
+\end{describe}
+
%%%--------------------------------------------------------------------------
-\section{File locations}
+\section{File locations} \label{sec:parsing.floc}
+
+\begin{describe}{cls}{file-location}
+\end{describe}
+
+\begin{describe}{fun}{file-location-p @<object> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{fun}
+ {make-file-location @<filename> \&optional @<line> @<column>
+ @> @<file-location>}
+\end{describe}
+
+\begin{describe*}
+ {\dhead{fun}{file-location-filename @<floc> @> @<string-or-nil>}
+ \dhead{fun}{file-location-line @<floc> @> @<fixnum-or-nil>}
+ \dhead{fun}{file-location-column @<floc> @> @<fixnum-or-nil>}}
+\end{describe*}
+
+\begin{describe}{gf}{file-location @<object> @> @<floc>}
+ \begin{describe}{meth}{file-location (@<floc> file-location) @> @<floc>}
+ \end{describe}
+ \begin{describe}{meth}{file-location (@<stream> stream) @> @<floc>}
+ \end{describe}
+ \begin{describe}{meth}{file-location (@<any> t) @> @<floc>}
+ \end{describe}
+\end{describe}
+
+\begin{describe}{cls}{condition-with-location (condition) \&key :location}
+\end{describe}
+
+\begin{describe}{meth}
+ {file-location (@<condition> condition-with-location) @> @<floc>}
+\end{describe}
+
+\begin{describe*}
+ {\quad\=\quad\=\kill
+ \dhead{cls}
+ {error-with-location (condition-with-location error) \\ \>
+ \&key :location}
+ \dhead{cls}
+ {warning-with-location (condition-with-location warning) \\ \>
+ \&key :location}
+ \dhead{cls}
+ {enclosing-error-with-location
+ (enclosing-error-with-location error) \\ \>
+ \&key :condition :location}
+ \dhead{cls}
+ {enclosing-warning-with-location
+ (enclosing-condition-with-location warning) \\ \>
+ \&key :condition :location}
+ \dhead{cls}
+ {simple-condition-with-location
+ (condition-with-location simple-condition) \\ \>
+ \&key :format-control :format-arguments :location}
+ \dhead{cls}
+ {simple-error-with-location
+ (error-with-location simple-error) \\ \>
+ \&key :format-control :format-arguments :location}
+ \dhead{cls}
+ {simple-warning-with-location
+ (warning-with-location simple-warning) \\ \>
+ \&key :format-control :format-arguments :location}}
+\end{describe*}
+
+\begin{describe}{fun}
+ {make-condition-with-location @<default-type> @<floc>
+ @<datum> \&rest @<arguments>
+ \nlret @<condition-with-location>}
+\end{describe}
+
+\begin{describe*}
+ {\dhead{fun}{error-with-location @<floc> @<datum> \&rest @<arguments>}
+ \dhead{fun}{cerror-with-location @<floc> @<continue-string>
+ @<datum> \&rest @<arguments>}
+ \dhead{fun}{cerror*-with-location @<floc> @<datum> \&rest @<arguments>}
+ \dhead{fun}{warn-with-location @<floc> @<datum> \&rest @<arguments>}}
+\end{describe*}
+
+\begin{describe}{mac}
+ {with-default-error-location (@<floc>) @<body-form>^* @> @<value>^*}
+\end{describe}
+
+\begin{describe}{mac}
+ {count-and-report-errors () @<body-form>^*
+ @> @<value> @<n-errors> @<n-warnings>}
+\end{describe}
%%%--------------------------------------------------------------------------
\section{Scanners} \label{sec:parsing.scanner}
\subsection{Scanner file-location protocol} \label{sec:parsing.scanner.floc}
-Some scanners participate in the file-location protocol (\xref{sec:floc}).
-They implement a method on @|file-location| which collects the necessary
-information using scanner-specific functions described here.
+Some scanners participate in the file-location protocol
+(\xref{sec:parsing.floc}). They implement a method on @|file-location| which
+collects the necessary information using scanner-specific functions described
+here.
\begin{describe}{fun}{scanner-file-location @<scanner> @> @<file-location>}
Return a @|file-location| object describing the current position of the
specialized methods on @|file-location|.
\end{describe}
-\begin{describe}{gf}{scanner-filename @<scanner> @> @<string>}
- Return the name of the file the scanner is currently processing, as a
- string, or nil if the filename is not known.
-\end{describe}
-
-\begin{describe}{meth}{scanner-filename (@<scanner> t) @> @<string>}
- Returns nil.
-\end{describe}
+\begin{describe*}
+ {\dhead{gf}{scanner-filename @<scanner> @> @<string>}
+ \dhead{gf}{scanner-line @<scanner> @> @<integer>}
+ \dhead{gf}{scanner-column @<scanner> @> @<integer>}}
+ Return the filename, line and column components of the @<scanner>'s current
+ position, for use in assembling a @<file-location>: see the
+ @|scanner-file-location| function.
-\begin{describe}{gf}{scanner-line @<scanner> @> @<integer>}
- Return the line number of the @<scanner>'s current position, as an integer,
- or nil if the line number is not known.
-\end{describe}
-
-\begin{describe}{meth}{scanner-line (@<scanner> t) @> @<integer>}
- Returns nil.
-\end{describe}
-
-\begin{describe}{gf}{scanner-column @<scanner> @> @<integer>}
- Return the column number of the @<scanner>'s current position, as an
- integer, or nil if the column number is not known.
-\end{describe}
-
-\begin{describe}{meth}{scanner-column (@<scanner> t) @> @<integer>}
- Returns nil.
-\end{describe}
+ There are default methods on all three generic functions which simply
+ return nil.
+\end{describe*}
\subsection{Character scanners} \label{sec:parsing.scanner.char}
\end{describe}
%%%--------------------------------------------------------------------------
-\section{Parsing macros}
+\section{Parsing syntax}
-%%%--------------------------------------------------------------------------
+\begin{describe}{gf}{expand-parser-spec @<context> @<spec> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}
+ {expand-parser-form @<context> @<head> @<tail> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{wrap-parser @<context> @<form> @> @<wrapped-form>}
+\end{describe}
+
+\begin{describe}{mac}
+ {defparse @<name> (@[[ :context (@<var> @<context-class>) @]]
+ @<destructuring-lambda-list-item>^*) \\ \ind
+ @<body-form>^* \-
+ \nlret @<name>}
+\end{describe}
+
+\begin{describe}{mac}
+ {with-parser-context
+ (@<context-class> @{ @<init-keyword> @<value> @}^*) \\ \ind
+ @<body-form>^* \-
+ \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{lmac}
+ {parse @<parser> @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+\begin{describe}{gf}{parser-at-eof-p @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-step @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{sym}{it}
+\end{describe}
+
+\begin{describe}{mac}
+ {if-parse (@[[ \=:result @<result-var> @!
+ :expected @<expected-var> @! \+ \\
+ :consumedp @<consumed-var> @]]) \- \\ \ind\ind
+ @<parser> \- \\
+ @<consequent> \\
+ @[@<alternatve>@] \-
+ \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{mac}
+ {when-parse (@[@<result-var>@]) @<parser> \\ \ind
+ @<body-form>^* \-
+ \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{mac}
+ {cond-parse (@[[ \=:result @<result-var> @!
+ :expected @<expected-var> @! \+ \\
+ :consumedp @<consumed-var> @]]) \- \\ \ind
+ @{ (@<parser> @<form>^*) @}^* \-
+ \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{parse}{:eof}
+\end{describe}
+
+\begin{describe}{parseform}{lisp @<form>^*}
+\end{describe}
+
+\begin{describe}{parseform}{label @<parser>}
+\end{describe}
+
+\begin{describe}{parse}{t}
+\end{describe}
+
+\begin{describe}{parseform}{t @<value>}
+\end{describe}
+
+\begin{describe}{parse}{nil}
+\end{describe}
+
+\begin{describe}{parseform}{nil @<indicator>}
+\end{describe}
+
+\begin{describe}{parseform}{when @<cond> @<parser>}
+\end{describe}
+
+\begin{describe}{parseform}
+ {seq (@{ @<atomic-parser-spec> @! (@[@<var>@] @<parser>) @}^*) \\ \ind
+ @<body-form>^*}
+\end{describe}
+
+\begin{describe}{parseform}{and @<parser>^*}
+\end{describe}
+
+\begin{describe}{parseform}{or @<parser>^*}
+\end{describe}
+
+\begin{describe}{parseform}{? @<parser> @[@<default>@]}
+\end{describe}
+
+\begin{describe}{parseform}
+ {many (\=@<accumulator-var> @<init-form> @<update-form> \+ \\
+ @[[ \=:new @<new-var> @! :final @<final-form> @! \+ \\
+ :min @<minimum> @! :max @<maximum> @! \\
+ :commitp @<commitp> @]]) \-\- \\ \ind
+ @<item-parser> @[@<sep-parser>@]}
+\end{describe}
+
+\begin{describe}{parseform}
+ {list (@[[ :min @<minimum> @! :max @<maximum> @!
+ :commitp @<commitp> @]])\\ \ind
+ @<item-parser> @[@<sep-parser>@]}
+\end{describe}
+
+\begin{describe}{parseform}
+ {skip-many (@[[ :min @<minimum> @! :max @<maximum> @!
+ :commitp @<commitp> @]])\\ \ind
+ @<item-parser> @[@<sep-parser>@]}
+\end{describe}
+
+\begin{describe}{fun}{call-pluggable-parser @<symbol> \&rest @<args>}
+\end{describe}
+
+\begin{describe}{parseform}{plug @<symbol> @<arg>^*}
+\end{describe}
+
+\begin{describe}{fun}
+ {pluggable-parser-add @<symbol> @<tag> @<parser-function>}
+\end{describe}
+
+\begin{describe}{mac}
+ {define-pluggable-parser @<symbol> @<tag> @<lambda-list> @<body-form>^*}
+\end{describe}
+
+\begin{describe}{gf}{parser-capture-place @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-restore-place @<context> @<place> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-release-place @<context> @<place> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}
+ {parser-places-must-be-released-p @<context> @> @<generalized-boolean>>}
+\end{describe}
+
+\begin{describe}{mac}
+ {with-parser-place (@<place-var> @<context>) @<body-form>^*}
+\end{describe}
+
+\begin{describe}{parseform}{peek @<parser>}
+\end{describe}
+
+\begin{describe}{cls}{character-parser-context () \&key}
+\end{describe}
+
+\begin{describe}{gf}{parser-current-char @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{parseform}
+ {if-char (@[@<result-var>@]) @<condition> @<consequent> @<alternative>}
+\end{describe}
+
+\begin{describe}{parseform}{char @<character>}
+\end{describe}
+
+\begin{describe}[char]{parse}{@<character>}
+\end{describe}
+
+\begin{describe}[string]{parse}{@<string>}
+\end{describe}
+
+\begin{describe}{parse}{:any}
+\end{describe}
+
+\begin{describe}{parseform}{satisfies @<predicate>}
+\end{describe}
+
+\begin{describe}{parseform}{not @<character>}
+\end{describe}
+
+\begin{describe}{parseform}{filter @<predicate>}
+\end{describe}
+
+\begin{describe}{parse}{:whitespace}
+\end{describe}
+
+\begin{describe}{cls}{token-parser-context () \&key}
+\end{describe}
+
+\begin{describe}{gf}{parser-token-type @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-token-value @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{parseform}{token @<type> @[@<value>@] @[:peekp @<peek>@]}
+\end{describe}
+
+\begin{describe}[atom]{parse}{@<atom>}
+\end{describe}
+
+\begin{describe}[string]{parse}{@<string>}
+\end{describe}
+
+\begin{describe}{cls}{scanner-context () \&key :scanner}
+\end{describe}
+
+\begin{describe}{gf}{parse-scanner @<context> @> @<symbol>}
+\end{describe}
+
+\begin{describe}{cls}
+ {character-scanner-context (scanner-context character-parser-context)
+ \&key :scanner}
+\end{describe}
+
+\begin{describe}{cls}
+ {token-scanner-context (scanner-context token-parser-context)
+ \&key :scanner}
+\end{describe}
+
+\begin{describe}{gf}{push-operator @<operator> @<state>}
+\end{describe}
+
+\begin{describe}{gf}{push-value @<value> @<state>}
+\end{describe}
+
+\begin{describe}{gf}{apply-operator @<operator> @<state>}
+\end{describe}
+
+\begin{describe}{gf}{operator-push-action @<left> @<right>}
+\end{describe}
+
+\begin{describe}{parseform}
+ {expr \=(@[[ :nestedp @<nestedp-var> @]]) \+ \\
+ @<operand-parser> @<binop-parser>
+ @<preop-parser> @<postop-parser>}
+\end{describe}
+
+\begin{describe}{gf}{operator-left-precedence @<operator> @> @<prec>}
+\end{describe}
+
+\begin{describe}{gf}{operator-right-precedence @<operator> @> @<prec>}
+\end{describe}
+
+\begin{describe}{gf}{operator-associativity @<operator> @> @<assoc>}
+\end{describe}
+
+\begin{describe}{cls}{prefix-operator () \&key}
+\end{describe}
+
+\begin{describe}{cls}{simple-operator () \&key :name :function}
+\end{describe}
+
+\begin{describe}{cls}
+ {simple-unary-operator (simple-operator) \&key :name :function}
+\end{describe}
+
+\begin{describe*}
+ {\quad\=\kill
+ \dhead{cls}{simple-binary-operator (simple-operator) \\ \>
+ \&key :name :function :lprec :rprec :associativity}
+ \dhead{cls}{simple-postfix-operator (simple-unary-operator) \\ \>
+ \&key :name :function :lprec :rprec}
+ \dhead{cls}{simple-prefix-operator
+ (prefix-operator simple-unary-operator) \\ \>
+ \&key :name :function :rprec}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{mac}{preop @<name> (@<operand-var> @<lprec>)
+ @<body-form>^*
+ @> @<prefix-operator>}
+ \dhead{mac}{postop @<name>
+ (@<operand-var> @<lprec> @[[ :rprec @<rprec> @]])
+ @<body-form>^*
+ @> @<postfix-operator>}
+ \dhead{mac}{binop @<name> (@<operand-var> @<lprec> @<rprec> @<assoc>)
+ @<body-form>^*
+ @> @<binary-operator>}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{cls}{parenthesis () \&key :tag}
+ \dhead{cls}{open-parenthesis (parenthesis prefix-operator) \&key :tag}
+ \dhead{cls}{close-parenthesis (parenthesis) \&key :tag}}
+\end{describe*}
+
+\begin{describe*}
+ {\dhead{fun}{lparen @<tag> @> @<open-paren>}
+ \dhead{fun}{rparen @<tag> @> @<close-paren>}}
+\end{describe*}
+
+%%%-------------------------------------------------------------------------
\section{Lexical analyser}
+\begin{describe}{cls}
+ {sod-token-scanner (token-scanner)
+ \&key :filename (:line 1) (:column 0) :char-scanner}
+\end{describe}
+
+\begin{describe}{fun}{define-indicator @<indicator> @<description>}
+\end{describe}
+
+\begin{describe}{fun}{syntax-error @<scanner> @<expected> \&key :continuep}
+\end{describe}
+
+\begin{describe}{fun}
+ {lexer-error @<char-scanner> @<expected> @<consumed-flag>}
+\end{describe}
+
+\begin{describe}{parseform}
+ {skip-until (@[[ :keep-end @<keep-end-flag> @]]) @<token-type>^*}
+\end{describe}
+
+\begin{describe}{parseform}{error () @<sub-parser> @<recover-parser>}
+\end{describe}
+
+\begin{describe}{fun}
+ {scan-comment @<char-scanner>
+ @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
%%%----- That's all, folks --------------------------------------------------
%%% Local variables: